ページ 11

openCVを使ったハフ変換で角度を限定して検出したい

Posted: 2015年7月03日(金) 12:00
by パンフ
はじめまして。
現在、c++でopenCVを使用してハフ変換である範囲の角度の直線のみを検出しようとしています。
OSはwindows7、ソフトはvisual studio 2010を使用しています。

私がやった方法では一度すべての直線を検出した後、
描画する前に直線の角度を見て、指定した範囲の角度だった場合に描画します。

直線を検出することはできましたが、角度の限定がうまくいきません。

検出する直線の角度を限定できればよかったのですが、
方法がわからずこのような方法になってしまいました。

私が教えていただきたいのは
・ある範囲の角度の直線のみを検出する方法
・検出した直線の角度を判別し、描画するかしないかを判断する方法
です。

以下はソースコードです。

よろしくお願いいたします。

コード:


#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/opencv_lib.hpp>
#include <math.h>

#define PI 3.141592653589793

int main(int argc, char *argv[])
{
	int i1;
	char suuzi[249];
	FILE *f;
	int i=0;
	char filename01[100];
	char filename02[100];

	for(i=1;i<240;i++){
		sprintf(filename01,"00[%d].bmp",i);
		sprintf(filename02,"out[%d].bmp",i);
		//f=fopen(filename,"r");
		//fclose(f);                
		cv::Mat src_img = cv::imread(filename01);//Canny1000.jpg
		if(!src_img.data) return -1;

		cv::Mat dst_img, work_img;
		dst_img = src_img.clone();
		cv::cvtColor(src_img, work_img, CV_RGB2GRAY);
		cv::Canny(work_img, work_img, 50, 200, 3);
  
		// (古典的)Hough変換
		std::vector<cv::Vec2f> lines;
		// 入力画像,出力,距離分解能,角度分解能,閾値,*,*
		cv::HoughLines(work_img, lines, 1, CV_PI/180, 120, 0, 0);

		std::vector<cv::Vec2f>::iterator it = lines.begin();
		for(; it!=lines.end(); ++it) {
			float rho = (*it)[0], theta = (*it)[1];
    
			cv::Point pt1, pt2;
			double x1,x2,y1,y2;	

			double a = cos(theta), b = sin(theta);
			double x0 = a*rho, y0 = b*rho;
			double x3,y3;
			double tantan;
			int amari,amo,c,d;

			pt1.x= cv::saturate_cast<int>(x0 + 1000*(-b));
			pt1.y = cv::saturate_cast<int>(y0 + 1000*(a));
			pt2.x = cv::saturate_cast<int>(x0 - 1000*(-b));
			pt2.y = cv::saturate_cast<int>(y0 - 1000*(a));

			x1=pt1.x;
			y1=pt1.y;
			x2=pt2.x;
			y2=pt2.y;
	
			if(x1<x2){
				x3=x1-x2;
			}else{
				x3=x2-x1;
			}

			if(y1>y2){
				y3=y1-y2;
			}else{
				y3=y2-y1;
			}
	
			tantan=atan2(y3,x3);
			amo=fabs(tantan);
			d=amo*180/PI;
			amari=d%360;

			printf("//////////////////////\n");

			printf("x1\n");
			printf("%f\n",x1);

			printf("y1\n");
			printf("%f\n",y1);

			printf("x2\n");
			printf("%f\n",x2);

			printf("y2\n");
			printf("%f\n",y2);

			printf("x3\n");
			printf("%f\n",x3);

			printf("y3\n");
			printf("%f\n",y3);

			printf("tantan\n");
			printf("%f\n",tantan);

			printf("amo\n");
			printf("%d\n",amo);

			printf("d\n");
			printf("%d\n",d);
	
			printf("amari\n");
			printf("%d\n",amari);

			if(0<amari&&amari<360){
				cv::line(dst_img, pt1, pt2, cv::Scalar(0,0,255), 3, CV_AA);
			}
		}
		cv::namedWindow("HoughLines", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);
		//cv::imshow("HoughLines", dst_img);
		cv::imwrite(filename02,dst_img);
		//cv::waitKey(0);
	}
	cv::waitKey(0);
}


Re: openCVを使ったハフ変換で角度を限定して検出したい

Posted: 2015年7月03日(金) 13:43
by usao
40行目:
>float rho = (*it)[0], theta = (*it)[1];

でのthetaが何なのかわかってますか?

Re: openCVを使ったハフ変換で角度を限定して検出したい

Posted: 2015年7月06日(月) 09:20
by パンフ
よくわからず使っていました。
式の勉強からやり直してきます。
ご回答ありがとうございました。

Re: openCVを使ったハフ変換で角度を限定して検出したい

Posted: 2015年7月06日(月) 10:19
by usao
オフトピック
>方法がわからずこのような方法になってしまいました。

値の正体が不明な状態で,いろいろやってみてるんですか?
まずもって
「cv::HoughLines()という関数を使うぞー(あるいは使われてるぞー)」ってなった時に
リファレンス等で引数の意味などを調べたりとかしないのでしょうか?
以下,調べればわかることそのまんまですが…

>float rho = (*it)[0], theta = (*it)[1];

直線上で原点(0,0)に最も近い点Pに関して,
・rho : (0,0)から点Pまでの距離
・theta : (0,0)から見たPの方向 = 直線の法線の向き
です.

なので,

>・検出した直線の角度を判別し、描画するかしないかを判断する方法

は本来自明ですよね.

Re: openCVを使ったハフ変換で角度を限定して検出したい

Posted: 2015年7月06日(月) 18:43
by usao
>・ある範囲の角度の直線のみを検出する方法

こちらについては,ハフ変換では
不要な角度部分のハフ空間をそもそも設けない(=そういうパラメタには投票しない)
ことで達成できると思いますが,
cv::HoughLines() ではそういった指定はできないようです.
オフトピック
cv::HoughLines()に入力する2値画像の時点で
不要な直線を構成すると思われる点を(何らかの方法で判定して)消しておく
という方針も考えられますが…

Re: openCVを使ったハフ変換で角度を限定して検出したい

Posted: 2015年7月07日(火) 14:57
by パンフ
・検出した直線の角度を判別し、描画するかしないかを判断する方法
はなんとかできそうです。

・ある範囲の角度の直線のみを検出する方法
についてはハフ変換の原理等の理解を深めてから
opencvを使わず、挑戦してみます。

ありがとうございました。