fork_rs.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #include "fork_rs.h"
  2. namespace graft_cv{
  3. CForkDetectOptimal::CForkDetectOptimal()
  4. :m_roi_width(0),m_roi_height(0)
  5. {
  6. }
  7. CForkDetectOptimal::CForkDetectOptimal(int w,int h)
  8. :m_roi_width(w),m_roi_height(h)
  9. {
  10. }
  11. CForkDetectOptimal::~CForkDetectOptimal(){}
  12. void CForkDetectOptimal::set_roi_size(int w,int h){
  13. m_roi_width = w;
  14. m_roi_height = h;
  15. }
  16. void CForkDetectOptimal::get_roi_size(int &w,int &h){
  17. w = m_roi_width;
  18. h = m_roi_height;
  19. }
  20. double CForkDetectOptimal::center_pt_index(
  21. const Mat& binimg,
  22. Point&cent,
  23. double cut_angle //刀具切割角度
  24. )
  25. {
  26. double ratio = 0.0;
  27. RotatedRect centers_rect = RotatedRect(Point2f(0,0), Size2f(m_roi_width,m_roi_height), -cut_angle);//换算成顺时针角度
  28. Point2f vertices[4];
  29. centers_rect.points(vertices);
  30. Point2f left_cent = Point2f(cent.x + vertices[0].x, cent.y + vertices[0].y);
  31. Point2f right_cent = Point2f(cent.x + vertices[1].x, cent.y + vertices[1].y);
  32. RotatedRect left_rect = RotatedRect(left_cent, Size2f(m_roi_width,m_roi_height), -cut_angle);
  33. RotatedRect right_rect = RotatedRect(right_cent, Size2f(m_roi_width,m_roi_height), -cut_angle);
  34. double left_cnt = roi_object_size(binimg, left_rect);
  35. double right_cnt = roi_object_size(binimg, right_rect);
  36. ratio = left_cnt* left_cnt/right_cnt/(m_roi_width*m_roi_height);
  37. //imshow
  38. Mat tmp_img = binimg.clone();
  39. Point2f vertices_left[4];
  40. Point2f vertices_right[4];
  41. left_rect.points(vertices_left);
  42. right_rect.points(vertices_right);
  43. for (int i = 0; i < 4; i++){
  44. line(tmp_img, vertices_left[i], vertices_left[(i+1)%4], Scalar(128,255,0), 1);
  45. line(tmp_img, vertices_right[i], vertices_right[(i+1)%4], Scalar(200,255,0), 1);
  46. }
  47. circle(tmp_img,cent,5,Scalar(128,0,0));
  48. return ratio;
  49. }
  50. double CForkDetectOptimal::roi_object_size(
  51. const Mat& binimg,
  52. RotatedRect &rrect)
  53. {
  54. double cnt = 1.0;
  55. Rect brect = rrect.boundingRect();
  56. Point2f vertices[4];
  57. rrect.points(vertices);
  58. //Mat tmp_img = Mat::zeros(binimg.rows,binimg.cols,CV_8UC1);
  59. for(int r = brect.y; r<brect.y+brect.height;++r){
  60. for(int c=brect.x; c<brect.x+brect.width;++c){
  61. Point2f ptf = Point2f(c,r);
  62. bool isin = is_in_rrect(vertices,ptf, rrect.angle);
  63. if(isin){
  64. //tmp_img.at<unsigned char>(r,c) = 255;
  65. if(r<0||r>binimg.rows-1){continue;}
  66. if(c<0||c>binimg.cols-1){continue;}
  67. if(binimg.at<unsigned char>(r,c) >0){cnt+=1.0;}
  68. }
  69. }
  70. }
  71. return cnt;
  72. }
  73. bool CForkDetectOptimal::is_in_rrect(
  74. Point2f* ptf4,
  75. Point2f ptf,
  76. float fAngle)
  77. {
  78. Point2f ptf4Vector[4];
  79. int nQuadrant[4] = {0};
  80. fAngle *= CV_PI/180 *(-1);
  81. for(int idx=0;idx<4;idx++){
  82. float fDifx = float(ptf.x - ptf4[idx].x);
  83. float fDify = float(ptf.y - ptf4[idx].y);
  84. int nDifx = fDifx * cos(fAngle) - fDify * sin(fAngle);
  85. int nDify = fDifx * sin(fAngle) + fDify * cos(fAngle);
  86. if(nDifx >=0 && nDify >=0) nQuadrant[0]++;
  87. if(nDifx < 0 && nDify >=0) nQuadrant[1]++;
  88. if(nDifx < 0 && nDify < 0) nQuadrant[2]++;
  89. if(nDifx > 0 && nDify < 0) nQuadrant[3]++;
  90. }
  91. int firstIdx = -1;
  92. int secIdx = -1;
  93. int countNum = 0;
  94. for(int idx=0;idx<4;idx++){
  95. if(nQuadrant[idx] !=0){
  96. if(firstIdx == -1){
  97. firstIdx = idx;
  98. }
  99. else{
  100. if(secIdx == -1 && firstIdx != -1){
  101. secIdx = idx;
  102. }
  103. }
  104. countNum++;
  105. }
  106. }
  107. if(countNum <= 2){
  108. if(abs(firstIdx - secIdx)==1 || abs(firstIdx - secIdx)==3 ||
  109. (countNum==1 && (firstIdx==-1 || secIdx==-1)))
  110. {
  111. return false;
  112. }
  113. }
  114. return true;
  115. }
  116. };