2017-06-13 84 views
0

我想创建一个拼接算法。我已经成功地通过一些必要的调整来创建它。下面的照片是我的拼接程序的例子。我可以向它提供的图像(的无序列表,只要图像是在飞行路径或并排而不管它们的取向也将努力彼此。 img1 then img2 enter image description hereOpenCV Center同形异形

的问题是,如果图像假设找到关键点,匹配和单应性都是正确的。

通过改变这段代码有没有办法将第一张图像居中放置到目标空白图像上,然后仍然缝到它上面,并且我在堆栈溢出(Opencv Image Stitching or Panorama)上得到了这个代码,我不完全确定它是如何工作的,并且如果有人可以解释它。

感谢您提前提供任何帮助!

Mat stitchMatches(Mat image1,Mat image2, Mat homography){ 
    Mat result; 
    vector<Point2f> fourPoint; 
    //-Get the four corners of the first image (master) 
    fourPoint.push_back(Point2f (0,0)); 
    fourPoint.push_back(Point2f (image1.size().width,0)); 
    fourPoint.push_back(Point2f (0, image1.size().height)); 
    fourPoint.push_back(Point2f (image1.size().width, image1.size().height)); 
    Mat destination; 
    perspectiveTransform(Mat(fourPoint), destination, homography); 

    double min_x, min_y, tam_x, tam_y; 
    float min_x1, min_x2, min_y1, min_y2, max_x1, max_x2, max_y1, max_y2; 
    min_x1 = min(fourPoint.at(0).x, fourPoint.at(1).x); 
    min_x2 = min(fourPoint.at(2).x, fourPoint.at(3).x); 
    min_y1 = min(fourPoint.at(0).y, fourPoint.at(1).y); 
    min_y2 = min(fourPoint.at(2).y, fourPoint.at(3).y); 
    max_x1 = max(fourPoint.at(0).x, fourPoint.at(1).x); 
    max_x2 = max(fourPoint.at(2).x, fourPoint.at(3).x); 
    max_y1 = max(fourPoint.at(0).y, fourPoint.at(1).y); 
    max_y2 = max(fourPoint.at(2).y, fourPoint.at(3).y); 
    min_x = min(min_x1, min_x2); 
    min_y = min(min_y1, min_y2); 
    tam_x = max(max_x1, max_x2); 
    tam_y = max(max_y1, max_y2); 

    Mat Htr = Mat::eye(3,3,CV_64F); 
    if (min_x < 0){ 
     tam_x = image2.size().width - min_x; 
     Htr.at<double>(0,2)= -min_x; 
    } 
    if (min_y < 0){ 
     tam_y = image2.size().height - min_y; 
     Htr.at<double>(1,2)= -min_y; 
    } 


    result = Mat(Size(tam_x*2,tam_y*2), CV_32F); 
    warpPerspective(image2, result,  Htr, result.size(), INTER_LINEAR, BORDER_CONSTANT, 0); 
    warpPerspective(image1, result, (Htr*homography), result.size(), INTER_LINEAR, BORDER_TRANSPARENT,0); 
    return result;` 
+0

Off topic:看起来你一直在玩乐。前一段时间看了一下,以便在转向不同的工作之前用无人机检测石油管道泄漏。不知道有没有人建造过它。 – user4581301

+0

“颠倒”是什么意思? – KjMag

+0

可能重复[拼接图像使用模板匹配和warpAffine](https://stackoverflow.com/questions/44457064/stitching-images-using-template-matching-and-warpaffine) –

回答

1

通常很容易居中图像;您只需创建一个填充了零(或任何想要的颜色)的较大矩阵,然后在中心定义一个具有相同图像大小的ROI,然后将其放置在那里。但是,一般情况下,您无法在两张图片上进行此操作。问题是,如果图像被移动或旋转,以致其部分位于目标图像边界之外,那么从warpPerspective返回的扭曲图像在这些边界处被切断。你需要做的是创建填充图像,插入没有被翘曲的图像,只要你喜欢,并修改转换(在这种情况下单应性),通过在翻译中添加这些像素。

例如,如果您的居中图像的填充图像中的左上角点为(400,500),则需要将(400, 500)的翻译添加到您的单应性中,以便将像素映射到正确的空间,并且只要你填充的图像足够大,它们都不会被切断。

您需要创建一个平移单应矩阵,并将其与您的原始单应矩阵进行组合以添加翻译。例如,假设您填充图像中未扭曲图像的锚点位于(x,y)。单元翻译由最后两列给出;如果你的单应性是3x3矩阵H然后(使用正常的数学索引)H(1,3)是你的翻译xH(2,3)是在你的单应式给出的y的翻译。因此,我们需要创建一个新的身份单应H_t和添加这些翻译:H_n = H_t * H

 1 0 x 
H_t = 0 1 y 
     0 0 1 

然后你就可以用你原来的单应H(使用矩阵乘法)撰写此。使用新的单应性H_n,我们可以像往常一样使用warpPerspective将图像变形到该填充空间中,并将其添加到正确的点上。

您也可以自动执行此操作,以便根据需要精确地填充图像,以便不会出现多余的填充并且填充只会根据需要拉伸。请参阅我的回答here,详细了解如何计算并将图像变形为填充空间。

+0

感谢这些令人敬畏的建议和资源检查。数学方面对我来说有点多,但到了那里。感谢帮助。 –

+0

@ C.Radford没有问题,它不是*太多*很多数学,只是一些线性代数。即使如此,你需要知道的是单应性采用当前的像素,并通过矩阵乘法将它们映射到新的位置。 'warpPerspective'这样做,然后像素值(颜色)被放置在新的位置。我基本上建议的是将目标图像放置在一个大零矩阵的中心,并告诉单应性您在顶部和左侧使用了多少填充,所以它知道在单应性中使用该翻译(在另一个翘曲它)。 –