OpenCV实现照片换底色处理

目录

1.导言

2.引言

3.代码分析

4.优化改进

5.总结


1.导言

在图像处理领域,OpenCV是一款强大而广泛应用的开源库,能够提供丰富的图像处理和计算机视觉功能。本篇博客将介绍如何利用Qt 编辑器调用OpenCV库对照片进行换底色处理,实现更加独特和吸引人的效果

最终的实现效果如下图

2.引言

OpenCV是一个跨平台的计算机视觉库,其中包含了大量用于图像处理的函数和算法。照片换底色处理是一种常见的图像处理技术,可应用于广告设计、摄影后期处理等领域,为照片增添更多的艺术表现力。本次博客将使用OpenCV库中的函数和方法,在一张照片中将指定颜色范围内的背景替换为自定义的颜色。

3.代码分析

照片换底色处理是一种图像处理技术,通过选择并替换背景颜色,改变照片的整体视觉效果。OpenCV库提供了丰富的函数和方法,可以实现对图像的读取、处理和显示等操作。通过利用OpenCV的颜色转换、颜色范围选择和图像复制等函数,我们可以方便地实现照片换底色处理。

1.首先,需要在程序中引入OpenCV库的头文件,这样才能使用OpenCV的函数和数据结构。先下载好OpenCV然后把OpenCv的头文件包含到pro文件中去 注意要找到include文件地址

然后在x86中bin文件下所以形如 libopencv_*,dll 的文件 包含进去同时复制粘贴到C:\Windows\SysWOW64

 添加好库以后头文件也要包含进去(可以在添加OpenCV头文件之前运行一遍,不然电脑可能没有运行找不到库,让电脑反应过来)

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

 2.对图片进行处理

本次使用的代码中,我们首先将输入图像转换为HSV格式,以便更好地处理颜色信息。然后,通过指定颜色范围,创建一个掩膜(mask),将在范围内的像素设置为白色,不在范围内的像素设置为黑色。接下来,通过取反操作,我们可以从原始图像中抠出人像区域。创建一个新的背景图像,并将其设置为自定义的背景颜色。最后,通过将原始图像复制到新的背景图像中,仅保留人像区域,实现照片换底色的效果。

代码实现

    //1.显示一张图片
    Mat image = imread("d:/test.png");
    imshow("1",image);

    //2.图片转hsv格式
    Mat hsv;
    cvtColor(image,hsv,COLOR_BGR2HSV);
    imshow("2",hsv);

    //3.截取颜色区域的范围 inRang   在hsv取值范围内 呈白色  不在范围内 呈黑色
    Mat mask;//模板
    inRange(hsv,Scalar(100,43,46),Scalar(124,255,255),mask);
    imshow("3",mask);//现在的mask 就是可以抠出蓝色的底色

    //4.取反操作  但是我们需要抠出的是人像
    bitwise_not(mask,mask);
    imshow("4",mask);

 对图片进行hsv  ,取色  , 取反 创建新背景效果如下

Scalar可以选择颜色范围,三元素RGB颜色范围,针对选取的颜色可以参考hsv表

 3.实现照片换底色,选取红色背景

红色背景RGB选择 为 40,40,200,也可以根据自己需要调整范围

 //5.做一张红色背景图   大小?类型? 参考image原始图片
    Mat redBack = Mat::zeros(image.size(),image.type());
    redBack = Scalar(40,40,200);
    imshow("5",redBack);

    //6.实现图片的拷贝操作
    image.copyTo(redBack,mask);
    imshow("6",redBack);

4.优化改进

对于原始代码,我们可以进行一些优化和改进,以提高代码的可读性和扩展性。例如,可以将换底色处理的功能封装成一个独立的函数,方便重复调用。同时,可以通过参数化的方式,使得函数可以根据不同的需求进行自定义设置。此外,还可以添加错误检查和异常处理机制,提高代码的健壮性和容错性。此外优化后还增加了对图像的保存流程

优化后完整代码

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

void changeBackground(const Mat& inputImage, const Scalar& backgroundColor, const Scalar& lowerBound, const Scalar& upperBound)
{


    // 图片转为hsv格式
    Mat hsv;
    cvtColor(inputImage, hsv, COLOR_BGR2HSV);
    // 在指定范围内的变为白色,不在范围内的变为黑色
    Mat mask;
    inRange(hsv, lowerBound, upperBound, mask);
    imwrite("D:/QtProject/mask1.png", mask);

    // 取反操作,抠出人像
    bitwise_not(mask, mask);


    // 创建新的背景图像
    Mat newBackground = Mat::zeros(inputImage.size(), inputImage.type());
    newBackground = backgroundColor;

    // 将原始图像复制到新背景图像中,只保留前景(人像)区域
    inputImage.copyTo(newBackground, mask);

    imshow("New Background Image", newBackground);


    //保存图片
    imwrite("D:/QtProject/new_background.png", newBackground);


}

