opencv3更换图片背景
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
void ChangeImgBG();
Mat HandleImgData(Mat &img);
/*
图片背景替换
知识点:分水岭分割、高斯模糊
处理步骤:数据组装-KMeans分割-背景消除-生成遮罩-模糊-输出
*/
void ChangeImgBG()
{
char* win1 = "window1";
char* win2 = "window2";
char* win3 = "window3";
char* win4 = "window4";
char* win5 = "window5";
char* win6 = "window6";
namedWindow(win1,CV_WINDOW_AUTOSIZE);//创建窗口 win1
namedWindow(win2,CV_WINDOW_AUTOSIZE);//创建窗口 win2
namedWindow(win3,CV_WINDOW_AUTOSIZE);//创建窗口 win3
namedWindow(win4, CV_WINDOW_AUTOSIZE);//创建窗口 win4
namedWindow(win5, CV_WINDOW_AUTOSIZE);//创建窗口 win5
namedWindow(win6, CV_WINDOW_AUTOSIZE);//创建窗口 win6
Mat img1, img2;
//加载图片
img1 = imread("D:\\参考手册\\opencv素材\\xl.jpg");
if (img1.empty())
{
cout << "image not found..." << endl;
exit(0);//如果图片不存在,退出程序
}
img2 = img1.clone();
//显示原始图片
imshow(win1,img1);
//组装数据
Mat points = HandleImgData(img1);
//Kmeans处理
int numCluster = 4;
Mat labels;
Mat centers;
TermCriteria termCriteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT,10,0.1);
kmeans(points, numCluster,labels, termCriteria,3,KMEANS_PP_CENTERS,centers);
//遮罩
Mat mask = Mat::zeros(img1.size(),CV_8UC1);
int index = img1.rows*2 + 2;
int cindex = labels.at<int>(index,0);//背景设置为0
int height = img1.rows;
int width = img1.cols;
for (int row = 0;row<height;row++)
{
for (int col =0;col<width;col++)
{
index = row*width + col;
int label = labels.at<int>(index,0);
if (label ==cindex)
{
img2.at<Vec3b>(row, col)[0] = 0;
img2.at<Vec3b>(row, col)[1] = 0;
img2.at<Vec3b>(row, col)[2] = 0;
mask.at<uchar>(row, col) = 0;
}
else
{
mask.at<uchar>(row, col) = 255;
}
}
}
//腐蚀
Mat k = getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));
erode(mask,mask,k);
imshow(win4,mask);
//高斯模糊
GaussianBlur(mask,mask,Size(3,3),0,0);
imshow(win5,mask);
//通道混合
RNG rng(12345);
Vec3b color;
color[0] = rng.uniform(0,255);
color[1] = rng.uniform(0, 255);
color[2] = rng.uniform(0, 255);
Mat result(img1.size(),img1.type());
double d1 = 0.0;
int r = 0, g = 0, b = 0;
int r1 = 0, g1 = 0, b1 = 0;
int r2 = 0, g2 = 0, b2 = 0;
for (int row = 0; row < height;row++)
{
for (int col=0;col<width;col++)
{
int m = mask.at<uchar>(row,col);
if (m==255)
{
result.at<Vec3b>(row, col) = img1.at<Vec3b>(row,col);//前景
}
else if (m == 0)
{
result.at<Vec3b>(row, col) = color;//背景
}
else
{
d1 = m / 255.0;
b1 = img1.at<Vec3b>(row, col)[0];
g1 = img1.at<Vec3b>(row, col)[1];
r1 = img1.at<Vec3b>(row, col)[2];
b2 = color[0];
g2 = color[1];
r2 = color[2];
b = b1*d1 + b2*(1.0-d1);
g = g1*d1 + g2*(1.0-d1);
r = r1*d1 + r2*(1.0-d1);
result.at<Vec3b>(row,col)[0] = b;
result.at<Vec3b>(row, col)[1] = g;
result.at<Vec3b>(row, col)[2] = r;
}
}
}
//输出
imshow(win2,mask);
imshow(win3,img2);
imshow(win6,result);
//保存处理后的图片
imwrite("result-2.jpg",result);
}
//组装样本数据
Mat HandleImgData(Mat &img)
{
int width = img.cols;
int height = img.rows;
int count1 = width*height;
int channels1 = img.channels();
Mat points(count1, channels1,CV_32F,Scalar(10));
int index = 0;
for (int row = 0; row < height;row++)
{
for (int col = 0; col < width;col++)
{
index = row*width + col;
Vec3b bgr = img.at<Vec3b>(row,col);
points.at<float>(index, 0) = static_cast<int>(bgr[0]);
points.at<float>(index, 1) = static_cast<int>(bgr[1]);
points.at<float>(index, 2) = static_cast<int>(bgr[2]);
}
}
return points;
}
int main()
{
ChangeImgBG();
waitKey(0);
return 0;
}
运行效果:

