OpenCV轮廓检测 物体旋转角度

原文地址:http://blog.csdn.net/wangyaninglm/article/details/43959947

 

效果还是有点问题的,希望大家共同探讨一下

 

OpenCV轮廓检测 物体旋转角度_第1张图片

OpenCV轮廓检测 物体旋转角度_第2张图片

 

OpenCV轮廓检测 物体旋转角度_第3张图片

[cpp] view plain copy print ?
  1. // FindRotation-angle.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. // findContours.cpp : 定义控制台应用程序的入口点。  
  5. //  
  6.   
  7. #include "stdafx.h"  
  8.   
  9.   
  10.   
  11. #include   
  12. #include   
  13. #include    
  14. #include   
  15. #include   
  16. #include   
  17.   
  18.   
  19. #pragma comment(lib,"opencv_core2410d.lib")        
  20. #pragma comment(lib,"opencv_highgui2410d.lib")        
  21. #pragma comment(lib,"opencv_imgproc2410d.lib")   
  22.   
  23. #define PI 3.1415926  
  24.   
  25. using namespace std;  
  26. using namespace cv;  
  27.   
  28.   
  29.   
  30. int hough_line(Mat src)  
  31. {  
  32.     //【1】载入原始图和Mat变量定义     
  33.     Mat srcImage = src;//imread("1.jpg");  //工程目录下应该有一张名为1.jpg的素材图  
  34.     Mat midImage,dstImage;//临时变量和目标图的定义  
  35.   
  36.     //【2】进行边缘检测和转化为灰度图  
  37.     Canny(srcImage, midImage, 50, 200, 3);//进行一此canny边缘检测  
  38.     cvtColor(midImage,dstImage, CV_GRAY2BGR);//转化边缘检测后的图为灰度图  
  39.   
  40.     //【3】进行霍夫线变换  
  41.     vector lines;//定义一个矢量结构lines用于存放得到的线段矢量集合  
  42.     HoughLinesP(midImage, lines, 1, CV_PI/180, 80, 50, 10 );  
  43.   
  44.     //【4】依次在图中绘制出每条线段  
  45.     forsize_t i = 0; i < lines.size(); i++ )  
  46.     {  
  47.         Vec4i l = lines[i];  
  48.         line( dstImage, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(186,88,255), 1, CV_AA);  
  49.     }  
  50.   
  51.     //【5】显示原始图    
  52.     imshow("【原始图】", srcImage);    
  53.   
  54.     //【6】边缘检测后的图   
  55.     imshow("【边缘检测后的图】", midImage);    
  56.   
  57.     //【7】显示效果图    
  58.     imshow("【效果图】", dstImage);    
  59.   
  60.     //waitKey(0);    
  61.   
  62.     return 0;    
  63. }  
  64.   
  65. int main()  
  66. {  
  67.     // Read input binary image  
  68.   
  69.     char *image_name = "test.jpg";  
  70.     cv::Mat image = cv::imread(image_name,0);  
  71.     if (!image.data)  
  72.         return 0;   
  73.   
  74.     cv::namedWindow("Binary Image");  
  75.     cv::imshow("Binary Image",image);  
  76.   
  77.   
  78.       
  79.     // 从文件中加载原图    
  80.        IplImage *pSrcImage = cvLoadImage(image_name, CV_LOAD_IMAGE_UNCHANGED);    
  81.         
  82.            // 转为2值图  
  83.           
  84.      cvThreshold(pSrcImage,pSrcImage,200,255,cv::THRESH_BINARY_INV);  
  85.              
  86.       
  87.        image = cv::Mat(pSrcImage,true);  
  88.   
  89.        cv::imwrite("binary.jpg",image);  
  90.   
  91.     // Get the contours of the connected components  
  92.     std::vector> contours;  
  93.     cv::findContours(image,   
  94.         contours, // a vector of contours   
  95.         CV_RETR_EXTERNAL, // retrieve the external contours  
  96.         CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours  
  97.   
  98.     // Print contours' length  
  99.     std::cout << "Contours: " << contours.size() << std::endl;  
  100.     std::vector>::const_iterator itContours= contours.begin();  
  101.     for ( ; itContours!=contours.end(); ++itContours)   
  102.     {  
  103.   
  104.         std::cout << "Size: " << itContours->size() << std::endl;  
  105.     }  
  106.   
  107.     // draw black contours on white image  
  108.     cv::Mat result(image.size(),CV_8U,cv::Scalar(255));  
  109.     cv::drawContours(result,contours,  
  110.         -1, // draw all contours  
  111.         cv::Scalar(0), // in black  
  112.         2); // with a thickness of 2  
  113.   
  114.     cv::namedWindow("Contours");  
  115.     cv::imshow("Contours",result);  
  116.   
  117.   
  118.   
  119.   
  120.   
  121.   
  122.     // Eliminate too short or too long contours  
  123.     int cmin= 100;  // minimum contour length  
  124.     int cmax= 1000; // maximum contour length  
  125.     std::vector>::const_iterator itc= contours.begin();  
  126.     while (itc!=contours.end()) {  
  127.   
  128.         if (itc->size() < cmin || itc->size() > cmax)  
  129.             itc= contours.erase(itc);  
  130.         else   
  131.             ++itc;  
  132.     }  
  133.   
  134.     // draw contours on the original image  
  135.     cv::Mat original= cv::imread(image_name);  
  136.     cv::drawContours(original,contours,  
  137.         -1, // draw all contours  
  138.         cv::Scalar(255,255,0), // in white  
  139.         2); // with a thickness of 2  
  140.   
  141.     cv::namedWindow("Contours on original");  
  142.     cv::imshow("Contours on original",original);  
  143.   
  144.       
  145.   
  146.     // Let's now draw black contours on white image  
  147.     result.setTo(cv::Scalar(255));  
  148.     cv::drawContours(result,contours,  
  149.         -1, // draw all contours  
  150.         cv::Scalar(0), // in black  
  151.         1); // with a thickness of 1  
  152.     image= cv::imread("binary.jpg",0);  
  153.   
  154.     //imshow("lll",result);  
  155.     //waitKey(0);  
  156.   
  157.     // testing the bounding box   
  158.     //////////////////////////////////////////////////////////////////////////////  
  159.     //霍夫变换进行直线检测,此处使用的是probabilistic Hough transform(cv::HoughLinesP)而不是standard Hough transform(cv::HoughLines)  
  160.   
  161.     cv::Mat result_line(image.size(),CV_8U,cv::Scalar(255));  
  162.     result_line = result.clone();  
  163.   
  164.     hough_line(result_line);  
  165.   
  166.     //Mat tempimage;  
  167.   
  168.     //【2】进行边缘检测和转化为灰度图  
  169.     //Canny(result_line, tempimage, 50, 200, 3);//进行一此canny边缘检测  
  170.     //imshow("canny",tempimage);  
  171.     //waitKey(0);  
  172.   
  173.     //cvtColor(tempimage,result_line, CV_GRAY2BGR);//转化边缘检测后的图为灰度图  
  174.     vector lines;  
  175.   
  176.     cv::HoughLinesP(result_line,lines,1,CV_PI/180,80,50,10);  
  177.   
  178.     for(int i = 0; i < lines.size(); i++)  
  179.     {  
  180.         line(result_line,cv::Point(lines[i][0],lines[i][1]),cv::Point(lines[i][2],lines[i][3]),Scalar(0,0,0),2,8,0);  
  181.     }  
  182.     cv::namedWindow("line");  
  183.     cv::imshow("line",result_line);  
  184.     //waitKey(0);  
  185.   
  186.     /////////////////////////////////////////////////////////////////////////////////////////////  
  187.     //  
  188.   
  189.     //std::vector>::const_iterator itc_rec= contours.begin();  
  190.     //while (itc_rec!=contours.end())  
  191.     //{  
  192.     //  cv::Rect r0= cv::boundingRect(cv::Mat(*(itc_rec)));  
  193.     //  cv::rectangle(result,r0,cv::Scalar(0),2);  
  194.     //      ++itc_rec;  
  195.     //}  
  196.   
  197.       
  198.   
  199.     //cv::namedWindow("Some Shape descriptors");  
  200.     //cv::imshow("Some Shape descriptors",result);  
  201.   
  202.   
  203.     CvBox2D     End_Rage2D;  
  204.     CvPoint2D32f rectpoint[4];  
  205.     CvMemStorage *storage = cvCreateMemStorage(0);  //开辟内存空间  
  206.   
  207.   
  208.     CvSeq*      contour = NULL;     //CvSeq类型 存放检测到的图像轮廓边缘所有的像素值,坐标值特征的结构体以链表形式  
  209.   
  210.     cvFindContours( pSrcImage, storage, &contour, sizeof(CvContour),CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);//这函数可选参数还有不少  
  211.   
  212.   
  213.   
  214.     for(; contour; contour = contour->h_next)   //如果contour不为空,表示找到一个以上轮廓,这样写法只显示一个轮廓  
  215.         //如改为for(; contour; contour = contour->h_next) 就可以同时显示多个轮廓  
  216.     {    
  217.   
  218.         End_Rage2D = cvMinAreaRect2(contour);    
  219.         //代入cvMinAreaRect2这个函数得到最小包围矩形  这里已得出被测物体的角度,宽度,高度,和中点坐标点存放在CvBox2D类型的结构体中,  
  220.         //主要工作基本结束。  
  221.         for(int i = 0;i< 4;i++)  
  222.         {  
  223.               //CvArr* s=(CvArr*)&result;  
  224.             //cvLine(s,cvPointFrom32f(rectpoint[i]),cvPointFrom32f(rectpoint[(i+1)%4]),CV_G(0,0,255),2);  
  225.             line(result,cvPointFrom32f(rectpoint[i]),cvPointFrom32f(rectpoint[(i+1)%4]),Scalar(125),2);  
  226.         }   
  227.         cvBoxPoints(End_Rage2D,rectpoint);  
  228.       
  229.     std::cout <<" angle:\n"<<(float)End_Rage2D.angle << std::endl;      //被测物体旋转角度   
  230.       
  231.     }  
  232.     cv::imshow("lalalal",result);  
  233.     cv::waitKey();  
  234.     return 0;  
  235.   
  236.   
  237. }  


 

 

 

OpenCV轮廓检测 物体旋转角度_第4张图片

 

这个是原来实现的代码的博客文章:

http://blog.csdn.net/wangyaninglm/article/details/41864251

 

 

参考文献:

http://blog.csdn.net/z397164725/article/details/7248096

http://blog.csdn.net/fdl19881/article/details/6730112

http://blog.csdn.net/mine1024/article/details/6044856


你可能感兴趣的:(Opencv)