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.]()
Ответы
Ответ 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
есть четное/нечетное количество углов, то есть это 9x6, я не знаю, может ли это быть проблемой.