opencv 凹凸性检测 和 缺陷分析

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.youkuaiyun.com/lichengyu/article/details/38392473

 一 概念:

Convexity hull, Convexity defects

 

 

 

如上图所示,黑色的轮廓线为convexity hull, 而convexity hull与手掌之间的部分为convexity defects. 每个convexity defect区域有四个特征量:起始点(startPoint),结束点(endPoint),距离convexity hull最远点(farPoint),最远点到convexity hull的距离(depth)。

 

二.OpenCV中的相关函数

void convexityDefects(InputArray contour, InputArray convexhull, OutputArrayconvexityDefects)

参数:

coutour: 输入参数,检测到的轮廓,可以调用findContours函数得到;

convexhull: 输入参数,检测到的凸包,可以调用convexHull函数得到。注意,convexHull函数可以得到vector<vector<Point>>和vector<vector<int>>两种类型结果,这里的convexhull应该为vector<vector<int>>类型,否则通不过ASSERT检查;

convexityDefects:输出参数,检测到的最终结果,应为vector<vector<Vec4i>>类型,Vec4i存储了起始点(startPoint),结束点(endPoint),距离convexity hull最远点(farPoint)以及最远点到convexity hull的距离(depth)

 

三.代码


 
 
  1. //http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/hull/hull.html
  2. //http://www.codeproject.com/Articles/782602/Beginners-guide-to-understand-Fingertips-counting
  3. #include "opencv2/highgui/highgui.hpp"
  4. #include "opencv2/imgproc/imgproc.hpp"
  5. #include <iostream>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. using namespace cv;
  9. using namespace std;
  10. Mat src; Mat src_gray;
  11. int thresh = 100;
  12. int max_thresh = 255;
  13. RNG rng(12345);
  14. /// Function header
  15. void thresh_callback(int, void* );
  16. /** @function main */
  17. int main( int argc, char** argv )
  18. {
  19. /// Load source image and convert it to gray
  20. src = imread( argv[ 1], 1 );
  21. /// Convert image to gray and blur it
  22. cvtColor( src, src_gray, CV_BGR2GRAY );
  23. blur( src_gray, src_gray, Size( 3, 3) );
  24. /// Create Window
  25. char* source_window = "Source";
  26. namedWindow( source_window, CV_WINDOW_AUTOSIZE );
  27. imshow( source_window, src );
  28. createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback );
  29. thresh_callback( 0, 0 );
  30. waitKey( 0);
  31. return( 0);
  32. }
  33. /** @function thresh_callback */
  34. void thresh_callback(int, void* )
  35. {
  36. Mat src_copy = src.clone();
  37. Mat threshold_output;
  38. vector< vector<Point> > contours;
  39. vector<Vec4i> hierarchy;
  40. /// Detect edges using Threshold
  41. threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
  42. /// Find contours
  43. findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point( 0, 0) );
  44. /// Find the convex hull object for each contour
  45. vector< vector<Point> >hull( contours.size() );
  46. // Int type hull
  47. vector< vector< int>> hullsI( contours.size() );
  48. // Convexity defects
  49. vector< vector<Vec4i>> defects( contours.size() );
  50. for( size_t i = 0; i < contours.size(); i++ )
  51. {
  52. convexHull( Mat(contours[i]), hull[i], false );
  53. // find int type hull
  54. convexHull( Mat(contours[i]), hullsI[i], false );
  55. // get convexity defects
  56. convexityDefects(Mat(contours[i]),hullsI[i], defects[i]);
  57. }
  58. /// Draw contours + hull results
  59. Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
  60. for( size_t i = 0; i< contours.size(); i++ )
  61. {
  62. Scalar color = Scalar( rng.uniform( 0, 255), rng.uniform( 0, 255), rng.uniform( 0, 255) );
  63. drawContours( drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
  64. drawContours( drawing, hull, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
  65. // draw defects
  66. size_t count = contours[i].size();
  67. std:: cout<< "Count : "<<count<< std:: endl;
  68. if( count < 300 )
  69. continue;
  70. vector<Vec4i>::iterator d =defects[i].begin();
  71. while( d!=defects[i].end() ) {
  72. Vec4i& v=(*d);
  73. //if(IndexOfBiggestContour == i)
  74. {
  75. int startidx=v[ 0];
  76. Point ptStart( contours[i][startidx] ); // point of the contour where the defect begins
  77. int endidx=v[ 1];
  78. Point ptEnd( contours[i][endidx] ); // point of the contour where the defect ends
  79. int faridx=v[ 2];
  80. Point ptFar( contours[i][faridx] ); // the farthest from the convex hull point within the defect
  81. int depth = v[ 3] / 256; // distance between the farthest point and the convex hull
  82. if(depth > 20 && depth < 80)
  83. {
  84. line( drawing, ptStart, ptFar, CV_RGB( 0, 255, 0), 2 );
  85. line( drawing, ptEnd, ptFar, CV_RGB( 0, 255, 0), 2 );
  86. circle( drawing, ptStart, 4, Scalar( 255, 0, 100), 2 );
  87. circle( drawing, ptEnd, 4, Scalar( 255, 0, 100), 2 );
  88. circle( drawing, ptFar, 4, Scalar( 100, 0, 255), 2 );
  89. }
  90. /*printf("start(%d,%d) end(%d,%d), far(%d,%d)\n",
  91. ptStart.x, ptStart.y, ptEnd.x, ptEnd.y, ptFar.x, ptFar.y);*/
  92. }
  93. d++;
  94. }
  95. }
  96. /// Show in a window
  97. namedWindow( "Hull demo", CV_WINDOW_AUTOSIZE );
  98. imshow( "Hull demo", drawing );
  99. //imwrite("convexity_defects.jpg", drawing);
  100. }


四.结果

 

原图

 

Convexity defects图,蓝色点是convexity defects的起始点和结束点,红色点是最远点。(为什么有的起始点和结束点中间没有最远点呢?因为只画出了depth范围在20到80之间的convexity defects的起始点、结束点和最远点)

 

五.参考

[1] Gary BradskiAdrian KaehlerLearning OpenCV: Computer Vision with the OpenCV Library. Page258~259.

[2] http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/hull/hull.html

[3] http://www.codeproject.com/Articles/782602/Beginners-guide-to-understand-Fingertips-counting

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值