OpenCV 应用边缘检测与霍夫线变换实现旋转角度检测

2022-05-07 09:28:19 浏览数 (1)

首先我们需要画出一个这样的图片,此时兴趣区域的角度为0度

使用opencv的图片旋转功能,把它旋转一个角度,旋转方法参考: http://blog.csdn.net/chaipp0607/article/details/63263347

逆时针旋转3.3度后,作为待检测图片。

由于我的原始图片很大2592*2048,前面做了很多预处理工作,流程图:

代码语言:javascript复制
	double t = (double)getTickCount();
	Mat SrcImage;
	Mat ResizeImage;
	Mat  ResizeroiImage;
	Mat SrcroiImage;
	Mat grayImage;
	Mat thresholdImage;
	Mat  roiimage;
	Mat CannyImage;
	Mat ThinImage;
	double Srccutpointx,Srccutpointy,time;
		int  anglenum = 0;
		double angleall = 0;
		SrcImage = imread("3_000_3.3.bmp");
		cvtColor(SrcImage,grayImage,CV_BGR2GRAY);
		Size dsize = Size(grayImage.cols*0.1,grayImage.rows*0.1);
		resize(grayImage, ResizeImage,dsize);
		ResizeroiImage = ResizeImage(Rect(ResizeImage.cols/3,ResizeImage.rows/3,ResizeImage.cols/3,ResizeImage.rows/3));
		threshold(ResizeroiImage,thresholdImage, 0, 255, CV_THRESH_OTSU CV_THRESH_BINARY);
		vector<vector<Point> > contours;
		vector<Vec4i>hierarchy;
		findContours(thresholdImage,contours,hierarchy,CV_RETR_TREE,CV_CHAIN_APPROX_NONE);  
		for(int k = 0; k < (int)contours.size(); k  )    //查找轮廓
		{
			if (contours.at(k).size()>100)
			{
				//把原图的rio区域涂成蓝色
				// drawContours(SrcroiImage, contours, k, Scalar(255,0,0), CV_FILLED);
				Rect position = boundingRect(contours.at(k));
				//在缩小的图上画出芯片位置
				// rectangle(
				//ResizeImage,
				//Point(position.tl().x ResizeImage.cols/3, position.tl().y ResizeImage.rows/3),
				//Point(position.br().x ResizeImage.cols/3, position.br().y ResizeImage.rows/3),
				//Scalar(0,0,255));

				//在原图上画出芯片位置
				// rectangle(
				//SrcImage,
				//Point(10*(position.tl().x ResizeImage.cols/3)-30, 10*(position.tl().y ResizeImage.rows/3)-30),
				//Point(10*(position.br().x ResizeImage.cols/3) 30, 10*(position.br().y ResizeImage.rows/3) 30),
				//Scalar(0,0,255));

				//在原图上截取出芯片位置		
				SrcroiImage =SrcImage(Rect(
					10*(position.tl().x ResizeImage.cols/3)-30,
					10*(position.tl().y ResizeImage.rows/3)-30,
					10*position.width 60,
					10*position.height 60));

				Srccutpointx =	10*(position.tl().x ResizeImage.cols/3)-30;
				Srccutpointy =	10*(position.tl().y ResizeImage.rows/3)-30;
				//  roiimage = SrcImage(juxing);
				//	  mu[k] = moments( contours[k], false );   
				//		  mc[k] = Point2d( mu[k].m10/mu[k].m00 , mu[k].m01/mu[k].m00 ); 
				//		  Point center = Point(mc[k].x,mc[k].y);  
				//		  int r = 1;  
				//		  circle(SrcImage,center,r,Scalar(0,0,255),-1);  
				//		  printf("x=%f,y=%fn",mc[k].x,mc[k].y);
			}
		}
		Mat DelSrcroiImage;
		Mat ThreholdsrcroiImage;
		Mat graysrcroiImage;
		SrcroiImage.copyTo(DelSrcroiImage);
		cvtColor(SrcroiImage,graysrcroiImage,CV_BGR2GRAY);
		blur( graysrcroiImage, graysrcroiImage, Size(7,7) );
		threshold(graysrcroiImage,ThreholdsrcroiImage, 0, 255, CV_THRESH_OTSU CV_THRESH_BINARY);
		Canny(ThreholdsrcroiImage, CannyImage, 50, 200, 3);
		vector<Vec4i> mylines;
		HoughLinesP(CannyImage, mylines, 1, CV_PI/180, 100, 200, 10 );

		for( size_t j = 0; j < mylines.size(); j   )  
		{
			Vec4d l = mylines[j]; 

			if (l[0]!=l[2]&&l[1]!=l[3])
			{
				anglenum   ;
				Point start = Point (l[0], l[1]);  
				Point end =  Point (l[2], l[3]);  	
				line(DelSrcroiImage,start,end,Scalar(255));
				double  duijixoabian = l[1]-l[3];
				double  linbian = l[2]-l[0];
				double  radian = atan(duijixoabian/linbian);
				double  angle =(radian*180)/CV_PI;
				angleall = angleall angle;
				cout<<"霍夫线检测角度="<<angle<<endl;
			}
		}
		double angleaverage =angleall/anglenum;
		cout<<"角度平个数="<<anglenum<<endl;
		cout<<"角度平均值="<<angleaverage<<endl;

	    t = (double)getTickCount() - t;
   	    printf("execution time = %lfmsn", t*1000. / getTickFrequency());
	    waitKey(0);
	    getchar();
	    return 0;

结果:

可以看到,结果的误差在0.3度左右,霍夫直线检测作为角度测量应用中的效果一般。

0 人点赞