【问题标题】:OpenCV Center HomographyOpenCV 中心单应性
【发布时间】:2017-06-13 21:33:53
【问题描述】:

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

问题是如果图像被颠倒,一些图像不会进入最终产品。这是实际拼接的代码。假设找到关键点、匹配和单应性是正确的。

通过更改此代码,有一种方法可以将第一张图像居中到目标空白图像并仍然缝合到它。另外,我在堆栈溢出时得到了这段代码 (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;`

【问题讨论】:

  • 离题:看起来你玩得很开心。前段时间研究了这一点,以使用无人机检测石油管道泄漏,然后再进行另一项工作。不知道是否有人建造过它。
  • 你所说的“反转”是什么意思?
  • 我将此标记为重复。这根本不是一个坏问题,但我just answered a very similar question the other day。希望对您有所帮助!
  • KjMag - 颠倒是指图像通过管道传输到程序中的顺序。我希望它能够将图像拼接在一起,而不管顺序如何(如果最左边的图像是第一个或最右边的图像是第一个)。

标签: c++ opencv image-stitching


【解决方案1】:

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

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

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

      1 0 x
H_t = 0 1 y
      0 0 1

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

您还可以自动执行此操作,以根据需要精确填充图像,这样您就没有多余的填充,并且填充只会根据需要拉伸。请参阅我的回答 here,详细说明如何计算并将图像扭曲到填充空间中。

【讨论】:

  • 感谢您提供这些很棒的建议和资源来查看。数学方面对我来说有点多,但到达那里。感谢您的帮助。
  • @C.Radford 没问题,这不是太多数学,只是一点线性代数。即便如此,您只需要知道单应性获取当前像素并通过矩阵乘法将它们映射到新位置。 warpPerspective 执行此操作,然后将像素值(颜色)放置在新位置。我基本上建议的是将目标图像放在一个大的零矩阵的中心,并告诉单应性您在顶部和左侧使用了多少填充,因此它知道在单应性中使用该翻译(在顶部它所做的其他翘曲)。
猜你喜欢
  • 2017-02-01
  • 2014-04-06
  • 2020-01-25
  • 2012-11-30
  • 2012-06-13
  • 2018-09-08
  • 1970-01-01
  • 2016-09-30
  • 2012-02-22
相关资源
最近更新 更多