OpenCV 中心单应

OpenCV Center Homography

我正在尝试创建拼接算法。我已经成功地创建了它,需要进行一些调整。下面的照片是到目前为止我的拼接程序的示例。我能够为它提供一个无序列表的图像(只要图像在飞行路径上或并排放置,无论它们彼此的方向如何,它都会起作用。

问题是如果图片颠倒了,有些图片就不会出现在最终产品中。这是实际拼接的代码。假设正确完成了查找关键点、匹配和单应性。

通过更改此代码,是否可以将第一张图片居中放置在目标空白图片上,并仍然与其拼接。此外,我在堆栈溢出 (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;`

通常很容易将图像居中;您只需创建一个更大的矩阵,用零(或您想要的任何颜色)填充,然后在中心定义一个与图像大小相同的 ROI,然后将其放置在那里。但是,您通常不能对两个图像执行此操作。问题是,如果图像被移动或旋转,使其部分超出目标图像边界,那么从 warpPerspective 返回的变形图像会在这些边界处被截断。您需要做的是创建填充图像,将未扭曲的图像插入您喜欢的任何位置,并通过向这些像素添加平移来修改变换(在本例中为单应性)。

例如,如果居中图像的左上角点位于填充图像的 (400,500) 处,则您需要将 (400, 500) 的翻译添加到单应性中,以便像素得到映射到正确的 space,只要你填充的图像足够大,它的 none 就会被截掉。

您需要创建平移单应性并将其与原始单应性组合以添加翻译。例如,假设填充图像内非扭曲图像的锚点位于 (x,y) .最后两列给出了单应性的翻译;如果你的单应性是 3x3 矩阵 H 那么(使用正常的数学索引) H(1,3) 是你在 x 中的翻译而 H(2,3) 是 [=20 中的翻译=] 由你的单应性给出。所以我们需要创建一个新的身份单应性 H_t 并将这些翻译添加到:

      1 0 x
H_t = 0 1 y
      0 0 1

然后你可以用你原来的单应性 H(使用矩阵乘法):H_n = H_t * H 来组合它。使用新的单应性 H_n 我们可以像往常一样使用 warpPerspective 将图像变形到这个填充的 space 并添加平移以将其移动到正确的位置。

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