FindChessboardCorners не может обнаружить шахматную доску на очень больших изображениях с помощью объектива с большим фокусным расстоянием

Я могу использовать функции FindChessboardCorners для изображений размером менее 15 мегапикселей, таких как 2k x 1.5k. Однако, когда я использую его на изображении из DSLR, разрешение 3700×5300, это не работает.

Я попытался использовать 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);

Обновить

Просто здесь, чтобы уточнить. Я думаю, что алгоритм работает с большим разрешением изображения, но не работает, когда шахматная доска занимает большую часть изображения.
Например, когда я использую фиксированный объектив 50 мм в той же позиции камеры, FindChessboardCorners никогда не выходит из строя. После того, как я заменил его на объектив с фиксированным фокусным расстоянием 100 мм, функция перестает обнаруживать шаблон. Я думаю, что это относится к пропорции или фокусному расстоянию.

Изображение ниже — результат объектива 100 мм.

Обновление 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);

Загрузил изображение:

Изображение в формате jpg с исходным разрешением 3744 x 5616, если этот сайт принудительно преобразуется, убедитесь, что вы используете правильное разрешение.

Изображение в формате jpg с исходным разрешением 3744 x 5616, если этот сайт принудительно преобразуется, убедитесь, что вы используете правильное разрешение.

13

Решение

Несколько баллов.

  1. Как вы заметили, уменьшение размера помогает детектору. Это связано с тем, что фильтры обнаружения углов, используемые в OpenCV для определения углов, имеют фиксированный размер, и этот размер маски свертки может быть слишком мал, чтобы обнаружить ваши углы — в этом масштабе полноразмерное изображение может фактически выглядеть «гладким», особенно где это немного размыто. Однако, уменьшая масштаб, вы отбрасываете некоторую точность определения угла.
  2. По той же причине, заточка тоже помогает. Однако, это также идет вразрез с точностью, потому что это добавляет смещение к подпиксельным позициям углов — даже в идеальном случае без шума. Чтобы убедиться, что это так, рассмотрите аналог 1D: интенсивность изображения за углом (в 1D, резкий черно-белый переход) в идеале выглядит как сигмовидная кривая (скат с гладкими углами), и вы хотите найти местоположение его точки перегиба. Резкость делает кривую круче, что в целом будет перемещать местоположение этой точки. Ситуация ухудшается, если принять во внимание, что повышение резкости обычно усиливает шум.
  3. Вероятный правильный путь — начать с более низкого разрешения (то есть с уменьшением размера), затем масштабировать позиции найденных углов и использовать их в качестве начальных оценок для запуска cvFindCornersSubpix при полном разрешении.
23

Другие решения

Если у вас есть доступ к исходному коду OpenCV и вы можете перестроить его, то, возможно, вы можете отладить поведение cvFindChessboardCorners,

Ты должен #define DEBUG_CHESSBOARD и тогда у вас будет помощь в понимании алгоритма.

Я думаю, что OpenCV 2.4 имеет эту возможность (см., Например, https://github.com/Itseez/opencv/blob/2.4/modules/calib3d/src/calibinit.cpp).

Кроме того, даже если это не относится к вашему случаю, документ OpenCV дает требование для цели калибровки:

Заметка: Функция требует пробела (например, квадратная граница, чем шире, тем лучше) вокруг доски, чтобы сделать обнаружение
более устойчивы в различных условиях. В противном случае, если нет границы
и фон темный, внешние черные квадраты не могут быть
правильно сегментирован и поэтому квадратный алгоритм группировки и упорядочения
выходит из строя.

http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#findchessboardcorners

1