图像拼接(十二):OpenCVSeamFinder+GraphCut+最佳拼接缝寻

阅读: 评论:0

图像拼接(⼗⼆):OpenCVSeamFinder+GraphCut+最佳拼接缝寻很多情况下,使⽤⼀个全局单应变换并不能准确对齐图像,需要⼀些后处理来削弱拼接的痕迹,⽐如寻最佳拼接缝。
使⽤全局单应变换的对齐结果,实现代码参考:
仔细观察,在拼缝的下⽅出现了没对齐的问题。
寻最佳拼接缝算法中,Graph Cut很经典。它将计算机视觉问题和⽹络流联系在⼀起。寻最佳拼接缝等价于求⽹络流的最⼩割。在⽹络流问题中,最⼩割和最⼤流相等。这些概念可能会使你困惑,了解⼀些概念,可参考百度⽂库⾥图⽂并茂的PPT-
不了解这些这些概念也没关系,因为在这⾥我也没打算⾃⼰造轮⼦实现。
OpenCV stitching模块⾥有相关的函数,实现⾥基于最⼩图割的最佳拼接缝寻算法。官⽅⽂档见这⾥:
void cv::detail::GraphCutSeamFinder::find ( const std::vector< UMat > &  src,
const std::vector< Point > &  corners,
std::vector< UMat > &  masks
)
具体怎么操作呢?
先输⼊两幅⽤全局单应变换配准后的图像,要统⼀坐标系。在这⾥图像宽为原始图像的两倍。
left
right
傅科摆图片
find函数第⼀个参数是输⼊源图像集合;第⼆个参数corners的是图像左上⾓坐标的集合;第三个参数会返回更新的拼接缝掩码。
按这种思路,两幅图像左上⾓都是(0,0),输⼊图像完全是重合的。但测试发现,这样使⽤函数并不能返回预期的结果。个⼈猜测,可能是因为完全重合,算法不到分割的起点和终点,或者是因为图像中有⼤⾯积的⿊⾊。
最佳的使⽤情形是输⼊图像间有部分重合区域。
既然这样,先剪切,需要注意不要忘记图像的配准信息。
从中间剪,其实是原图。
从1/4和3/4位置剪,(隐含了图像间有⼀半重复的假设)
这样,左图的corner是(0,0),右图的corner是(0.5*width,0)。使⽤find函数返回得到表现拼接缝位置的掩码:
左图掩码:
右图掩码:
咦?为啥拼接缝这么竖直?不清楚内部原理的我,内⼼也有些许忐忑,担⼼效果。最后的效果说明结果是合理的,根据掩码拼合图像:
以上对函数的说明,属于个⼈理解,如有错误,多谢指正帮助。
代码:
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/stitching/detail/seam_finders.hpp>
#include<iostream>
现浇箱梁施工using namespace cv;
using namespace cv::detail;
int main()
{
//统⼀坐标下的两幅图
// 此例中canvas.width=2*src.width
Mat canvas1 = imread("left.jpg");
Mat canvas2 = imread("right.jpg");
//将两幅图剪切出来,剪切位置包含了配准(两幅图像的相对位置)信息
首饰加工技术
Mat image1 = canvas1(Range::all(), Range(0, ls/2));
Mat image2 = canvas2(Range::all(), ls/4, ls*3/4));//假设⼤概1/2重复区域
image1 /= 255.0;
image2 /= 255.0;
//在拼缝的操作中,为了减少计算量,⽤image_small
Mat image1_small;
Mat image2_small;
Size small_size1 = ls / 2, ws / 2);
Size small_size2 = ls / 2, ws / 2);
resize(image1, image1_small, small_size1);
resize(image2, image2_small, small_size2);
物流订单管理系统// 左图的左上⾓坐标
cv::Point corner1;外墙保温用锚栓
corner1.x = 0;
corner1.y = 0;
//右图的左上⾓坐标
cv::Point corner2;
corner2.x = ls/2;
corner2.y = 0;
std::vector<cv::Point> corners;
corners.push_back(corner1);
corners.push_back(corner2);
std::vector<cv::Mat> masks;
Mat imageMask1(small_size1, CV_8U);
Mat imageMask2(small_size2, CV_8U);
imageMask1 = Scalar::all(255);
imageMask2 = Scalar::all(255);
masks.push_back(imageMask1);
masks.push_back(imageMask2);
std::vector<cv::Mat> sources;
sources.push_back(image1_small);
sources.push_back(image2_small);
Ptr<SeamFinder> seam_finder = new cv::detail::GraphCutSeamFinder(GraphCutSeamFinderBase::COST_COLOR); seam_finder->find(sources, corners, masks);
//将mask恢复放⼤人造海参
resize(masks[0], imageMask1, image1.size());
resize(masks[1], imageMask2, image2.size());
Mat ls*3/2,CV_32FC3);
/*canvas *= 255;
imshow("canvas",canvas);
imshow("Mask1",masks[0]);

本文发布于:2023-08-22 02:46:55,感谢您对本站的认可!

本文链接:https://patent.en369.cn/patent/2/226945.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:图像   拼接   结果
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 369专利查询检索平台 豫ICP备2021025688号-20 网站地图