Deskew边界框

时间:2014-06-04 05:28:51

标签: c++ opencv computer-vision bounding-box

我正在开发一个应用程序来检测图像中的卡片而我正在成功这样做但是有时卡片不是直的,它可能有轻微的倾斜。

Mat card;
card = src(bounding_box);

我觉得最好的办法是先找到边界框的倾斜,然后旋转提取的图像以纠正偏斜。

以下是找到卡片的示例:

enter image description here

并非所有卡片都有大量的偏斜,例如示例,但在某些情况下会出现相当大的偏差。

如何找到边界框的倾斜角度,然后旋转提取的图像?现在我只是这样做从图像中提取矩形

2 个答案:

答案 0 :(得分:0)

通过对结果点进行侵蚀和装箱,您可以计算角度:

double deskew(const char* filename)
{
    cv::Mat img = cv::imread(filename, 0);

    cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 3));
    cv::erode(img, img, element);

    std::vector<cv::Point> points;
    cv::Mat_<uchar>::iterator it = img.begin<uchar>();
    cv::Mat_<uchar>::iterator end = img.end<uchar>();

    for (; it != end; ++it)
       if (*it)
          points.push_back(it.pos());

    cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));

    double angle = box.angle;
    if (angle < -45.)
       angle += 90.;

    return angle;
}

OpenCV Bouding Box & Skew Angle

然后你可以歪斜:

void deskew(cv::Mat img, double angle)
{
  cv::bitwise_not(img, img);

  std::vector<cv::Point> points;
  cv::Mat_<uchar>::iterator it = img.begin<uchar>();
  cv::Mat_<uchar>::iterator end = img.end<uchar>();
  for (; it != end; ++it)
    if (*it)
      points.push_back(it.pos());

  cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));

  cv::Mat rot_mat = cv::getRotationMatrix2D(box.center, angle, 1);

  cv::Mat rotated;
  cv::warpAffine(img, rotated, rot_mat, img.size(), cv::INTER_CUBIC);
}

OpenCV Rotating/Deskewing

答案 1 :(得分:0)

您可以通过替换它来使代码更快:

cv::Mat_<uchar>::iterator it = img.begin<uchar>();
cv::Mat_<uchar>::iterator end = img.end<uchar>();
for (; it != end; ++it)
    if (*it)
      points.push_back(it.pos());`

......用这个:

points.push_back(cv::Point(0,0));
points.push_back(cv::Point(img.rows,0));
points.push_back(cv::Point(img.rows,img.cols));
points.push_back(cv::Point(0,img.cols));

你只需要更多的点,而不是所有的点。