Сопоставление шаблона с Orb: ошибка с методом batchDistance

Я пытаюсь определить, присутствует ли изображение шаблона (логотип) в документе PDF. Документ может быть отсканированным документом в формате PDF или «чистым» документом PDF, но это совершенно случайно.

Сначала я преобразую документ pdf в изображение png с помощью инструмента преобразования ImageMagick, затем разрезаю выходные изображения пополам, потому что они такие большие, и после этого я пытаюсь сопоставить логотип из базы данных с любой из фигур, представленных в разрезанное изображение.

Для этого я использую Orb Feature Detector с дескриптором Orb и RobustMatcher (вроде улучшенного средства сравнения BruteForce, исходный код доступен) Вот). Вот фрагмент кода из моей адаптации к нему:

// Read input images
Mat image1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
Mat image2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);

if (!image1.data || !image2.data) {
std::cout << " --(!) Error reading images " << std::endl;
exit(1);
}

// Setting up values for ORB Detector
int nfeatures = 800;
//float scaleFactor = 1.10;
int nlevels = 8;
int edgeThreshold = 12;
int firstLevel = 0;
int WTA_K = 2;
int scoreType = 0;
int patchSize = 31;

// Prepare the matcher
RobustMatcher rmatcher;
rmatcher.setConfidenceLevel(0.98);
rmatcher.setMinDistanceToEpipolar(1.0);
rmatcher.setRatio(0.80f);
cv::Ptr<cv::FeatureDetector> pfd = new cv::OrbFeatureDetector(nfeatures, scaleFactor, nlevels, edgeThreshold, firstLevel, WTA_K, scoreType, patchSize);
rmatcher.setFeatureDetector(pfd);
cv::Ptr<cv::DescriptorExtractor> pde = new cv::OrbDescriptorExtractor();
rmatcher.setDescriptorExtractor(pde);

// Match the two images
std::vector<cv::DMatch> matches;
std::vector<cv::KeyPoint> keypoints1, keypoints2;
cv::Mat fundemental = rmatcher.match(image1, image2, matches, keypoints1, keypoints2);

// If nothing could be matched, stop here
if(matches.size() < 4){
exit(2);
}

Код прекрасно работает на некоторых примерах, которые я выбрал тщательно, с хорошо узнаваемым логотипом и чистым изображением, с определенными пропорциями … и т. Д. Но когда я пытаюсь применить этот процесс к случайным файлам PDF, я начинаю получать эту ошибку из OpenCV:

Ошибка OpenCV: утверждение не выполнено (type == src2.type () && src1.cols == src2.cols && (введите == CV_32F || type == CV_8U)) в batchDistance, файл /home/das/Downloads/opencv-2.4.5/modules/core/src/stat.cpp, строка 1797
прекращение вызова после создания экземпляра cv :: Exception
what (): /home/das/Downloads/opencv-2.4.5/modules/core/src/stat.cpp:1797: ошибка: (-215) type == src2.type () && src1.cols == src2.cols && (введите == CV_32F || type == CV_8U) в функции batchDistance

Прервано (ядро сброшено)

Я проверил эту ошибку, и оказалось, что src1.cols! = Src2.cols, и быстрое решение этой проблемы — проверить условие, прежде чем пытаться сопоставить изображения. Проблема в том, что я скучаю по многим изображениям, и это будет нормально, только если я работаю с видеопотоком … но я не работаю, и следующее изображение не имеет ничего общего с предыдущим, и Я не могу определить, присутствовал ли мой логотип в документе.

Вот код из stat.cpp, строки 1789-1826: (утверждение в начале строки 1797)

void cv::batchDistance( InputArray _src1, InputArray _src2,
OutputArray _dist, int dtype, OutputArray _nidx,
int normType, int K, InputArray _mask,
int update, bool crosscheck )
{
Mat src1 = _src1.getMat(), src2 = _src2.getMat(), mask = _mask.getMat();
int type = src1.type();
CV_Assert( type == src2.type() && src1.cols == src2.cols &&
(type == CV_32F || type == CV_8U));
CV_Assert( _nidx.needed() == (K > 0) );

if( dtype == -1 )
{
dtype = normType == NORM_HAMMING || normType == NORM_HAMMING2 ? CV_32S : CV_32F;
}
CV_Assert( (type == CV_8U && dtype == CV_32S) || dtype == CV_32F);

K = std::min(K, src2.rows);

_dist.create(src1.rows, (K > 0 ? K : src2.rows), dtype);
Mat dist = _dist.getMat(), nidx;
if( _nidx.needed() )
{
_nidx.create(dist.size(), CV_32S);
nidx = _nidx.getMat();
}

if( update == 0 && K > 0 )
{
dist = Scalar::all(dtype == CV_32S ? (double)INT_MAX : (double)FLT_MAX);
nidx = Scalar::all(-1);
}

if( crosscheck )
{
CV_Assert( K == 1 && update == 0 && mask.empty() );
Mat tdist, tidx;
batchDistance(src2, src1, tdist, dtype, tidx, normType, K, mask, 0, false);

Поэтому мне интересно, что означает это утверждение? Что такое файлы src1 и src2 в stat.cpp? Почему они должны иметь одинаковое количество столбцов?

Я попытался перейти на Surf-детектор и экстрактор, но все равно получаю ошибку.

Если у кого-то есть идея, не стесняйтесь писать, я приветствую любые советы или уведомления!

Заранее спасибо.

У меня есть более точный вопрос: как мне обеспечить src1.cols == src2.cols ? Чтобы ответить на этот вопрос, я думаю, я должен знать, какие преобразования применяются к моим cv :: Mat image1 и image2 перед вызовом batchDistance (…), чтобы найти условие для image1 и image2, которое будет гарантировать, что src1.cols == src2.cols, так что мой код будет выглядеть так:

// Match the two images
std::vector<cv::DMatch> matches;
std::vector<cv::KeyPoint> keypoints1, keypoints2;
if( CONDITION_ON_IMAGE1&IMAGE2_TO_ENSURE_SRC1.COLS==SRC2.COLS ){
cv::Mat fundemental = rmatcher.match(image1, image2, matches, keypoints1, keypoints2);
}

3

Решение

  1. Чтобы избавиться от ошибок, Вы можете поиграть с копированием и вставкой изображений в пустое изображение требуемого размера, но это только быстрое и грязное решение для утверждения.
  2. Для правильной работы детектора и дескриптора вам, возможно, придется узнать, как он работает. Может быть, тогда вы сможете получить изображения, которые будут работать. После прочтения Эта статья, похоже, что у ORB будут проблемы с масштабированием (они упоминают об этом в разделе «Заключение»). Это означает, что вам нужно будет найти обходной путь для этого (например, пирамиды изображений или другой способ проверки изображения в нескольких масштабах) или использовать другой экстрактор и дескриптор, который не зависит от масштаба и поворота.
3

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

Других решений пока нет …

По вопросам рекламы [email protected]