opencv4 图像无缝融合

举报
风吹稻花香 发表于 2022/01/14 01:03:31 2022/01/14
【摘要】 一:API函数介绍 OpenCV3.x的图像计算模块多了新算法API-无缝克隆(Seamless Cloning),主要是针对图像编辑,局部修改等应用场景实现迁移对象与原图像场景的无缝克隆。相关函数与参数说明如下: seamlessClone( InputArray src, // 输入的待克隆的图像,三通道 Inpu...

一:API函数介绍

OpenCV3.x的图像计算模块多了新算法API-无缝克隆(Seamless Cloning),主要是针对图像编辑,局部修改等应用场景实现迁移对象与原图像场景的无缝克隆。相关函数与参数说明如下:


  1. seamlessClone(

  2. InputArray src, // 输入的待克隆的图像,三通道

  3. InputArray dst, // 输入的克隆目标图像,三通道

  4. InputArray mask, // 遮罩层,大小跟src图像一样大

  5. Point p, // 克隆图像在dst图像上的中心位置

  6. OutputArray blend, // 克隆完成输出图像

  7. int flags // 克隆方法选择

  8. )

支持的克隆方法有三种分别如下

- NORMAL_CLONE

把待克隆的src对象完整的插入到dst目标图像图像中去,不改变其轮廓特征与结构

- MIXED_CLONE

混合克隆跟正常克隆相比,它会把背景颜色与纹理考虑进去,对轮廓特征与背景实现透明通道混合。

- MONOCHROME_TRANSFER

基于特征的迁移融合,只会把特征融合到背景图像当中。

二:代码演示

一般我们使用无缝克隆时候最常用设置就是正常克隆,都是想无缝替换或者融合特定对象到场景中去。演示程序主要是基于图像二值化实现自动遮罩层提取生成,然后基于遮罩图像,原图像、目标图像使用无缝克隆算法生成混合之后的输出图像。

案例一:文字融合

文字信息

图片

目标图像

图片

融合效果

图片

遮罩层

图片

演示源码


  1. #include <opencv2/opencv.hpp>

  2. #include <iostream>

  3. using namespace cv;

  4. using namespace std;

  5. int main(int argc, char** argv) {

  6.    Mat dst = imread("D:/javaopencv/test.png");

  7.    Mat image = imread("D:/javaopencv/text_opencv.png");

  8.    if (dst.empty() || image.empty()) {

  9.        printf("could not load image...\n");

  10.        return -1;

  11.    }

  12.    Mat gray, mask;

  13.    cvtColor(image, gray, COLOR_BGR2GRAY);

  14.    threshold(gray, mask, 0, 255, THRESH_BINARY | THRESH_OTSU);

  15.    Mat k = getStructuringElement(MORPH_RECT, Size(10, 10), Point(-1, -1));

  16.    dilate(mask, mask, k);

  17.    imshow("mask", mask);

  18.    imshow("input", image);

  19.    imshow("target", dst);

  20.    imwrite("D:/mask.png", mask);

  21.    Mat blend;

  22.    seamlessClone(image, dst, mask, Point(dst.cols/2, dst.rows/2), blend, NORMAL_CLONE);

  23.    imshow("blend-image", blend);

  24.    imwrite("D:/blend.png", blend);

  25.    waitKey(0);

  26.    return 0;

  27. }

案例二:对象融合

对象信息

图片

目标图像

图片

融合效果

图片

遮罩层

图片

演示源码


  1. #include <opencv2/opencv.hpp>

  2. #include <iostream>

  3. using namespace cv;

  4. using namespace std;

  5. int main(int argc, char** argv) {

  6.    Mat dst = imread("D:/javaopencv/landscape.png");

  7.    Mat image = imread("D:/javaopencv/myapple.png");

  8.    if (dst.empty() || image.empty()) {

  9.        printf("could not load image...\n");

  10.        return -1;

  11.    }

  12.    Mat gray, mask;

  13.    cvtColor(image, gray, COLOR_BGR2GRAY);

  14.    threshold(gray, mask, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);

  15.    Mat k = getStructuringElement(MORPH_RECT, Size(10, 10), Point(-1, -1));

  16.    dilate(mask, mask, k);

  17.    imshow("mask", mask);

  18.    imshow("input", image);

  19.    imshow("target", dst);

  20.    imwrite("D:/mask.png", mask);

  21.    add(image, Scalar(100, 100, 100), image, mask);

  22.    Mat blend;

  23.    seamlessClone(image, dst, mask, Point(dst.cols*0.7, dst.rows/2), blend, NORMAL_CLONE);

  24.    imshow("blend-image", blend);

  25.    imwrite("D:/blend.png", blend);

  26.    waitKey(0);

  27.    return 0;

  28. }

注意点:

上述代码中,我使用了add来提升输入图像的亮度,这样做的好处是可以让融合之后的图像跟原图更加相似,感兴趣可以尝试注释掉看看会出来什么结果。另外还可以尝试本文中提到另外两种融合方法,这里就不再一一举例说明。

文章来源: blog.csdn.net,作者:AI视觉网奇,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/jacke121/article/details/122465875

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。