首页 > 其他分享 >OpenCV3.2图像分割 实例10:绿幕视频背景替换

OpenCV3.2图像分割 实例10:绿幕视频背景替换

时间:2023-08-18 09:12:25浏览次数:38  
标签:10 targetrow Mat ++ 绿幕 mask int frame OpenCV3.2

  1 #include <opencv2/opencv.hpp>
  2 #include <iostream>
  3  
  4 using namespace cv;
  5 using namespace std;
  6  
  7 Mat replace_and_blend(Mat &frame, Mat &mask);
  8 Mat background_01;//背景1
  9 Mat background_02;//背景2
 10 int main(int argc, char** argv) {
 11     // start here...    
 12     background_01 = imread("bg_01.jpg");
 13     background_02 = imread("bg_02.jpg");
 14     VideoCapture capture;//视频抓取
 15     capture.open("01.mp4");
 16     if (!capture.isOpened()) {
 17         printf("could not find the video file...\n");
 18         return -1;
 19     }
 20     const char* title = "input video";
 21     const char* resultWin = "result video";
 22     namedWindow(title, CV_WINDOW_AUTOSIZE);
 23     namedWindow(resultWin, CV_WINDOW_AUTOSIZE);
 24     Mat frame, hsv, mask;
 25     int count = 0;
 26     //测试视频读取
 27     //while (capture.read(frame)) {//判断读取视频单帧是否成功,读取单帧图像复制给frame对象
 28     //    imshow(title, frame);
 29     //    char c =waitKey(50);
 30     //    if (c == 27) {
 31     //        break;
 32     //    }
 33  
 34     //}
 35     ///
 36     mask测试
 37     //while (capture.read(frame)) {
 38     //    cvtColor(frame, hsv, COLOR_BGR2HSV);//转换为HSV
 39     //    //原背景选择HSV--绿色
 40     //    inRange(hsv, Scalar(35, 43, 46), Scalar(60, 255, 255), mask);//mask数据调整60
 41     //    imshow("mask",mask);//显示mask
 42     //    count++;
 43     //    imshow(title, frame);//显示输入video
 44     //    char c = waitKey(1);
 45     //    if (c == 27) {
 46     //        break;
 47     //    }
 48     //}
 49     /
 50     while (capture.read(frame)) {//判断读取视频单帧是否成功,读取单帧图像复制给frame对象
 51         cvtColor(frame, hsv, COLOR_BGR2HSV);//转换为HSV
 52         inRange(hsv, Scalar(35, 43, 46), Scalar(60, 255, 255), mask);
 53         // 形态学操作,3*3进行腐蚀,然后高斯进行3*3的模糊,边界不变
 54         Mat k = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
 55         morphologyEx(mask, mask, MORPH_CLOSE, k);
 56         erode(mask, mask, k);
 57         GaussianBlur(mask, mask, Size(3, 3), 0, 0);
 58         //背景替换和混合
 59         Mat result = replace_and_blend(frame, mask);
 60         char c = waitKey(1);
 61         if (c == 27) {
 62             break;
 63         }
 64         imshow(resultWin, result);//显示处理结果video
 65         imshow(title, frame);//显示输入video
 66     }
 67  
 68     waitKey(0);
 69     return 0;
 70 }
 71 //背景替换和混合
 72 Mat replace_and_blend(Mat &frame, Mat &mask) {
 73     Mat result = Mat::zeros(frame.size(), frame.type());
 74     int h = frame.rows;
 75     int w = frame.cols;
 76     int dims = frame.channels();
 77  
 78     // replace and blend
 79     int m = 0;
 80     double wt = 0;
 81  
 82     int r = 0, g = 0, b = 0;
 83     int r1 = 0, g1 = 0, b1 = 0;
 84     int r2 = 0, g2 = 0, b2 = 0;
 85  
 86     for (int row = 0; row < h; row++) {
 87         uchar* current = frame.ptr<uchar>(row);//当前
 88         uchar* bgrow = background_01.ptr<uchar>(row);//背景2
 89         uchar* maskrow = mask.ptr<uchar>(row);//面罩 行
 90         uchar* targetrow = result.ptr<uchar>(row);//目标 行
 91         for (int col = 0; col < w; col++) {
 92             m = *maskrow++;
 93             if (m == 255) { // 赋值为背景
 94                 *targetrow++ = *bgrow++;
 95                 *targetrow++ = *bgrow++;
 96                 *targetrow++ = *bgrow++;
 97                 current += 3;
 98  
 99             } else if(m==0) {// 赋值为前景
100                 *targetrow++ = *current++;
101                 *targetrow++ = *current++;
102                 *targetrow++ = *current++;
103                 bgrow += 3;
104             } else {
105                 b1 = *bgrow++;
106                 g1 = *bgrow++;
107                 r1 = *bgrow++;
108  
109                 b2 = *current++;
110                 g2 = *current++;
111                 r2 = *current++;
112  
113                 // 权重
114                 wt = m / 255.0;
115                 
116                 // 混合
117                 b = b1*wt + b2*(1.0 - wt);
118                 g = g1*wt + g2*(1.0 - wt);
119                 r = r1*wt + r2*(1.0 - wt);
120  
121                 *targetrow++ = b;
122                 *targetrow++ = g;
123                 *targetrow++ = r;
124             }
125         }
126     }
127  
128     return result;
129 }

