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

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

OpenCV 应用边缘检测与霍夫线变换实现旋转角度检测_第1张图片

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

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

OpenCV 应用边缘检测与霍夫线变换实现旋转角度检测_第2张图片

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

OpenCV 应用边缘检测与霍夫线变换实现旋转角度检测_第3张图片

    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 > contours;
        vectorhierarchy;
        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 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<<"霍夫线检测角度="<double angleaverage =angleall/anglenum;
        cout<<"角度平个数="<cout<<"角度平均值="<double)getTickCount() - t;
        printf("execution time = %lfms\n", t*1000. / getTickFrequency());
        waitKey(0);
        getchar();
        return 0;

结果:

OpenCV 应用边缘检测与霍夫线变换实现旋转角度检测_第4张图片

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

你可能感兴趣的:(#,OpenCV)