opencv / opencv_contrib

Repository for OpenCV's extra modules
Apache License 2.0
9.24k stars 5.73k forks source link

aruco::CharucoBoard::draw() crashes with specific image size #1226

Closed spium closed 7 years ago

spium commented 7 years ago
System information (version)
Detailed description

When calling cv::aruco::CharucoBoard::draw() using specific board and image sizes, code crashes with OpenCV Error: Assertion failed (!fixedSize() || ((Mat*)obj)->size.operator()() == Size(_cols, _rows)) in create. Specifically, I've been able to reproduce the problem when creating a 7x5 board and then drawing it at size 1600x1200 pixels.

Steps to reproduce
#include <opencv2/opencv.hpp>
#include <opencv2/aruco.hpp>
#include <opencv2/aruco/charuco.hpp>
int main(int argc, char **argv)
{
  int squares_x = 7,
      squares_y = 5;

  int bwidth = 1600,
      bheight = 1200;

  cv::Ptr<cv::aruco::Dictionary> dict = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_50);
  cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create(squares_x, squares_y, 1.0, 0.75, dict);
  cv::Size sz(bwidth, bheight);
  cv::Mat mat;
  board->draw(sz, mat, 0, 1);
  cv::imshow("test", mat);
  cv::waitKey(-1);
  return 0;
}

This code triggers the bug. Changing the size of the board to, e.g. 9x7, or changing the size of the image to, eg. 1600x1201, does not trigger the bug.

Possible fix

I've managed to trace the bug to cv::aruco::_drawPlanarBoardImpl() at line 1683 (https://github.com/opencv/opencv_contrib/blob/master/modules/aruco/src/aruco.cpp#L1683):

if((outCorners[0].y == outCorners[1].y) && (outCorners[1].x == outCorners[2].x)) {
            // marker is aligned to image axes
            marker.copyTo(out(Rect(outCorners[0], dst_sz)));
            continue;
}

When using the parameters above, dst_sz == Size(172, 171) whereas marker.size() == Size(172,172), which causes the crash. I managed to fix it simply by adding the condition that marker.size() == dst_sz. It seems to work correctly, but I'm not expert enough on the matter to know whether it's the right fix.

sovrasov commented 7 years ago

The problem is caused by the rounding in line 1678. I think your fix is correct, but it can block the optimization in some cases. Take a look at the my fix: #1230