1、证件背景替换

代码实现思路:

1.将二维图像数据线性化

2.使用K-means聚类;分离出背景色

3.背景与人物像素二值化

4.腐蚀 + 高斯模糊:图像与背景交汇处高斯模糊化

5.更换背景色以及交汇处融合处理

代码:

#include <opencv2/opencv.hpp>
#include <iostream>using namespace std;
using namespace cv;int main(int argc, char** argv) {Mat src = imread("../img/toux.jpg");if (src.empty()) {printf("could not load image...\n");return -1;}imshow("原图", src);// 1.将二维图像数据线性化Mat data;for (int i = 0; i < src.rows; i++)     //像素点线性排列for (int j = 0; j < src.cols; j++){Vec3b point = src.at<Vec3b>(i, j);Mat tmp = (Mat_<float>(1, 3) << point[0], point[1], point[2]);data.push_back(tmp);}// 2.使用K-means聚类;分离出背景色int numCluster = 4;Mat labels;TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1);kmeans(data, numCluster, labels, criteria, 3, KMEANS_PP_CENTERS);// 3.背景与人物二值化Mat mask = Mat::zeros(src.size(), CV_8UC1);int index = src.rows * 2 + 2;  //获取点(2,2)作为背景色int cindex = labels.at<int>(index);/*  提取背景特征 */for (int row = 0; row < src.rows; row++) {for (int col = 0; col < src.cols; col++) {index = row * src.cols + col;int label = labels.at<int>(index);if (label == cindex) { // 背景mask.at<uchar>(row, col) = 0;}else {mask.at<uchar>(row, col) = 255;}}}//imshow("mask", mask);// 4.腐蚀 + 高斯模糊:图像与背景交汇处高斯模糊化Mat k = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));erode(mask, mask, k);//imshow("erode-mask", mask);GaussianBlur(mask, mask, Size(3, 3), 0, 0);//imshow("Blur Mask", mask);// 5.更换背景色以及交汇处融合处理RNG rng(12345);Vec3b color;  //设置的背景色color[0] = 217;//rng.uniform(0, 255);color[1] = 60;// rng.uniform(0, 255);color[2] = 160;// rng.uniform(0, 255);Mat result(src.size(), src.type());double w = 0.0;   //融合权重int b = 0, g = 0, r = 0;int b1 = 0, g1 = 0, r1 = 0;int b2 = 0, g2 = 0, r2 = 0;for (int row = 0; row < src.rows; row++) {for (int col = 0; col < src.cols; col++) {int m = mask.at<uchar>(row, col);if (m == 255) {result.at<Vec3b>(row, col) = src.at<Vec3b>(row, col); // 前景}else if (m == 0) {result.at<Vec3b>(row, col) = color; // 背景}else {/* 融合处理部分 */w = m / 255.0;b1 = src.at<Vec3b>(row, col)[0];g1 = src.at<Vec3b>(row, col)[1];r1 = src.at<Vec3b>(row, col)[2];b2 = color[0];g2 = color[1];r2 = color[2];b = b1 * w + b2 * (1.0 - w);g = g1 * w + g2 * (1.0 - w);r = r1 * w + r2 * (1.0 - w);result.at<Vec3b>(row, col)[0] = b;result.at<Vec3b>(row, col)[1] = g;result.at<Vec3b>(row, col)[2] = r;}}}imshow("背景替换", result);waitKey(0);return 0;
}

结果:

2、视频背景替换

视频背景替换思路:

  • Take each frame of the video
  • Convert from BGR to HSV color-space
  • We threshold the HSV image for a range of blue color
  • Now extract the blue object alone, we can do whatever on that image we want.

视频帧背景替换关键API:

1、   cvtColor(frame, hsv, COLOR_BGR2HSV);  //转换颜色域
     2、   inRange(hsv, Scalar(35, 43, 46), Scalar(155, 255, 255), OutImg);  //提取背景

