You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

FineMapping.cpp 7.9 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. //
  2. // Created by 庾金科 on 22/09/2017.
  3. //
  4. #include "FineMapping.h"
  5. namespace pr{
  6. const int FINEMAPPING_H = 50;
  7. const int FINEMAPPING_W = 120;
  8. const int PADDING_UP_DOWN = 30;
  9. void drawRect(cv::Mat image,cv::Rect rect)
  10. {
  11. cv::Point p1(rect.x,rect.y);
  12. cv::Point p2(rect.x+rect.width,rect.y+rect.height);
  13. cv::rectangle(image,p1,p2,cv::Scalar(0,255,0),1);
  14. }
  15. FineMapping::FineMapping(std::string prototxt,std::string caffemodel) {
  16. net = cv::dnn::readNetFromCaffe(prototxt, caffemodel);
  17. }
  18. cv::Mat FineMapping::FineMappingHorizon(cv::Mat FinedVertical,int leftPadding,int rightPadding)
  19. {
  20. // if(FinedVertical.channels()==1)
  21. // cv::cvtColor(FinedVertical,FinedVertical,cv::COLOR_GRAY2BGR);
  22. cv::Mat inputBlob = cv::dnn::blobFromImage(FinedVertical, 1/255.0, cv::Size(66,16),
  23. cv::Scalar(0,0,0),false);
  24. net.setInput(inputBlob,"data");
  25. cv::Mat prob = net.forward();
  26. int front = static_cast<int>(prob.at<float>(0,0)*FinedVertical.cols);
  27. int back = static_cast<int>(prob.at<float>(0,1)*FinedVertical.cols);
  28. front -= leftPadding ;
  29. if(front<0) front = 0;
  30. back +=rightPadding;
  31. if(back>FinedVertical.cols-1) back=FinedVertical.cols - 1;
  32. cv::Mat cropped = FinedVertical.colRange(front,back).clone();
  33. return cropped;
  34. }
  35. std::pair<int,int> FitLineRansac(std::vector<cv::Point> pts,int zeroadd = 0 )
  36. {
  37. std::pair<int,int> res;
  38. if(pts.size()>2)
  39. {
  40. cv::Vec4f line;
  41. cv::fitLine(pts,line,cv::DIST_HUBER,0,0.01,0.01);
  42. float vx = line[0];
  43. float vy = line[1];
  44. float x = line[2];
  45. float y = line[3];
  46. int lefty = static_cast<int>((-x * vy / vx) + y);
  47. int righty = static_cast<int>(((136- x) * vy / vx) + y);
  48. res.first = lefty+PADDING_UP_DOWN+zeroadd;
  49. res.second = righty+PADDING_UP_DOWN+zeroadd;
  50. return res;
  51. }
  52. res.first = zeroadd;
  53. res.second = zeroadd;
  54. return res;
  55. }
  56. cv::Mat FineMapping::FineMappingVertical(cv::Mat InputProposal,int sliceNum,int upper,int lower,int windows_size){
  57. cv::Mat PreInputProposal;
  58. cv::Mat proposal;
  59. cv::resize(InputProposal,PreInputProposal,cv::Size(FINEMAPPING_W,FINEMAPPING_H));
  60. if(InputProposal.channels() == 3)
  61. cv::cvtColor(PreInputProposal,proposal,cv::COLOR_BGR2GRAY);
  62. else
  63. PreInputProposal.copyTo(proposal);
  64. // proposal = PreInputProposal;
  65. // this will improve some sen
  66. cv::Mat kernal = cv::getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(1,3));
  67. // cv::erode(proposal,proposal,kernal);
  68. float diff = static_cast<float>(upper-lower);
  69. diff/=static_cast<float>(sliceNum-1);
  70. cv::Mat binary_adaptive;
  71. std::vector<cv::Point> line_upper;
  72. std::vector<cv::Point> line_lower;
  73. int contours_nums=0;
  74. for(int i = 0 ; i < sliceNum ; i++)
  75. {
  76. std::vector<std::vector<cv::Point> > contours;
  77. float k =lower + i*diff;
  78. cv::adaptiveThreshold(proposal,binary_adaptive,255,cv::ADAPTIVE_THRESH_MEAN_C,cv::THRESH_BINARY,windows_size,k);
  79. cv::Mat draw;
  80. binary_adaptive.copyTo(draw);
  81. cv::findContours(binary_adaptive,contours,cv::RETR_EXTERNAL,cv::CHAIN_APPROX_SIMPLE);
  82. for(auto contour: contours)
  83. {
  84. cv::Rect bdbox =cv::boundingRect(contour);
  85. float lwRatio = bdbox.height/static_cast<float>(bdbox.width);
  86. int bdboxAera = bdbox.width*bdbox.height;
  87. if (( lwRatio>0.7&&bdbox.width*bdbox.height>100 && bdboxAera<300)
  88. || (lwRatio>3.0 && bdboxAera<100 && bdboxAera>10))
  89. {
  90. cv::Point p1(bdbox.x, bdbox.y);
  91. cv::Point p2(bdbox.x + bdbox.width, bdbox.y + bdbox.height);
  92. line_upper.push_back(p1);
  93. line_lower.push_back(p2);
  94. contours_nums+=1;
  95. }
  96. }
  97. }
  98. std:: cout<<"contours_nums "<<contours_nums<<std::endl;
  99. if(contours_nums<41)
  100. {
  101. cv::bitwise_not(InputProposal,InputProposal);
  102. cv::Mat kernal = cv::getStructuringElement(cv::MORPH_ELLIPSE,cv::Size(1,5));
  103. cv::Mat bak;
  104. cv::resize(InputProposal,bak,cv::Size(FINEMAPPING_W,FINEMAPPING_H));
  105. cv::erode(bak,bak,kernal);
  106. if(InputProposal.channels() == 3)
  107. cv::cvtColor(bak,proposal,cv::COLOR_BGR2GRAY);
  108. else
  109. proposal = bak;
  110. int contours_nums=0;
  111. for(int i = 0 ; i < sliceNum ; i++)
  112. {
  113. std::vector<std::vector<cv::Point> > contours;
  114. float k =lower + i*diff;
  115. cv::adaptiveThreshold(proposal,binary_adaptive,255,cv::ADAPTIVE_THRESH_MEAN_C,cv::THRESH_BINARY,windows_size,k);
  116. // cv::imshow("image",binary_adaptive);
  117. // cv::waitKey(0);
  118. cv::Mat draw;
  119. binary_adaptive.copyTo(draw);
  120. cv::findContours(binary_adaptive,contours,cv::RETR_EXTERNAL,cv::CHAIN_APPROX_SIMPLE);
  121. for(auto contour: contours)
  122. {
  123. cv::Rect bdbox =cv::boundingRect(contour);
  124. float lwRatio = bdbox.height/static_cast<float>(bdbox.width);
  125. int bdboxAera = bdbox.width*bdbox.height;
  126. if (( lwRatio>0.7&&bdbox.width*bdbox.height>120 && bdboxAera<300)
  127. || (lwRatio>3.0 && bdboxAera<100 && bdboxAera>10))
  128. {
  129. cv::Point p1(bdbox.x, bdbox.y);
  130. cv::Point p2(bdbox.x + bdbox.width, bdbox.y + bdbox.height);
  131. line_upper.push_back(p1);
  132. line_lower.push_back(p2);
  133. contours_nums+=1;
  134. }
  135. }
  136. }
  137. // std:: cout<<"contours_nums "<<contours_nums<<std::endl;
  138. }
  139. cv::Mat rgb;
  140. cv::copyMakeBorder(PreInputProposal, rgb, 30, 30, 0, 0, cv::BORDER_REPLICATE);
  141. // cv::imshow("rgb",rgb);
  142. // cv::waitKey(0);
  143. //
  144. std::pair<int, int> A;
  145. std::pair<int, int> B;
  146. A = FitLineRansac(line_upper, -2);
  147. B = FitLineRansac(line_lower, 2);
  148. int leftyB = A.first;
  149. int rightyB = A.second;
  150. int leftyA = B.first;
  151. int rightyA = B.second;
  152. int cols = rgb.cols;
  153. int rows = rgb.rows;
  154. // pts_map1 = np.float32([[cols - 1, rightyA], [0, leftyA],[cols - 1, rightyB], [0, leftyB]])
  155. // pts_map2 = np.float32([[136,36],[0,36],[136,0],[0,0]])
  156. // mat = cv2.getPerspectiveTransform(pts_map1,pts_map2)
  157. // image = cv2.warpPerspective(rgb,mat,(136,36),flags=cv2.INTER_CUBIC)
  158. std::vector<cv::Point2f> corners(4);
  159. corners[0] = cv::Point2f(cols - 1, rightyA);
  160. corners[1] = cv::Point2f(0, leftyA);
  161. corners[2] = cv::Point2f(cols - 1, rightyB);
  162. corners[3] = cv::Point2f(0, leftyB);
  163. std::vector<cv::Point2f> corners_trans(4);
  164. corners_trans[0] = cv::Point2f(136, 36);
  165. corners_trans[1] = cv::Point2f(0, 36);
  166. corners_trans[2] = cv::Point2f(136, 0);
  167. corners_trans[3] = cv::Point2f(0, 0);
  168. cv::Mat transform = cv::getPerspectiveTransform(corners, corners_trans);
  169. cv::Mat quad = cv::Mat::zeros(36, 136, CV_8UC3);
  170. cv::warpPerspective(rgb, quad, transform, quad.size());
  171. return quad;
  172. }
  173. }