int main(int argc, char* argv[])
{
    // 显示一张图片
    Mat image = imread("D:/QtProject/gege.jpg");
    imshow("1",image);
    // 检查图像是否成功加载
    if (image.empty())
    {
        cout << "Failed to load image." << endl;
        return -1;
    }

    // 定义背景颜色、颜色范围
    Scalar backgroundColor(60,60,220);
    Scalar lowerBound(100, 43, 46);
    Scalar upperBound(124, 255, 255);

    // 更换背景
    changeBackground(image, backgroundColor, lowerBound, upperBound);

    // 等待用户按下任意键
    waitKey(0);

    return 0;
}

5.总结

通过本篇博客,我们了解了OpenCV实现照片换底色处理的方法和步骤。OpenCV库提供了丰富的图像处理函数和算法,可以帮助我们实现各种各样的图像处理任务。照片换底色处理是其中的一种,通过选择并替换背景颜色,可以为照片增添独特的艺术效果。希望本篇博客能够对读者理解和应用OpenCV库进行图像处理有所帮助。如果有需要Qt和OpenCV下载的同学可以私聊我,欢迎大家共同进步

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/43613.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTTP 缓存机制 强制缓存/协商缓存

为什么被缓存&#xff0c;如何命中缓存以及缓存什么时候生效的&#xff0c;我们却很少在实际开发中去了解。借助动画形式来从根上理解 HTTP 缓存机制及原理。 HTTP 缓存&#xff0c;对于前端的性能优化方面来讲&#xff0c;是非常关键的&#xff0c;从缓存中读取数据和直接向服…

REST和RPC的区别

1 REST REST 不是一种协议&#xff0c;它是一种架构。大部分REST的实现中使用了RPC的机制&#xff0c;大致由三部分组成&#xff1a; method&#xff1a;动词&#xff08;GET、POST、PUT、DELETE之类的&#xff09;Host&#xff1a;URI&#xff08;统一资源标识&#xff09;&…

前端Vue uni-app App/小程序/H5 通用tree树形结构图

随着技术的发展&#xff0c;开发的复杂度也越来越高&#xff0c;传统开发方式将一个系统做成了整块应用&#xff0c;经常出现的情况就是一个小小的改动或者一个小功能的增加可能会引起整体逻辑的修改&#xff0c;造成牵一发而动全身。 通过组件化开发&#xff0c;可以有效实现…

Apple M1 Pro macOS 切换中文输入法卡住

