Visual Studio 2013 Express Visual C++( アンマネージドコード ) OpenCV 3.1 |
■284.OpenCV 2値画像から直線を検出 | Prev Top Next | |
|
標準ハフ変換を用いて,2値画像から直線を検出します。2要素から直線を算出するというのが謎。
#include <iostream> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc.hpp> #pragma comment( lib, "opencv_world300d.lib" ) int main(int argc, const char* argv[]) { int hr = -1; try { cv::Mat src, edge, dst; std::vector<cv::Vec2f> lines; // 画像読み込み src = cv::imread("D:/TEMP/MaverickProj/Image/OpenCV/46/building.jpg", cv::IMREAD_GRAYSCALE); cv::namedWindow("src", 1); imshow("src", src); // 輪郭抽出 cv::Canny(src, edge, 50, 200, 3); // 画像領域確保 dst = cv::Mat::zeros(src.rows, src.cols, CV_8UC3); // src[0] -> dst[2], src[0] -> dst[1], src[0] -> dst[0] // て感じでコピー元インデックスとコピー先インデックスを指定する int fromTo[] = { 0, 2, 0, 1, 0, 0 }; // シングルチャンネルを3チャンネルに増やして、コピーする cv::mixChannels(&src, 1, &dst, 1, fromTo, 3); // 直線検出 cv::HoughLines( edge, // 8ビット,シングルチャンネルの2値入力画像.この画像は関数により書き換えられる可能性があり. lines, // 検出された直線が出力されるベクトル.原点からの距離とラジアン単位の角度. 1, // ピクセル単位での距離分解能. CV_PI / 180.0, // ラジアンでの角度分解能 100 // 閾値.thresholdを十分に超えている直線のみが出力対象. ); // 直線描画 for (auto line : lines) { // 原点からの距離 float rho = line[0]; // ラジアン単位の角度 float theta = line[1]; double a = cos(theta), b = sin(theta); double x0 = a*rho, y0 = b*rho; // 直点を定義するには直線を通る点の座標と角度が必要なんだが、どういう意味の計算だろう? cv::Point pt1( x0 + 1000 * (-b), y0 + 1000 * (a)); cv::Point pt2( x0 - 1000 * (-b), y0 - 1000 * (a)); // 直線描画 cv::line(dst, pt1, pt2, cv::Scalar(0, 0, 255), 1); } cv::namedWindow("dst", 1); cv::imshow("dst", dst); cv::waitKey(0); hr = 0; } catch (cv::Exception ex) { std::cout << ex.err << std::endl; } // ウィンドウの破棄 cv::destroyAllWindows(); return hr; }元画像
直線の検出