Opencv图像拼接

描述

两张图片,如何拼成一张图片

代码

主要有两种方法

我这里举个例子,假设我有一张图片,这张图片左边部分是a,右面部分是b

我想要的新图片,想要左边是原图像的b,右边是原图像的a,而a和b的尺寸和信息都不变,我的代码应该怎么写

我先贴一段模板吧,下面会有实际的例子讲解

cv::Mat inputImage;
cv::Mat outputImage;
// 选定第一帧图要放的位置:0, 0, width, height
CvRect rect = cvRect(0, 0, inputImage.cols, inputImage.rows);
// 从要输出的大图中,获取第一张图要放的位置区域的引用
cv::Mat dstMat = outputImage(rect);
// 将原始图拷贝至目标区域
inputImage.colRange(0, inputImage.cols).copyTo(dstMat);

1. 操作图片

cv::Mat frame; // 原图像,你需要自己加载
int width = frame.size().width;
int height = frame.size().height;

int problem_col = 511; // 左图的最右像素值

cv::Mat frame_needBe_left = frame(cv::Rect(problem_col+1, 0, width - problem_col-1, height-1)); // 需要放在左面的图
cv::Mat frame_needBe_right = frame(cv::Rect(0, 0, problem_col, height-1)); // 需要放在右面的图

cv::Mat frame_fix(height, width, CV_8UC3, cv::Scalar(255, 255, 255)); // 定义一张空白图

cv::Rect rect_left = cv::Rect(0, 0, width - problem_col-1, height-1); // 新图像左边尺寸
cv::Rect rect_right = cv::Rect(width - problem_col, 0, problem_col, height-1); // 新图像右边尺寸

cv::Mat dstMat_left = frame_fix(rect_left); // 从要输出的大图中,获取左图要放的位置区域的引用
frame_needBe_left.colRange(0, width - problem_col-1).copyTo(dstMat_left); // 将原始图拷贝至目标区域

cv::Mat dstMat_right = frame_fix(rect_right); // 从要输出的大图中,获取右图要放的位置区域的引用
frame_needBe_right.colRange(0, problem_col).copyTo(dstMat_right); // 将原始图拷贝至目标区域

这种操作的问题:拼接出来的图片,中间是有个分界线的,颜色和你定义的frame_fix是一样的,看起来像某一列的图像值没有被覆盖,但实际上代码的参数是正确的。我没有进一步研究,采用了下面的操作像素来拼接

2. 操作像素

由于上面的问题,我直接对目标图像的像素进行了操作。最终结果是正确的,只不过专业的来说,这样遍历像素的办法是费时的

cv::Mat frame; // 原图像,你需要自己加载
int width = frame.size().width;
int height = frame.size().height;

int problem_col = 511; // 左图的最优一个像素值

cv::Mat frame_needBe_left = frame(cv::Rect(problem_col+1, 0, width - problem_col-1, height-1)); // 需要放在左面的图
cv::Mat frame_needBe_right = frame(cv::Rect(0, 0, problem_col, height-1)); // 需要放在右面的图

cv::Mat frame_fix(height, width, CV_8UC3, cv::Scalar(255, 0, 255)); // 定义一张空白图

for (int i = 0; i < width; i++)
{
    for (int j = 0 ; j < height; j ++)
    {
        if (i <= width - problem_col-1)
        {
            frame_fix.at<cv::Vec3b>(j,i)[0] = frame_needBe_left.at<cv::Vec3b>(j,i)[0];
            frame_fix.at<cv::Vec3b>(j,i)[1] = frame_needBe_left.at<cv::Vec3b>(j,i)[1];
            frame_fix.at<cv::Vec3b>(j,i)[2] = frame_needBe_left.at<cv::Vec3b>(j,i)[2];
        }
        else
        {
            frame_fix.at<cv::Vec3b>(j,i)[0] = frame_needBe_right.at<cv::Vec3b>(j,i-width +problem_col)[0];
            frame_fix.at<cv::Vec3b>(j,i)[1] = frame_needBe_right.at<cv::Vec3b>(j,i-width +problem_col)[1];
            frame_fix.at<cv::Vec3b>(j,i)[2] = frame_needBe_right.at<cv::Vec3b>(j,i-width +problem_col)[2];
        }
    }
}   
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值