opencv3更换图片背景的更多相关文章
- C# 给PDF添加图片背景
C# 给PDF添加图片背景 今天要实现的是给PDF文件添加图片背景这个功能.PDF是近年来最流行的文件之一,无论是办公还是日常生活中都经常会用到,很多时候,PDF文件的背景色都是白色,看多了难免觉得累 ...
- Angular4 自制华容道拼图(可以升级难度、关卡、更换图片)
前端工程师新手一枚,之前一直做些小设计,以及静态页面的编写工作.刚刚接触 Angular 没有多久,四个月前对于 js 也只是会写 alert 之流,现在进步算是很大,下面是自制的华容道拼图(可以升级 ...
- win10更换登陆背景和关闭锁屏
更换登陆背景图 用国外一个hacker写的工具,可在github上下载,或者下载我上传到百度网盘的备份.win10默认的登陆背景太难看了. 去掉锁屏图片 登陆界面其实本身就是一种锁屏,为什么还要单独搞 ...
- Atitit 动态按钮图片背景颜色与文字组合解决方案
Atitit 动态按钮图片背景颜色与文字组合解决方案 转换背景颜色,setFont("cywe_img", fontScale, 50, 5) 设置文字大小与坐标 文字分拆,使用字 ...
- jquery 图片背景透明度(支持IE5/IE6/IE7)
设置背景图片,以突出透明度的效果及jquery png背景透明插件实例教程 <head> <title>toggle()</title> <style typ ...
- 用shader使图片背景透明
转自:http://blog.csdn.net/dawn_moon/article/details/8631783 好吧,终于抽时间写这篇文章了. 手头上有很多人物行走图,技能特效图等,但这些图都有个 ...
- iOS 图片背景模糊效果
iOS 图片背景模糊效果 1.使用CoreImage中的模糊滤镜 原始效果图如下: CoreImage的实现: - (void)viewDidLoad { [super viewDidLoad]; / ...
- 【转】cocos2d-x游戏开发(十四)用shader使图片背景透明
转自:http://blog.csdn.net/dawn_moon/article/details/8631783 好吧,终于抽时间写这篇文章了. 手头上有很多人物行走图,技能特效图等,但这些图都有个 ...
- 关于文字颜色/图片背景---selector状态列表
文字颜色 android:textColor="@style/style_name" ----------------------------------widget 图片背景 a ...
随机推荐
- C++中string的常见用法
在ACM中主要用到string的这几个功能:赋值,添加,删除,替换,查找,比较,反向排序. 1.赋值 直接来就行: string ss; ss="aaa"; 或者 string s ...
- mysql 开发标准规范
一.表设计 1. 库名.表名.字段名使用小写字母,“_”分割. 2. 库名.表名.字段名不超过12个字符. 3. 库名.表名.字段名见名知意,尽量使用名词而不是动词. 4. 优先使用InnoDB存储引 ...
- VueJs路由跳转——vue-router的使用
对于单页应用,官方提供了vue-router进行路由跳转的处理,本篇主要也是基于其官方文档写作而成. 安装 基于传统,我更喜欢采用npm包的形式进行安装. npm install vue-router ...
- vector的内存分配机制分析
该程序初步演示了我对vector在分配内存的时候的理解.可能有误差,随着理解的改变,改代码可以被修改. /* 功能说明: vector的内存分配机制分析. 代码说明: vector所管理的内存地址是连 ...
- 2016 ACM-ICPC 区域赛(大连站)题解
题目链接 A - Wrestling Match (二分图染色) 题意略坑(没有说好的玩家一定能打过差的玩家啊啊~~) 典型的二分图染色问题,每个玩家看成一个点,把相互较量过的玩家之间连边,好的玩家染 ...
- 数据清洗记录,pandas
pandas数据清洗:http://www.it165.net/pro/html/201405/14269.html data=pd.Series([1,2,3,4]) data.replace([1 ...
- nginx之 [error] 6702#0:XXX is forbidden (13: Permission denied)
问题描述: 配置完 nginx 两个虚拟机后,客户端能够访问原始的server ,新增加的 server 虚拟机 不能够访问,报错如下页面 解决过程: 1. 查看报错日志[root@mysql03 n ...
- sleep(0)作用
假设现在是 2008-4-7 12:00:00.000,如果我调用一下 Thread.Sleep(1000) ,在 2008-4-7 12:00:01.000 的时候,这个线程会 不会被唤醒?某人的代 ...
- maven工程编译成jar包
在pom文件的project节点下增加build节点,mvn package即可 <build> <plugins> <plugin> <artifactId ...
- 上传文件csv 导入功能
HTML代码: <script> function uploadCsv() { $('#chooseCsvFile').click(); } function doUploadCsv() ...