Я пытаюсь определить, присутствует ли изображение шаблона (логотип) в документе 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);
}
Других решений пока нет …