hantas's blog

ブログ移転しました→ http://blog.taniho.net/

写真から迷路データの取得

題のとおりです。
マイクロマウスの迷路シミュレータ用にいちいち手打ちで迷路を入れるのが面倒だったので,写真を読み込ませるだけで迷路データを吐き出すというソフトウェアに挑戦してみました。
今回使用した環境は,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;
}

出力画像等

↓の画像を
f:id:hantas:20151009152756j:plain

↓になおして
f:id:hantas:20151009152800j:plain

↓のマスク画像にして
f:id:hantas:20151009152830j:plain

↓の迷路を出力させました

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|       |                                                       |
+   +   +   +---+---+---+---+---+---+---+---+---+---+---+---+   +
|   |   |       |                                           |   |
+   +   +   +---+   +---+---+---+---+---+---+---+---+---+   +   +
|   |   |   |           |                               |       |
+   +   +   +---+   +---+   +---+---+---+---+---+---+   +---+---+
|   |   |   |           |   |                       |       |   |
+   +   +   +---+   +---+   +   +---+---+---+---+   +---+   +   +
|   |   |   |           |   |           |           |   |       |
+   +   +   +---+   +---+   +---+---+   +---+   +   +   +   +   +
|   |   |   |           |   |   |       |       |   |       |   |
+   +   +   +   +---+---+   +   +   +---+   +   +---+   +---+   +
|   |   |   |                       |       |   |               |
+   +   +   +---+---+---+   +---+---+   +   +---+   +---+   +---+
|   |   |   |       |       |           |   |                   |
+   +   +   +   +   +---+   +   +   +   +---+   +---+---+   +---+
|   |   |   |   |   |       |       |   |           |   |       |
+   +   +   +   +   +   +---+   +---+---+   +---+---+   +---+   +
|   |   |   |   |       |           |           |           |   |
+   +   +   +   +---+---+   +---+---+   +---+---+   +---+   +   +
|   |   |   |   |   |           |           |           |   |   |
+   +   +   +   +   +   +---+---+   +---+---+   +   +---+   +   +
|   |   |   |   |           |           |       |       |   |   |
+   +   +   +   +   +---+---+   +---+---+   +---+---+   +   +   +
|   |   |   |           |           |           |       |   |   |
+   +   +   +   +---+---+   +---+---+   +---+   +   +   +   +   +
|   |   |   |   |   |           |           |       |   |   |   |
+   +   +   +---+   +---+   +---+   +   +   +   +   +   +   +   +
|   |   |   |           |           |   |       |       |   |   |
+   +   +   +   +---+   +---+---+---+---+---+---+---+   +   +   +
|   |               |                                   |       |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

また書きたくなったら追記します(レポートと東北大会と冬コミつらい)

○参考
OpenCV 2.xでマウスコールバックなGUI - minus9d's diary
C++(OpenCV2.x)でのHomographyTransformation : とある大学院生のプログラミング
OpenCVでHSV変換して色抽出 - Qiita