ちょっとやってみたい事があるので,その準備として画像中の矩形検出処理を書いてみました.処理手順は単純に
- 画像を2値化
- 輪郭線検出
- 輪郭線を近似して,四角形になっているか判定
のような感じです.
四角形かどうかの判定は4点かつ,面積が一定以上かどうかで判定しています.
追加で凸形になっているかを調べるともっといいかもしれません.
2014/03/20 ソースちょっと修正
/*************************** * 矩形検出 * @author : tetro ***************************/ #include <vector> #include <sstream> #include <iostream> #include <opencv2/opencv.hpp> /*************************** * main ***************************/ int main(){ cv::VideoCapture cap(0); // esc を押すまで while (cv::waitKey(5) != 0x1b){ cv::Mat frame; cap >> frame; // キャプチャできていなければ処理を飛ばす if (!frame.data){ continue; } // 2値化 cv::Mat grayImage, binImage; cv::cvtColor(frame, grayImage, CV_BGR2GRAY); cv::threshold(grayImage, binImage, 128.0, 255.0, CV_THRESH_OTSU); cv::imshow("bin", binImage); // 輪郭抽出 std::vector< std::vector< cv::Point > > contours; cv::findContours(binImage, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); // 検出された輪郭線の描画 for (auto contour = contours.begin(); contour != contours.end(); contour++){ cv::polylines(frame, *contour, true, cv::Scalar(0, 255, 0), 2); } // 輪郭が四角形かの判定 for (auto contour = contours.begin(); contour != contours.end(); contour++){ // 輪郭を直線近似 std::vector< cv::Point > approx; cv::approxPolyDP(cv::Mat(*contour), approx, 50.0, true); // 近似が4線かつ面積が一定以上なら四角形 double area = cv::contourArea(approx); if (approx.size() == 4 && area > 1000.0){ cv::polylines(frame, approx, true, cv::Scalar(255, 0, 0), 2); std::stringstream sst; sst << "area : " << area; cv::putText(frame, sst.str(), approx[0], CV_FONT_HERSHEY_PLAIN, 1.0, cv::Scalar(0, 128, 0)); } } cv::imshow("frame", frame); } }