代码:

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
using namespace std;Mat replace_and_blend(Mat &frame, Mat &mask);
Mat background_01;
Mat background_02;
int main(int argc, char** argv) {// start here...   background_01 = imread("D:/vcprojects/images/bg_01.jpg");background_02 = imread("D:/vcprojects/images/bg_02.jpg");VideoCapture capture;capture.open("D:/vcprojects/images/01.mp4");if (!capture.isOpened()) {printf("could not find the video file...\n");return -1;}char* title = "input video";char* resultWin = "result video";namedWindow(title, CV_WINDOW_AUTOSIZE);namedWindow(resultWin, CV_WINDOW_AUTOSIZE);Mat frame, hsv, mask;int count = 0;while (capture.read(frame)) {cvtColor(frame, hsv, COLOR_BGR2HSV);inRange(hsv, Scalar(35, 43, 46), Scalar(155, 255, 255), mask);// 形态学操作Mat k = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));morphologyEx(mask, mask, MORPH_CLOSE, k);erode(mask, mask, k);GaussianBlur(mask, mask, Size(3, 3), 0, 0);Mat result = replace_and_blend(frame, mask);char c = waitKey(1);if (c == 27) {break;}imshow(resultWin, result);imshow(title, frame);}waitKey(0);return 0;
}Mat replace_and_blend(Mat &frame, Mat &mask) {Mat result = Mat::zeros(frame.size(), frame.type());int h = frame.rows;int w = frame.cols;int dims = frame.channels();// replace and blendint m = 0;double wt = 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 < h; row++) {uchar* current = frame.ptr<uchar>(row);uchar* bgrow = background_02.ptr<uchar>(row);uchar* maskrow = mask.ptr<uchar>(row);uchar* targetrow = result.ptr<uchar>(row);for (int col = 0; col < w; col++) {m = *maskrow++;if (m == 255) { // 背景*targetrow++ = *bgrow++;*targetrow++ = *bgrow++;*targetrow++ = *bgrow++;current += 3;} else if(m==0) {// 前景*targetrow++ = *current++;*targetrow++ = *current++;*targetrow++ = *current++;bgrow += 3;} else {b1 = *bgrow++;g1 = *bgrow++;r1 = *bgrow++;b2 = *current++;g2 = *current++;r2 = *current++;// 权重wt = m / 255.0;// 混合b = b1*wt + b2*(1.0 - wt);g = g1*wt + g2*(1.0 - wt);r = r1*wt + r2*(1.0 - wt);*targetrow++ = b;*targetrow++ = g;*targetrow++ = r;}}}return result;
}

 视频中绿布替换成风景背景:

