【问题标题】:Warp perspective and stitch/overlap images (C++)扭曲透视和缝合/重叠图像 (C++)
【发布时间】:2015-11-22 20:28:13
【问题描述】:

我正在检测和匹配一对图像的特征,使用典型的检测器-描述符-匹配器组合,然后使用findHomography 生成转换矩阵。

在此之后,我希望两个图像重叠(第二个(imgTrain)在第一个(imgQuery)上,所以我使用变换矩阵扭曲第二个图像:

cv::Mat imgQuery, imgTrain;
...    
TRANSFORMATION_MATRIX = cv::findHomography(...)
...
cv::Mat imgTrainWarped;
cv::warpPerspective(imgTrain, imgTrainWarped, TRANSFORMATION_MATRIX, imgTrain.size());

从这里开始,我不知道如何生成包含原始imgQuery 和扭曲的imgTrainWarped 的图像。 我考虑两种情况: 1)最终图像的大小为imgQuery的大小 2) 最终图像的大小足以容纳imgQueryimgTrainWarped,因为它们只是部分重叠,而不是完全重叠。我知道第二种情况可能在图像周围的某处有黑色/空白区域。

【问题讨论】:

    标签: c++ opencv feature-detection


    【解决方案1】:

    您应该变形到与imgQuery 具有相同尺寸的目标矩阵,然后循环整个变形图像并将像素复制到第一个图像,但前提是变形图像实际上包含变形像素。这最容易通过扭曲额外的蒙版来完成。请试试这个:

    cv::Mat imgMask = cv::Mat(imgTrain.size(), CV_8UC1, cv::Scalar(255));
    cv::Mat imgMaskWarped;
    cv::warpPerspective(imgMask , imgMaskWarped, TRANSFORMATION_MATRIX, imgQuery.size());
    
    cv::Mat imgTrainWarped;
    cv::warpPerspective(imgTrain, imgTrainWarped, TRANSFORMATION_MATRIX, imgQuery.size());
    
    // now copy only masked pixel:
    imgTrainWarped.copyTo(imgQuery, imgMaskWarped);
    

    请尝试判断这是否可行并解决scenario 1。对于场景 2,您将测试图像在变形之前必须有多大(通过使用转换)并将两个图像复制到足够大的目标图像。

    【讨论】:

    • 嗯...我有点困惑。我是你写的代码,但我得到了这个:j.mp/warp001。 (可以在此处看到两个带有匹配项的图像:j.mp/warp002)。你怎么看?
    • 你能不能cv::imwriteimgTrainWarpedimgQuery在变形后分享给我?
    • 包装后:imgQuery 为j.mp/imgQuery,imgMaskWarped 为j.mp/imgMaskWarped,imgTrainWarped 为j.mp/imgTrainWarped
    • 翘曲没有按预期工作,也许必须“反其道而行之”进行翘曲...您也可以添加原始图像吗?
    • 我是这么想的,但是我对中间的Mask步骤并不完全熟悉,我无法获得正确的东西。这是原始的 imgQuery:j.mp/imgQuery_original 这是第二张图片:j.mp/imgTrain 非常感谢您的宝贵时间!
    【解决方案2】:

    对于 OpenCV 4 INTER_LINEAR 和 BORDER_TRANSPARENT 可以通过使用解决 cv::InterpolationFlags::INTER_LINEAR, cv::BorderTypes::BORDER_TRANSPARENT,例如

    cv::warpPerspective(imgTrain, imgQuery, TRANSFORMATION_MATRIX, imgQuery.size(), cv::InterpolationFlags::INTER_LINEAR, cv::BorderTypes::BORDER_TRANSPARENT);
    

    【讨论】:

    • 您能否解释一下您发布的代码与两年多前发布的answer by coyer 中的代码有何显着不同?
    【解决方案3】:

    接受的答案有效,但使用BORDER_TRANSPARENT 可以更轻松地完成:

    cv::warpPerspective(imgTrain, imgQuery, TRANSFORMATION_MATRIX, imgQuery.size(), INTER_LINEAR, BORDER_TRANSPARENT);
    

    使用BORDER_TRANSPARENT 时,imgQuery 的源像素保持不变。

    【讨论】:

      【解决方案4】:

      您是否尝试使用从同一视点在不同方向拍摄的两张重叠照片创建全景图像?如果是这样,我担心“第二个超过第一个”部分。将全景图拼接在一起的正确方法是将两个图像沿重叠部分的中心线(对称轴)切掉,而不是将一张图像的一部分添加到(整个)另一张图像中。

      【讨论】:

      • 我的意思是重叠的意思是其中一个图像保持不变,而另一个被绘制在“上面”。我认为,上一步是否切除第一张图像的部分(重叠)不会影响最终结果,所以两个程序都应该这样做。我可能误会你了……
      • 首先,图片是如何拍摄的?如果相机是平行移动的,比如在水平飞行中不同时间点拍摄的航拍照片,那就不用管我的cmets了。但是如果相机被放置在一个固定点并且只是在第一次和第二次拍摄之间稍微旋转了一下,那么重叠将不是完美匹配除了在重叠部分的对称轴上。跨度>
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-31
      • 1970-01-01
      • 2014-08-13
      相关资源
      最近更新 更多