扭曲透视和 stitch/overlap 图像 (C++)
Warp perspective and stitch/overlap images (C++)
我正在检测和匹配一对图像的特征,使用典型的检测器-描述符-匹配器组合,然后 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) 最终图像的大小足以容纳 imgQuery
和 imgTrainWarped
,因为它们只是部分重叠,而不是完全重叠。我知道第二种情况可能在图片周围有 black/blank space。
之后您应该变形到与 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,您将测试在变形之前图像必须有多大(通过使用转换)并将两个图像复制到足够大的目标图像。
您是否正在尝试使用从不同方向从同一视点拍摄的两张重叠照片来创建全景图像?如果是这样,我担心 "the second one over the first one" 部分。将全景图拼接在一起的正确方法是将两幅图像沿着重叠部分的中心线(对称轴)切掉,而不是将一幅图像的一部分添加到另一幅(整个)图像中。
已接受的答案有效,但使用 BORDER_TRANSPARENT
:
可以更轻松地完成
cv::warpPerspective(imgTrain, imgQuery, TRANSFORMATION_MATRIX, imgQuery.size(), INTER_LINEAR, BORDER_TRANSPARENT);
使用 BORDER_TRANSPARENT
时,imgQuery
的源像素保持不变。
对于 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);
我正在检测和匹配一对图像的特征,使用典型的检测器-描述符-匹配器组合,然后 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) 最终图像的大小足以容纳 imgQuery
和 imgTrainWarped
,因为它们只是部分重叠,而不是完全重叠。我知道第二种情况可能在图片周围有 black/blank space。
之后您应该变形到与 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,您将测试在变形之前图像必须有多大(通过使用转换)并将两个图像复制到足够大的目标图像。
您是否正在尝试使用从不同方向从同一视点拍摄的两张重叠照片来创建全景图像?如果是这样,我担心 "the second one over the first one" 部分。将全景图拼接在一起的正确方法是将两幅图像沿着重叠部分的中心线(对称轴)切掉,而不是将一幅图像的一部分添加到另一幅(整个)图像中。
已接受的答案有效,但使用 BORDER_TRANSPARENT
:
cv::warpPerspective(imgTrain, imgQuery, TRANSFORMATION_MATRIX, imgQuery.size(), INTER_LINEAR, BORDER_TRANSPARENT);
使用 BORDER_TRANSPARENT
时,imgQuery
的源像素保持不变。
对于 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);