(macOS 在切换中文输入法时出现卡住的情况 1&#xff0c;切换为中文输入法后再次卡住2&#xff0c;杀死 简体中文输入方式的进程参考 将光标移到菜单栏的输入法切换为英文输入法 多次切换为英文输入法&#xff0c;可以切换为英文输入法 切换为英文输入法后电脑不卡顿了&#xf…

云原生基础设施实践:NebulaGraph 的 KubeBlocks 集成故事

像是 NebulaGraph 这类基础设施上云&#xff0c;通用的方法一般是将线下物理机替换成云端的虚拟资源&#xff0c;依托各大云服务厂商实现“服务上云”。但还有一种选择&#xff0c;就是依托云数据基础设施&#xff0c;将数据库产品变成为云生态的一环&#xff0c;不只是提供自身…

《面试1v1》如何提高远程用户的吞吐量

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

【单调栈 +前缀和】AcWing 4738. 快乐子数组

原题链接 原题链接 相关算法概念介绍 前缀和&#xff08;Prefix Sum&#xff09; 前缀和是指将数组中从开头位置到当前位置的所有元素累加得到的新数组。通常&#xff0c;我们使用一个额外的数组来保存这些累加和&#xff0c;这个数组被称为前缀和数组。对于原始数组A&…

性能测试Ⅵ(总结)

locust&#xff1a;是基于Python语言的性能测试工具&#xff0c;它是基于协程的思想来进行设计的。Python语言是没有办法利用多核的优势&#xff0c;所以了Python为了解决这个问题&#xff0c;设计了协程&#xff0c;作为协程的任务&#xff0c;遇到IO堵塞就立刻切换。 生命是协…

项目初始化--uniapp--vscode--vue3--ts

HBuilderX 创建 uni-app 项目 注意开启服务端口 目录结构 ├─pages 业务页面文件存放的目录 │ └─index │ └─index.vue index页面 ├─static 存放应用引用的本地静态资源的目录(注意&#xff1a;静态资源只能存放于此) ├─unpackage …

Ceph 应用

Ceph 应用 一、创建 CephFS 文件系统 MDS 接口 1.服务端操作 1&#xff09;在管理节点创建 mds 服务 cd /etc/ceph ceph-deploy mds create node01 node02 node032&#xff09;查看各个节点的 mds 服务 ssh rootnode01 systemctl status ceph-mdsnode01 ssh rootnode02 syst…

代码随想录| 图论02●695岛屿最大面积 ●1020飞地的数量 ●130被围绕的区域 ●417太平洋大西洋水流问题

#695岛屿最大面积 模板题&#xff0c;很快.以下两种dfs&#xff0c;区别是看第一个点放不放到dfs函数中处理&#xff0c;那么初始化的area一个是1一个是0 int dir[4][2]{0,1,0,-1,1,0,-1,0};void dfs(int x, int y,int n, int m, int &area,vector<vector<bool>…

K8S初级入门系列之十一-安全

一、前言 安全是K8S重要的特性&#xff0c;在K8S初级入门系列之四-Namespace/ConfigMap/Secret章节&#xff0c;我们已经已经了解了Namespace&#xff0c;Secret与安全相关的知识。本篇将梳理K8S在安全方面的策略。主要包括两个方面&#xff0c;API安全访问策略以及Pod安全策略…

YOLOv5基础知识

定位和检测: 定位是找到检测图像中带有一个给定标签的单个目标 检测是找到图像中带有给定标签的所有目标 图像分割和目标检测的区别&#xff1a; 图像分割即为检测出物体的完整轮廓&#xff0c;而目标检测则是检测出对应的目标。&#xff08;使用框框把物体框出来&#xff…

Linux:多进程和多线程回环socket服务器和客户端

多进程socket服务器代码&#xff1a; #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h> #include <ctype.h> #include <sys/wait.h> #i…

06.计算机网络——IP协议

文章目录 网络层IP协议基本概念协议头格式如何解包如何交付网段划分子网掩码特殊的IP地址IP地址的数量限制私有IP地址和公网IP地址路由 网络层 IP协议 IP协议提供一种将数据从A主机送达到B主机的能力&#xff0c;进行网络层的通信。 ​ IP协议 基本概念 主机 —— 配有IP地址…

SpringCloudAlibaba微服务实战系列(五)Sentinel1.8.5+Nacos持久化

Sentinel数据持久化 前面介绍Sentinel的流控、熔断降级等功能&#xff0c;同时Sentinel应用也在面临着一个问题&#xff1a;我们在Sentinel后台管理界面中配置了一堆流控、降级规则&#xff0c;但是Sentinel一重启&#xff0c;这些规则全部消失了。那么我们就要考虑Sentinel的持…

小程序路由跳转页面重复问题

目标&#xff1a;想要某个页面在历史中&#xff08;页面栈&#xff09;只显示一次 什么是页面栈&#xff1a; 在小程序开发中&#xff0c;页面栈是指小程序当前打开的页面的层级关系堆栈。每当打开一个新页面时&#xff0c;它会被放置在页面栈的顶部&#xff0c;而当前页面就位…

Linux学习之Ubuntu 20.04安装内核模块

参考博客&#xff1a;Ubuntu20.04编译内核教程 sudo lsb_release -a可以看到我当前的系统是Ubuntu 20.04.4&#xff0c;sudo uname -r可以看到我的系统内核版本是5.4.0-100-generic。 sudo apt-get install -y libncurses5-dev flex bison libssl-dev安装所需要的依赖。 su…

交换一个整数二进制位的奇数位和偶数位

目录 一、方案一 1.求待操作数的二进制序列 2.创建一个数组存放待操作数的二进制序列 3.交换二进制序列奇偶位 4.输出奇偶位交换之后的二进制序列 5.代码 二、方案二&#xff08;宏的实现&#xff09; 1.求待操作数二进制序列偶数位 2.求待操作数二进制序列奇数位 3.求待…

手机word文档怎么转换成pdf?分享两种方法

手机word文档怎么转换成pdf&#xff1f;在如今信息化的时代&#xff0c;电子文档已经成为人们日常办公不可或缺的一部分。随着科技的不断进步&#xff0c;电子文档的格式也在不断发展。PDF作为电子文档的一种重要格式&#xff0c;被广泛使用。那么&#xff0c;如何将手机上的Wo…