FindChessboardCorners无法通过长焦距镜头检测非常大的图像上的棋盘

tom*_*234 15 c++ opencv computer-vision camera-calibration

我可以将FindChessboardCorners函数用于小于15百万像素的图像,如2k x 1.5k.然而,当我在DSLR的图像上使用它时,分辨率为3700x5300,它不起作用.

我试图使用resize()直接缩小图像大小,然后它工作.

显然,OpenCV源代码中存在一些硬编码或错误.

你能帮我解决一下,还是指点一下这个补丁?

我发现有人在2006年发布了类似的问题,在这里,所以它看起来像问题仍然存在.

我使用的代码就像

found = findChessboardCorners( viewGray, boardSize, ptvec,
                                CV_CALIB_CB_ADAPTIVE_THRESH + CV_CALIB_CB_FILTER_QUADS + CV_CALIB_CB_NORMALIZE_IMAGE + CV_CALIB_CB_FAST_CHECK);
Run Code Online (Sandbox Code Playgroud)

更新

就在这里澄清一下.我认为该算法适用于较大的图像分辨率,但当棋​​盘占据较大比例的图像时,它会失败.例如,当我在相同的相机位置使用50mm固定镜头时,FindChessboardCorners永远不会失败.将其更改为100mm固定镜头后,该功能开始停止检测图案.我认为这与比例或焦距有关.

下图是100mm镜头效果.

更新2

我为大图像添加了一个锐化滤镜,它开始解决问题.

首先我用过

//do a sharpen filter for the large resolution image
if (viewGray.cols > 1500)
{
  Mat temp ;
  GaussianBlur(viewGray,temp, Size(0,0), 105) ; //hardcoded filter size, to be tested on 50 mm lens
  addWeighted(viewGray, 1.8, temp, -0.8,0,viewGray) ; //hardcoded weight, to be tested.
//imwrite("test"+ imageList[k][i], viewGray) ;

}

found = findChessboardCorners( viewGray, boardSize, ptvec,
CV_CALIB_CB_ADAPTIVE_THRESH + CV_CALIB_CB_FILTER_QUADS + CV_CALIB_CB_NORMALIZE_IMAGE + CV_CALIB_CB_FAST_CHECK);
Run Code Online (Sandbox Code Playgroud)

上传图片:

原始分辨率为3744 x 5616的jpg图像,如果此站点强制转换,则确保您使用的是正确的分辨率.

原始分辨率为3744 x 5616的jpg图像,如果此站点强制转换,则确保您使用的是正确的分辨率.

Fra*_*ari 25

几点.

  1. 正如您所注意到的,缩小尺寸有助于探测器.这是因为OpenCV中用于找到角落的角点检测滤波器具有固定的大小,并且卷积掩模的大小可能太小而无法检测到您的角落 - 全尺寸图像实际上可能在该尺度上看起来"平滑",尤其是它有点模糊.但是,通过降尺度,您可以丢弃一些角落定位精度.
  2. 出于同样的原因,锐化也有帮助.然而,它也违背了准确性,因为它增加了角落的子像素位置的偏差 - 即使在没有噪声的理想情况下也是如此.为了让自己相信这种情况,请考虑一维模拟:角落周围的图像强度(在1D中,一个明显的黑白过渡)看起来像一个S形曲线(一个有光滑角落的斜坡),你想要的找到其拐点的位置.锐化会使曲线更陡峭,这通常会移动该点的位置.当你考虑到锐化通常会放大噪音时情况变得更糟.
  3. 可能正确的方法是以较低的分辨率(即缩小尺寸)开始,然后按比例放大所找到的角落的位置,并将它们用作全分辨率的cvFindCornersSubpix运行的初始估计.