首页 文章

与Orb匹配的模板:使用batchDistance方法出错

提问于
浏览
3

我正在尝试检测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()&& src1.cols == src2.cols &&(type == CV_32F || type == CV_8U))batchDistance,file / 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 &&(type == CV_32F || type == CV_8U)函数batchDistance Aborted(核心倾倒)

我检查了这个错误,似乎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文件到底是什么?为什么他们需要具有相同数量的列?

我尝试更换为冲浪探测器和提取器,但我仍然得到错误 .

如果有人有想法,请不要犹豫,我欢迎任何建议或通知!

提前致谢 .

编辑

我现在有一个更精确的问题:我如何确保 src1.cols == src2.cols ?要回答这个问题,我想我应该知道在调用batchDistance(...)之前应用于我的cv :: Mat image1和image2的转换是什么,以便在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);
    }

1 回答

  • 3
    • 为了摆脱错误,您可以将图像复制并粘贴到所需大小的空白图像中,但这只是断言的快速而肮脏的解决方案 .

    • 为了使探测器和描述符正常工作,您可能必须了解其工作原理 . 也许那时你将能够获得可行的图像 . 在阅读this article后,看起来ORB会出现缩放问题(他们在结论部分提到了它) . 这意味着您需要找到它的解决方法(如图像金字塔,或以多种比例检查图像的其他方法)或使用另一个提取器和描述符,即缩放和旋转不变 .

相关问题