我试图检测pdf文档中是否存在模板图像(徽标)。该文档可以是封装在pdf中的扫描,也可以是纯粹的" pdf文件,但这完全是随机的。
首先,我使用ImageMagick的转换工具将pdf文档转换为png图像,然后我将输出图像切成两半,因为它们非常大,之后我尝试匹配一个徽标来自包含半切图像中任何形状的数据库。
为此,我使用带有Orb描述符的Orb特征检测器和RobustMatcher(一种改进的BruteForce匹配器,可用的源代码here)。以下是我改编的代码片段:
// 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错误:断言失败(类型== src2.type()&amp;&amp; src1.cols == src2.cols&amp;&amp;(type == CV_32F || type == CV_8U))batchDistance,file /home/das/Downloads/opencv-2.4.5/modules/core/src/stat.cpp,第1797行 在抛出&#39; cv :: Exception&#39;的实例后终止调用 what():/ home / das / Downloads / opencv-2.4.5 / modules / core / src / stat.cpp:1797:error:( - 1515)type == src2.type()&amp;&amp; src1.cols == src2.cols&amp;&amp; (函数batchDistance
中的(type == CV_32F || type == CV_8U)中止(核心倾销)
我检查了这个错误,看起来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);
所以我想知道这个断言是什么意思? stat.cpp中的src1和src2文件到底是什么?为什么他们需要具有相同数量的列?
我尝试更换为Surf探测器和提取器,但我仍然收到错误。
如果有人有想法,请不要犹豫,我欢迎任何建议或通知!
提前致谢。
我现在有一个更准确的问题:我如何确保src1.cols == src2.cols
?为了回答这个问题,我想我应该知道在调用batchDistance(...)之前应用于我的cv :: Mat image1和image2的转换是什么,以便在image1和image2上找到一个条件来确保{{ 1}},所以我的代码看起来像这样:
src1.cols == src2.cols
答案 0 :(得分:3)