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.2 kB

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