Подтвердить что ты не робот

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

Я могу использовать функции 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);

Обновление

Просто здесь, чтобы уточнить. Я думаю, что алгоритм работает с большим разрешением изображения, но он терпит неудачу, когда шахматная доска занимает большую часть изображения. Например, когда я использую 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, если это принудительное преобразование сайта, убедитесь, что вы используете его с правильным разрешением.

A jpg image at original resolution 3744 x 5616, if this site force convert, then make sure you are using at the correct resolution.

4b9b3361

Ответ 1

Несколько точек.

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

Ответ 2

Если у вас есть доступ к исходному cvFindChessboardCorners 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

Шахматная доска в вопросе имеет четное количество внутренних углов как для строк (6 углов), так и для столбцов (8 углов), в то время как у эталонной шахматной доски OpenCV enter image description here есть четное/нечетное количество углов, то есть это 9x6, я не знаю, может ли это быть проблемой.