2013-07-02 10 views
2

템플릿 이미지 (로고)가 PDF 문서에 있는지 여부를 감지하려고합니다. 이 문서는 pdf 또는 "순수한"pdf 문서로 캡슐화 된 스캔 일 수 있지만 완전히 무작위입니다.Orb와의 템플릿 일치 : batchDistance 메소드의 오류

먼저 ImageMagick의 변환 도구를 사용하여 PDF 문서를 png 이미지로 변환 한 다음 이미지가 너무 커서 출력 이미지를 절반으로 자르고 그 이후로 데이터베이스의 로고를 하프 컷 이미지에있는 모양.

이렇게하려면 Orb Descriptor가있는 Orb Feature Detector와 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 Error: Assertion failed (type == src2.type() && src1.cols == src2.cols && (type == CV_32F || type == CV_8U)) in batchDistance, file /home/das/Downloads/opencv-2.4.5/modules/core/src/stat.cpp, line 1797 terminate called after throwing an instance of 'cv::Exception' what(): /home/das/Downloads/opencv-2.4.5/modules/core/src/stat.cpp:1797: error: (-215) type == src2.type() && src1.cols == src2.cols && (type == CV_32F || type == CV_8U) in function batchDistance

Aborted (core dumped)

내가이 오류를 검사하며 그 src1.cols = src2.cols하고 등장! 빠른 픽스는 이미지를 일치시키기 전에 조건을 테스트하는 것입니다. 문제는 내가 그렇게 많은 이미지를 그리워한다는 것이고, 비디오 스트림에서 작업 할 때만 괜찮을 것입니다.하지만 저는 아닙니다. 다음 이미지는 이전 이미지와 공통점이 없습니다. 내 로고가 문서에 있는지 없는지 확인할 수 없습니다. 여기

라인, 1826-1789 stat.cpp의 코드입니다 : 그래서 궁금하네요이 주장은 무엇을 의미 하는가

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); 

(주장 라인 1797 시작 부분에)? stat.cpp의 src1과 src2 파일은 정확히 무엇입니까? 왜 그들은 같은 수의 열을 가져야합니까?

서핑 감지기 및 추출기로 변경하려고했지만 오류가 계속 발생합니다.

누구나 아이디어가 있다면 주저하지 말고 조언이나 통지를 환영합니다!

미리 감사드립니다. 지금보다 정확한 질문이

편집 : 어떻게 src1.cols == src2.cols 보장합니까? 이 질문에 답하기 위해, batch1Distance (...)가 호출되기 전에 image1과 image2에 대한 조건을 찾기 위해 내 cv :: Mat 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

혹시 더 작은 이미지를 크기가 다른 빈 이미지에 붙여 넣으려고 했습니까? 그것은 빠르고 더러운 해결책 일 수 있습니다 ... – morynicz

+0

그게 효과가! 나는 더 이상 오류가 없습니다. 하지만 탐지 안정성이 떨어졌습니다. 이것은 알고리즘이 작동하기 위해 소스 이미지 크기 사이에 상관 관계가 있어야 함을 의미합니다. 문제는 그 상관 관계가 무엇일까요? –

+0

글쎄, 어디 보자 ... 이미지가 커질수록 더 많은 픽셀을 감지 할 수 있습니다. 기능의 품질이 좋습니다. 등 ... – morynicz

답변

3
  1. 이 오류를 제거하는 당신은 복사 놀 수 있으며, 필요한 크기의 빈 하나에 이미지를 붙여, 그러나 이것은에 대해서만 신속하고 더러운 솔루션입니다 : 그래서 내 코드는 다음과 같을 것이다 역설.
  2. 탐지기와 설명자가 제대로 작동하게하려면 어떻게 작동하는지 알아야 할 것입니다. 어쩌면 너는 작동 할 심상을 얻을 수있을 것이다. this article을 읽은 후 ORB는 스케일링에 문제가있는 것으로 보입니다 (결론 섹션에서 언급 함). 즉, 이미지 피라미드 또는 이미지를 여러 눈금으로 확인하는 등의 해결 방법을 찾아야하며 눈금 및 회전 불변 인 다른 추출기 및 설명자를 사용해야합니다.
+0

해결책 n ° 1이 허용되지 않습니다. 주위에 여백이 많은 작은 이미지가 일치하는 것으로 감지되는 경우가 있습니다. 해결책 2 번이 어렵습니다. 스캔 한 문서에 내 데이터베이스와 같은 크기의 로고. 이에 대한 해결책은 데이터베이스가 동일한 로고의 다양한 크기로 업데이트되도록하는 것입니다. –

+0

나는 올바른 생각을하고 있다고 생각합니다. 이미지 피라미드를보고 싶을 수도 있습니다. 나는 특성 추출기 및 설명자 전문가는 아니지만 일부 읽기 후에는 크기가 고정되어있는 것처럼 보입니다. 분석 된 이미지의 해상도를 두 번 변경하고 각 스케일에서 기능을 검색하면됩니다 (SIFT는 이해합니다. 바르게). – morynicz

+0

대용량 데이터베이스를 명확히 사용하는 것이 좋습니다. 탐지 정확도가 예상 한 것보다 큽니다! 그러나 일부 이미지에서 여전히 오류가 발생하고 있으며이를 방지하는 방법을 알 수 없습니다. –