写真から迷路データの取得
題のとおりです。
マイクロマウスの迷路シミュレータ用にいちいち手打ちで迷路を入れるのが面倒だったので,写真を読み込ませるだけで迷路データを吐き出すというソフトウェアに挑戦してみました。
今回使用した環境は,gcc4.8.4,OpenCV2.4.8です。
今回のプログラムでは次の順に処理を行う必要がありました。
「斜めから取った写真を上から見た迷路に変換(ホモグラフィー変換)」→「扱いやすいように色空間を変換(RGBからHSV)」→「壁の上色である赤のみ抽出」→「迷路の認識」
ホモグラフィー変換
OpenCVに関数が用意されています。
・getPerspectiveTransform //変換行列の作成
・warpPerspective //画像に行列を適用
変換前の座標と変換後の座標を任意に指定することで,ホモグラフィー変換を行うことが出来ました。
Mat_<Vec3b> img1 = imread(src_image); //画像ファイルの読み込み Mat homography_matrix = getPerspectiveTransform(src_pt, dst_pt); warpPerspective(img1, img2, homography_matrix, img1.size()); imwrite(dst_image, img2); //画像ファイルの書き出し
色空間の変換
・cvtColor //色空間の変換
cvtColor(*src, colorImage, code);
おしまい。
赤色の抽出
汚いソースコードのみ掲載します。
void colorExtraction(Mat *src, Mat *dst, int code, int ch1Lower, int ch1Upper, int ch2Lower, int ch2Upper, int ch3Lower, int ch3Upper ){ Mat colorImage; int lower[3]; int upper[3]; Mat lut = Mat(256, 1, CV_8UC3); cvtColor(*src, colorImage, code); lower[0] = ch1Lower; lower[1] = ch2Lower; lower[2] = ch3Lower; upper[0] = ch1Upper; upper[1] = ch2Upper; upper[2] = ch3Upper; Mat tmp = Mat(src->rows, src->cols, CV_8UC3); uchar hsv[3]; for (int i=0; i<src->cols; i++) { for (int j=0; j<src->rows; j++) { hsv[0] = colorImage.at<Vec3b>(j, i)[0]; hsv[1] = colorImage.at<Vec3b>(j, i)[1]; hsv[2] = colorImage.at<Vec3b>(j, i)[2]; if (lower[0] <= upper[0]) { if(((lower[0] <= hsv[0]) && (hsv[0] <= upper[0])) && ((lower[1] <= hsv[1]) && (hsv[1] <= upper[1])) && ((lower[2] <= hsv[2]) && (hsv[2] <= upper[2]))){ tmp.at<uchar>(j, i*3) = 255; tmp.at<uchar>(j, i*3+1) = 255; tmp.at<uchar>(j, i*3+2) = 255; } else { tmp.at<uchar>(j, i*3) = 0; tmp.at<uchar>(j, i*3+1) = 0; tmp.at<uchar>(j, i*3+2) = 0; } } else { if(((lower[0] <= hsv[0]) || (hsv[0] <= upper[0])) && ((lower[1] <= hsv[1]) && (hsv[1] <= upper[1])) && ((lower[2] <= hsv[2]) && (hsv[2] <= upper[2]))){ tmp.at<uchar>(j, i*3) = 255; tmp.at<uchar>(j, i*3+1) = 255; tmp.at<uchar>(j, i*3+2) = 255; } else { tmp.at<uchar>(j, i*3) = 0; tmp.at<uchar>(j, i*3+1) = 0; tmp.at<uchar>(j, i*3+2) = 0; } } } } *dst = tmp; return; }
出力画像等
↓の画像を
↓になおして
↓のマスク画像にして
↓の迷路を出力させました
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ | | | + + + +---+---+---+---+---+---+---+---+---+---+---+---+ + | | | | | | + + + +---+ +---+---+---+---+---+---+---+---+---+ + + | | | | | | | + + + +---+ +---+ +---+---+---+---+---+---+ +---+---+ | | | | | | | | | + + + +---+ +---+ + +---+---+---+---+ +---+ + + | | | | | | | | | | + + + +---+ +---+ +---+---+ +---+ + + + + + | | | | | | | | | | | | + + + + +---+---+ + + +---+ + +---+ +---+ + | | | | | | | | + + + +---+---+---+ +---+---+ + +---+ +---+ +---+ | | | | | | | | | + + + + + +---+ + + + +---+ +---+---+ +---+ | | | | | | | | | | | | + + + + + + +---+ +---+---+ +---+---+ +---+ + | | | | | | | | | | + + + + +---+---+ +---+---+ +---+---+ +---+ + + | | | | | | | | | | | + + + + + + +---+---+ +---+---+ + +---+ + + | | | | | | | | | | | + + + + + +---+---+ +---+---+ +---+---+ + + + | | | | | | | | | | + + + + +---+---+ +---+---+ +---+ + + + + + | | | | | | | | | | | | + + + +---+ +---+ +---+ + + + + + + + + | | | | | | | | | | | + + + + +---+ +---+---+---+---+---+---+---+ + + + | | | | | +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
また書きたくなったら追記します(レポートと東北大会と冬コミつらい)
○参考
OpenCV 2.xでマウスコールバックなGUI - minus9d's diary
C++(OpenCV2.x)でのHomographyTransformation : とある大学院生のプログラミング
OpenCVでHSV変換して色抽出 - Qiita