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

来源:互联网 发布:图文广告软件下载 编辑:程序博客网 时间:2024/06/06 02:25

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

这里写图片描述

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

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

这里写图片描述

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

这里写图片描述

    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=%f\n",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 = %lfms\n", t*1000. / getTickFrequency());        waitKey(0);        getchar();        return 0;

结果:

这里写图片描述

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

2 0
原创粉丝点击