OpenCV案例(五): 更换背景色相关推荐

  1. 2021年大数据Flink(三十八):​​​​​​​Table与SQL ​​​​​​案例五 FlinkSQL整合Hive

    目录 案例五 FlinkSQL整合Hive 介绍 集成Hive的基本方式 准备工作 1.添加hadoop_classpath 2.下载jar并上传至flink/lib目录 3.修改hive配置 4.启 ...

  2. linux oracle em使用,案例:五步解决linux操作系统Oracle EM乱码的问题

    天萃荷净 用户生产环境Linux系统Oracle数据库配置OEM使用时出现乱码情况 如果想以中文显示,则需要修改一些配置文件. 包括三个目录: $ORACLE_HOME/jdk/jre/lib $OR ...

  3. 【机器学习】多项式回归案例五:正则惩罚解决过拟合(Ridge回归和Lasso回归)

    正则惩罚解决过拟合(Ridge回归和Lasso回归) 案例五: 正则惩罚解决过拟合(Ridge回归和Lasso回归) 3.2.1 模块加载与数据读入 3.2.2 特征工程 3.2.3 模型搭建与应用 ...

  4. python怎么换背景颜色_用opencv给图片换背景色的示例代码

    图像平滑 模糊/平滑图片来消除图片噪声 OpenCV函数:cv2.blur(), cv2.GaussianBlur(), cv2.medianBlur(), cv2.bilateralFilter() ...

  5. opencv案例: 车辆检测

    opencv案例: 车辆检测 说明:这是在哔哩哔哩上看李超老师的视频时,他讲的案例,我是搬运工. 实现功能: 1.识别出图片中的汽车对象 2.对车辆进行统计,并将统计结果展示出来 涉及到的知识点: 图 ...

  6. 不同cpu服务器虚拟迁移,案例五:虚拟机迁移报错CPU不兼容

    [vSphere故障案例] 案例五:虚拟机迁移报错CPU不兼容 相同品牌不同型号服务器ESXi主机之间的虚拟机迁移时,报错:"主机的CPU在CPUID级别0x1寄存器ecx出的要求不兼容.& ...

  7. 案例五 温湿度+LED

    案例五 温湿度+LED --init.lua print("set up wifi mode") wifi.setmode(wifi.STATION) wifi.sta.confi ...

  8. 【Drools规则引擎】基础入门案例五(Kie-Server+WorkBench)

    [Drools规则引擎]基础入门案例五(Kie-Server+WorkBench) 介绍 搭建WorkBench 搭建Kie-Server 使用WorkBench 访问登入 客户端测试 介绍 java ...

  9. OPENCV图片批量更换文字

    团支书最头疼的事情莫过于假期收截图,例如当前的"暑假十课",总有人久催不交 看这图片上交的模板,通过改变右上角名字就能做到偷天换日,那么一个班近30,十课一共300张图片,人工肯定 ...

  10. OpenCV(五)绘制图形与文本

    目录 一.绘制直线 1.函数line() 2.代码 3.效果 二.绘制矩形 1.函数rectangle() 1-1.左上角顶点+右下角顶点 1-2.矩形位置和长宽 2.代码 3.效果 三.绘制椭圆 1 ...

最新文章

  1. 算法设计与分析男女匹配问题C语言,C语言解决新郎和新娘配对问题代码解析
  2. 使用 Circular Reveal 动画让页面跳转更炫酷
  3. 苹果手机各种型号图片_2020年12月小米/红米手机推荐|小米/红米手机选购要点|小米/红米手机性价比推荐,干货满满...
  4. 谈一谈HTTP中Get与Post的区别与主要应用场景
  5. CVPR 2020丨MAML-Tracker: 用目标检测思路做目标跟踪? 小样本即可得高准确率
  6. Android源码学习之如何使用eclipse+NDK
  7. python爬取qq音乐评论_教你用Python爬去QQ音乐评论
  8. SPSS中的数据分析—信度效度检验【2】
  9. Photoshop通道抠图
  10. 学习软件测试必备的网站清单,建议收藏!
  11. CentOS7 修改Swap大小
  12. 论文投稿指南——中国(中文EI)期刊推荐(第5期)
  13. 项目经理成功的五个关键因素
  14. 『R语言Python』使用logging、log4r写日志
  15. WPF编程--地图控件GMap使用
  16. 怎么把PPT批量变成图片?
  17. 【BZOJ 4399】魔法少女LJJ
  18. JAVA unusual问题收集
  19. 汇编 SHL指令和SHR指令
  20. android UI适配方法经验总结

热门文章

  1. 数据结构与算法——30. 广度、深度优先搜索及骑士周游问题
  2. 2015陈奕迅another eason‘s life演唱会歌单
  3. 我原以为我不会伤心......
  4. 微信小程序之商品发布+编辑功能(多图片上传功能)
  5. 2021年中国天眼对外开放,美媒感叹中国崛起的科技实力
  6. Java Web学习day25------Vue和综合案例
  7. ANSYS ICEM CFD三维非结构网络生成实例——教室全新风送风与排风
  8. 2017《Java技术预备作业1》计科1502杨雪莹
  9. oracle查询数字类溢出,有趣的数值溢出(一)
  10. 从0开始,利用docker搭建一套大数据开发环境(一)