2011-05-16 111 views
8

我正在使用以下代码缝合输入图像。对于未知的 原因输出结果是废话! 由于转换后的图像就像是一个“被剥削的明星”,看起来单应矩阵是错误的(或者是错误的) ! 我已经评论了部分,我猜是问题的来源 ,但我无法实现它。 任何帮助或点都appriciated!OpenCV - 图像拼接

有一个愉快的一天, 阿里

void Stitch2Image(IplImage *mImage1, IplImage *mImage2) 
{ 

    // Convert input images to gray 
    IplImage* gray1 = cvCreateImage(cvSize(mImage1->width, mImage1->height), 8, 1); 

    cvCvtColor(mImage1, gray1, CV_BGR2GRAY); 
    IplImage* gray2 = cvCreateImage(cvSize(mImage2->width, mImage2->height), 8, 1); 

    cvCvtColor(mImage2, gray2, CV_BGR2GRAY); 
    // Convert gray images to Mat 
    Mat img1(gray1); 
    Mat img2(gray2); 
    // Detect FAST keypoints and BRIEF features in the first image 
    FastFeatureDetector detector(50); 
    BriefDescriptorExtractor descriptorExtractor; 
    BruteForceMatcher<L1<uchar> > descriptorMatcher; 
    vector<KeyPoint> keypoints1; 
    detector.detect(img1, keypoints1); 
    Mat descriptors1; 
    descriptorExtractor.compute(img1, keypoints1, descriptors1); 

/* Detect FAST keypoints and BRIEF features in the second image*/ 


    vector<KeyPoint> keypoints2; 
    detector.detect(img1, keypoints2); 
    Mat descriptors2; 
    descriptorExtractor.compute(img2, keypoints2, descriptors2); 
    vector<DMatch> matches; 
    descriptorMatcher.match(descriptors1, descriptors2, matches); 
    if (matches.size()==0) 
      return; 
    vector<Point2f> points1, points2; 
    for(size_t q = 0; q < matches.size(); q++) 
    { 
      points1.push_back(keypoints1[matches[q].queryIdx].pt); 
      points2.push_back(keypoints2[matches[q].trainIdx].pt); 
    } 
    // Create the result image 
    result = cvCreateImage(cvSize(mImage2->width * 2, mImage2->height), 8, 3); 
    cvZero(result); 

    // Copy the second image in the result image 

    cvSetImageROI(result, cvRect(mImage2->width, 0, mImage2->width, mImage2->height)); 
    cvCopy(mImage2, result); 
    cvResetImageROI(result); 

    // Create warp image 
    IplImage* warpImage = cvCloneImage(result); 
    cvZero(warpImage); 

    /************************** Is there anything wrong here!? *******************/ 
    // Find homography matrix 
    Mat H = findHomography(Mat(points1), Mat(points2), 8, 3.0); 
    CvMat HH = H; // Is this line converted correctly? 
    // Transform warp image 
    cvWarpPerspective(mImage1, warpImage, &HH); 
    // Blend 
    blend(result, warpImage); 
    /*******************************************************************************/ 

    cvReleaseImage(&gray1); 
    cvReleaseImage(&gray2); 
    cvReleaseImage(&warpImage); 
} 

回答

7

这是我会建议你去尝试,顺序如下:

1)单应使用CV_RANSAC选项。参考http://opencv.willowgarage.com/documentation/cpp/calib3d_camera_calibration_and_3d_reconstruction.html

2)尝试其他描述符,特别是OpenFV附带的SIFT或SURF。对于某些图像,FAST或BRIEF描述符的分辨率不够。编辑(8月'12):ORB描述符,这是基于Brief,相当好,快!

3)尝试查看Homography矩阵(在调试模式下单步执行或打印它)并查看它是否一致。

4)如果上面没有提供线索,请尝试查看形成的匹配。它是否与一幅图像中的一点匹配,而另一幅图像中的点数是多少?如果是这样,那么问题应该与描述符或检测器一起。

我的预感是它是描述符(所以1)或2)应该修复它)。

+0

嗨,tanx答案。 – Edi 2011-05-17 14:13:32

+1

哪些建议适合您? – Muzikant 2012-02-23 20:19:18

1

您的单人表,可能是根据错误匹配计算得出的,因此代表不良联盟。 我建议通过额外检查其行之间的相互依赖性来检查矩阵。

可以使用以下代码:

bool cvExtCheckTransformValid(const Mat& T){ 

    // Check the shape of the matrix 
    if (T.empty()) 
     return false; 
    if (T.rows != 3) 
     return false; 
    if (T.cols != 3) 
     return false; 

    // Check for linear dependency. 
    Mat tmp; 
    T.row(0).copyTo(tmp); 
    tmp /= T.row(1); 
    Scalar mean; 
    Scalar stddev; 
    meanStdDev(tmp,mean,stddev); 
    double X = abs(stddev[0]/mean[0]); 
    printf("std of H:%g\n",X); 
    if (X < 0.8) 
     return false; 

    return true;  
} 
2

此外切换到汉明距离,而不是在BruteForceMatcher L1距离。简要描述符应该使用汉明距离进行比较。