1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Opencv -- 12图像色彩空间转换应用 -- 给证件照换颜色背景

Opencv -- 12图像色彩空间转换应用 -- 给证件照换颜色背景

时间:2020-01-20 05:50:50

相关推荐

Opencv -- 12图像色彩空间转换应用 -- 给证件照换颜色背景

应用:给证件照换颜色背景

利用HSV中的常见色彩区分度比RGB中的色彩区分度更明显的优势,再结合inRange()函数可以将图片中不同的颜色给提取出来。

openCV中的HSV颜色体系

使用 OpenCV 中的 cvtColor 函数,并设置参数为CV_BGR2HSV,那么所得的H、S、V值范围分别是[0,180),[0,255),[0,255),这时我们可以查下面的表格来确定颜色的大致区间。

inRange()函数

OpenCV中的inRange()函数可实现二值化功能(这点类似threshold()函数),更关键的是可以同时针对多通道进行操作,使用起来非常方便!主要是将在两个阈值内的像素值设置为白色(255),而不在阈值区间内的像素值设置为黑色(0)。

要特别注意的是:该函数输出的是一幅二值化之后的图像。

程序如下:

#include <iostream>#include "12_opencv_mat.h"using namespace std;void QuickDemo::inrange_demo(Mat &image){Mat hsv = Mat::zeros(image.size(), image.type());//我们这里输入的是一张白底图像cvtColor(image,hsv,COLOR_BGR2HSV);/** inRange* 函数功能:* inRange()函数可实现二值化功能(这点类似threshold()函数),* 更关键的是可以同时针对多通道进行操作,使用起来非常方便!* 主要是将在两个阈值内的像素值设置为白色(255),而不在阈值区间内的像素值设置为黑色(0)。* * void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst)* * 参数1:输入要处理的图像,可以为单通道或多通道。*参数2:包含下边界(最小值)的数组或标量。* 参数3:包含上边界(最大值)的数组或标量。* 参数4:输出图像,与输入图像src其大小和通道数量且为 CV_8U 类型。* * 要特别注意的是:该函数输出的DST是一幅二值化之后的图像。*/Mat mask;inRange(hsv, Scalar(0,0,221), Scalar(180,30,255), mask);//注意集合的开闭imshow("输出图像", mask);}

运行程序:

理论上,输入图像中除了白色部分都应该变成黑色。但从输入图像和输出图像对比来看,输入图像中的左半部分的颜色有点偏粉红并没有被识别出来。所以这种处理有些粗糙。

下面程序要求弄懂对mask的理解。

12_opencv_mat.h

#pragma once#ifndef _12_OPENCV_MAT_H#define _12_OPENCV_MAT_H#include <opencv2/opencv.hpp>using namespace cv;class QuickDemo {public:void inrange_demo(Mat& image);};#endif

12_opencv_mat.cpp

#include <iostream>#include "12_opencv_mat.h"using namespace std;void QuickDemo::inrange_demo(Mat &image){Mat hsv = Mat::zeros(image.size(), image.type());cvtColor(image,hsv,COLOR_BGR2HSV);/** inRange* 函数功能:* inRange()函数可实现二值化功能(这点类似threshold()函数),* 更关键的是可以同时针对多通道进行操作,使用起来非常方便!* 主要是将在两个阈值内的像素值设置为白色(255),而不在阈值区间内的像素值设置为黑色(0)。* * void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst)* * 参数1:输入要处理的图像,可以为单通道或多通道。*参数2:包含下边界(最小值)的数组或标量。* 参数3:包含上边界(最大值)的数组或标量。* 参数4:输出图像,与输入图像src其大小和通道数量且为 CV_8U 类型。* * 要特别注意的是:该函数输出是一幅二值化之后的图像。*/Mat mask;//我们这里输入的是一张白底图像inRange(hsv, Scalar(0,0,221), Scalar(180,30,255), mask);//注意集合的开闭//mask中白色背景的值为255,人物部分的值为0//创建一个空白图像Mat redback = Mat::zeros(image.size(), image.type());redback = Scalar(22,22,222);//红色bitwise_not(mask,mask);//此时mask中白色背景的值为0,人物部分的值为255/** copyTo的函数功能:将输入图像复制到输出图像。*copyTo是图像(Mat)对象的成员方法,有两种*void Mat::copyTo(OutputArray m)* 和* void Mat::copyTo(OutputArray m, InputArray mask)* * 参数:* m – 输出图像。 如果在操作之前它没有适当的大小或类型,则重新分配它。* mask – 掩码操作(标记操作). 它的非零元素表示需要复制哪些矩阵元素。* * 使用第二个函数时必须要提供mask参数,没有不能写NULL,否则程序报错。*//*该函数把输入图像(数组)image中被选中的(mask不为0对应的部分)元素拷贝到输出图像(redback)中,需要注意的是mask是一个和dst or src大小完全一致的数组(图像)。*/image.copyTo(redback,mask);/** 能够进行下述操作的前提是,mask是一个和dst or src大小完全一致的数组(图像)。if (mask(I) ! = 0)dst(I) = src(I);elsedst(I) = dst(I);*/imshow("输出图像", redback);}

main.cpp

#include <iostream>#include "12_opencv_mat.h"using namespace std;int main(int argc,char** argv){//使用Mat(matrix -- 矩阵)这种类型来读取通过指定路径的图像信息并存放到变量picture中。//图像从本质上来说都是二维的数组(矩阵)Mat picture = imread("鱼头人.jpeg", IMREAD_COLOR);if (picture.empty()){cout << "could not Load image." << endl;system("pause");return -1;}// namedWindow("输入窗口",WINDOW_FREERATIO);imshow("输入窗口", picture);QuickDemo qd;qd.inrange_demo(picture);waitKey(0);destroyAllWindows();system("pause");return 0;}

最后运行结果如下:

可以看出来处理后的结果非常粗糙,这种方式只适合背景与人物颜色相差非常明显(区分度很大)的图像的处理。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。