标签:10,targetrow,Mat,++,绿幕,mask,int,frame,OpenCV3.2
From: https://www.cnblogs.com/ybqjymy/p/17639465.html

相关文章

  • 黑苹果MAC 与 win10 双系统时间不一致(黑苹果系统与windows时间差问题的解决)
    原因分析可能你们都遇到过这样的问题,就是安装完OSX系统以后,发现系统时间和Windows的系统时间就不对了,总是相差了几个小时(刚好8个小时),这个问题的原因呢其实是因为他们看待系统硬件时间的方式不一样引起的,Windows把系统硬件时间当做本地时间,也就是操作系统显示的时间是跟Bios或者Ef......
  • OpenCV3.2图像分割 实例1:读取单张JPG图像(测试环境)
    1#include<opencv2/opencv.hpp>2#include<iostream>34usingnamespacecv;56intmain(intargc,char**argv)7{8Matsrc=imread("toux.jpg");//读取图像9if(src.empty())10{11printf("cou......
  • OpenCV3.2图像分割 实例2:KMeans对随机生成数据进行分类
    1#include<opencv2/opencv.hpp>2#include<iostream>34usingnamespacecv;5usingnamespacestd;67intmain(intargc,char**argv){8Matimg(500,600,CV_8UC3);//定义一张图9RNGrng(12345);//定义随机数10//不同类定义为不同......
  • OpenCV3.2图像分割 实例3:KMeans图像分割
    1#include<opencv2/opencv.hpp>2#include<iostream>34usingnamespacecv;5usingnamespacestd;67intmain(intargc,char**argv){8Matsrc=imread("toux.jpg");9if(src.empty()){10printf(&q......
  • OpenCV3.2图像分割 实例4:GMM(高斯混合模型)样本数据训练与预言
    1#include<opencv2/opencv.hpp>2#include<iostream>34usingnamespacecv;5usingnamespacecv::ml;6usingnamespacestd;78intmain(intargc,char**argv){9Matimg=Mat::zeros(500,500,CV_8UC3);10RNGrng(123......
  • OpenCV3.2图像分割 实例5:GMM(高斯混合模型)图像分割
    1#include<opencv2/opencv.hpp>2#include<iostream>34usingnamespacecv;5usingnamespacecv::ml;6usingnamespacestd;78intmain(intargc,char**argv){9Matsrc=imread("toux.jpg");10if(src.empt......
  • UVA10812 Beat the Spread! 题解
    题目链接思路大家应该都知道绝对值是什么吧?那么,我们不妨直接设\(a\gtb\),这样就省去了一次分类讨论的麻烦,大大降低了程序的复杂度。即可得到此二元一次含参方程组:\[\begin{cases} a+b=s\\ a-b=t\end{cases}\]运用二元一次方程的消元法,解得:\[\begin{cases} a=\frac{s+t}......
  • UVA10678 The Grazing Cow 题解
    题目链接思路一道简单模拟题。经过模拟,我们不难发现,牛的活动轨迹是一个椭圆。根据椭圆形面积公式得到\(S=\piab\)。其中,牛可以到的最左边或最右边时\(a=\frac{l}{2}\),距离中心最远时\(b=\frac{\sqrt{l^2-d^2}}{2}\)。注意有多组测试点,每次都应输出结果并换行。......
  • UVA10684 The jackpot 题解
    题目链接思路一道简单模拟题。用循环模拟每次的处理。对于每次输入的数\(N\),先判断\(N\)的值,如果为\(0\),直接结束程序,避免死循环。否则就依次输入每次赢或输的钱数,再进行集中判断,获取连胜获得的最多钱数,再判断是否连败,输出结果即可。参考代码(请勿抄袭):#include<bits/stdc+......
  • LeetCode 1035.不相交的线
    1.题目:在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足满足: nums1[i]==nums2[j]且绘制的直线不与任何其他连线(非水平线)相交。请注意,连线即使在端点也不能相交:每个数字只......