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.

FastDeskew.cpp 4.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. //
  2. // Created by 庾金科 on 02/10/2017.
  3. //
  4. #include <../include/FastDeskew.h>
  5. namespace pr{
  6. const int ANGLE_MIN = 30 ;
  7. const int ANGLE_MAX = 150 ;
  8. const int PLATE_H = 36;
  9. const int PLATE_W = 136;
  10. int angle(float x,float y)
  11. {
  12. return atan2(x,y)*180/3.1415;
  13. }
  14. std::vector<float> avgfilter(std::vector<float> angle_list,int windowsSize) {
  15. std::vector<float> angle_list_filtered(angle_list.size() - windowsSize + 1);
  16. for (int i = 0; i < angle_list.size() - windowsSize + 1; i++) {
  17. float avg = 0.00f;
  18. for (int j = 0; j < windowsSize; j++) {
  19. avg += angle_list[i + j];
  20. }
  21. avg = avg / windowsSize;
  22. angle_list_filtered[i] = avg;
  23. }
  24. return angle_list_filtered;
  25. }
  26. void drawHist(std::vector<float> seq){
  27. cv::Mat image(300,seq.size(),CV_8U);
  28. image.setTo(0);
  29. for(int i = 0;i<seq.size();i++)
  30. {
  31. float l = *std::max_element(seq.begin(),seq.end());
  32. int p = int(float(seq[i])/l*300);
  33. cv::line(image,cv::Point(i,300),cv::Point(i,300-p),cv::Scalar(255,255,255));
  34. }
  35. cv::imshow("vis",image);
  36. }
  37. cv::Mat correctPlateImage(cv::Mat skewPlate,float angle,float maxAngle)
  38. {
  39. cv::Mat dst;
  40. cv::Size size_o(skewPlate.cols,skewPlate.rows);
  41. int extend_padding = 0;
  42. // if(angle<0)
  43. extend_padding = static_cast<int>(skewPlate.rows*tan(cv::abs(angle)/180* 3.14) );
  44. // else
  45. // extend_padding = static_cast<int>(skewPlate.rows/tan(cv::abs(angle)/180* 3.14) );
  46. // std::cout<<"extend:"<<extend_padding<<std::endl;
  47. cv::Size size(skewPlate.cols + extend_padding ,skewPlate.rows);
  48. float interval = abs(sin((angle /180) * 3.14)* skewPlate.rows);
  49. // std::cout<<interval<<std::endl;
  50. cv::Point2f pts1[4] = {cv::Point2f(0,0),cv::Point2f(0,size_o.height),cv::Point2f(size_o.width,0),cv::Point2f(size_o.width,size_o.height)};
  51. if(angle>0) {
  52. cv::Point2f pts2[4] = {cv::Point2f(interval, 0), cv::Point2f(0, size_o.height),
  53. cv::Point2f(size_o.width, 0), cv::Point2f(size_o.width - interval, size_o.height)};
  54. cv::Mat M = cv::getPerspectiveTransform(pts1,pts2);
  55. cv::warpPerspective(skewPlate,dst,M,size);
  56. }
  57. else {
  58. cv::Point2f pts2[4] = {cv::Point2f(0, 0), cv::Point2f(interval, size_o.height), cv::Point2f(size_o.width-interval, 0),
  59. cv::Point2f(size_o.width, size_o.height)};
  60. cv::Mat M = cv::getPerspectiveTransform(pts1,pts2);
  61. cv::warpPerspective(skewPlate,dst,M,size,cv::INTER_CUBIC);
  62. }
  63. return dst;
  64. }
  65. cv::Mat fastdeskew(cv::Mat skewImage,int blockSize){
  66. const int FILTER_WINDOWS_SIZE = 5;
  67. std::vector<float> angle_list(180);
  68. memset(angle_list.data(),0,angle_list.size()*sizeof(int));
  69. cv::Mat bak;
  70. skewImage.copyTo(bak);
  71. if(skewImage.channels() == 3)
  72. cv::cvtColor(skewImage,skewImage,cv::COLOR_RGB2GRAY);
  73. if(skewImage.channels() == 1)
  74. {
  75. cv::Mat eigen;
  76. cv::cornerEigenValsAndVecs(skewImage,eigen,blockSize,5);
  77. for( int j = 0; j < skewImage.rows; j+=blockSize )
  78. { for( int i = 0; i < skewImage.cols; i+=blockSize )
  79. {
  80. float x2 = eigen.at<cv::Vec6f>(j, i)[4];
  81. float y2 = eigen.at<cv::Vec6f>(j, i)[5];
  82. int angle_cell = angle(x2,y2);
  83. angle_list[(angle_cell + 180)%180]+=1.0;
  84. }
  85. }
  86. }
  87. std::vector<float> filtered = avgfilter(angle_list,5);
  88. int maxPos = std::max_element(filtered.begin(),filtered.end()) - filtered.begin() + FILTER_WINDOWS_SIZE/2;
  89. if(maxPos>ANGLE_MAX)
  90. maxPos = (-maxPos+90+180)%180;
  91. if(maxPos<ANGLE_MIN)
  92. maxPos-=90;
  93. maxPos=90-maxPos;
  94. cv::Mat deskewed = correctPlateImage(bak, static_cast<float>(maxPos),60.0f);
  95. return deskewed;
  96. }
  97. }//namespace pr