首先我们需要画出一个这样的图片,此时兴趣区域的角度为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度左右,霍夫直线检测作为角度测量应用中的效果一般。