C++中如何使用OpenCV实现证件照蓝底换成白底功能

这篇文章主要介绍了C++中如何使用OpenCV实现证件照蓝底换成白底功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

创新互联建站专注于企业营销型网站建设、网站重做改版、昆玉网站定制设计、自适应品牌网站建设、H5建站商城建设、集团公司官网建设、成都外贸网站建设公司、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为昆玉等各大城市提供网站开发制作服务。

主要步骤为:

1.把RGB图像转换到HSV空间

2.取背景的一小块20*20,计算蓝色背景的平均色调和饱和度

3.设置阈值,取出蓝色背景替换为红色背景

4.把HSV图像转换会RGB空间

5.滤波器去除边缘效应

具体代码为:

// change_color.cpp : 定义控制台应用程序的入口点。//证件照从蓝色底换成红色底//#include "stdafx.h"#include #include #include #include using namespace cv;using namespace std;int main(){    char *origin="Original";    char *window="Image";    char *str="C:\\Users\\ltc\\Desktop\\nihao.jpg";    namedWindow(origin,1);    namedWindow(window,1);    Mat image=imread(str);    if(!image.data)    {        cout<<"图像载入出现问题"< v;    split(hsvImg,v);    Mat roiH=v[0](Rect(20,20,20,20));    Mat roiS=v[1](Rect(20,20,20,20));    int SumH=0;    int SumS=0;    int avgH, avgS;//蓝底的平均色调和平均饱和度    //取一块蓝色背景,计算出它的平均色调和平均饱和度    for(int i=0; i<20; i++)    {        for(int j=0; j<20; j++)        {            /*SumH=SumH+roiH(i,j);*/            SumH=int(roiH.at(j,i))+SumH;            SumS=int(roiS.at(j,i))+SumS;        }    }    avgH=SumH/400;    avgS=SumS/400;    //遍历整个图像    int nl=hsvImg.rows;    int nc=hsvImg.cols;    int step=10;    for(int j=0; j(j,i))<=(avgH+5) && v[0].at(j,i)>=(avgH-5)                &&(v[1].at(j,i))<=(avgS+40) && v[1].at(j,i)>=(avgS-40))            {                //cout<(j,i))<(j,i)=0;                //白色底                v[0].at(j,i)=0;                v[1].at(j,i)=0; //V[0]和V[1]全调成0就是变成白色                //绿色底                //v[0].at(j,i)=60;                //蓝色底                //v[0].at(j,i)=120;                /*cout<(j,i))<(j);//    for(int i=0; i

这里面主要说明一下:

HSV模型

倒锥形模型:

这个模型就是按色彩、深浅、明暗来描述的。

H是色彩

S是深浅, S = 0时,只有灰度

V是明暗,表示色彩的明亮程度,但与光强无直接联系,(意思是有一点点联系吧)。

在这个程序里

色调主要是由V[0]来控制的

hsv是一个360度的模型 每个角度代表一种颜色

0度是红色

120度是绿色

240度是蓝色

但是OpenCV里最大值是255 所以它会对色调除以2,就是最大值是180

绿色对应的让它等于60 蓝色对应的就是120

换不同的背景只需要改动:

//红色底v[0].at(j,i)=0;//白色底v[0].at(j,i)=0;v[1].at(j,i)=0; //V[0]和V[1]全调成0就是变成白色//绿色底v[0].at(j,i)=60;//蓝色底v[0].at(j,i)=120;

改动的位置就不需要说明了吧!这个方法的效果确实不错,大赞!

毕竟是老师的图片,不能轻易放出来,网上的也不能随便用吧!哈哈

那就放张我最爱的崩坏3吧!

附录

提取图像中指定颜色的像素区域

#include#include#include#includeusing namespace cv;class ColorDetector{private:    //最小可接受距离    int minDist;    //目标色    cv::Vec3b target;    //结果图像    cv::Mat result;//计算与目标颜色的距离int getDistance(cv::Vec3b color){    return abs(color[0] - target[0]) + abs(color[1] - target[1]) + abs(color[2] - target[2]);}public:    //空构造函数    ColorDetector() :minDist(100)    {    //初始化默认参数    target[0] = target[1] = target[2] = 0;    }    void setColorDistanceThreshold(int distance);    int getColorDistanceThreshold() const;    void setTargetColor(unsigned char red, unsigned char green, unsigned char blue);    void setTargetColor(cv::Vec3b color);    cv::Vec3b getTargetColor() const;    cv::Mat ColorDetector::process(const cv::Mat &image);    };//设置色彩距离阈值,阈值必须是正的,否则设为0void ColorDetector::setColorDistanceThreshold(int distance){    if (distance < 0)    distance = 0;    minDist = distance;}//获取色彩距离阈值int ColorDetector::getColorDistanceThreshold() const{    return minDist;}//设置需检测的颜色void ColorDetector::setTargetColor(unsigned char red, unsigned char green, unsigned char blue){    //BGR顺序    target[2] = red;    target[1] = green;    target[0] = blue;}//设置需检测的颜色void ColorDetector::setTargetColor(cv::Vec3b color){    target = color;}//获取需检测的颜色cv::Vec3b ColorDetector::getTargetColor() const{    return target;}cv::Mat ColorDetector::process(const cv::Mat &image)//核心的处理方法{    //按需重新分配二值图像    //与输入图像的尺寸相同,但是只有一个通道    result.create(image.rows, image.cols, CV_8U);    //得到迭代器    cv::Mat_::const_iterator it = image.begin();    cv::Mat_::const_iterator itend = image.end();    cv::Mat_::iterator itout = result.begin();    for (; it != itend; ++it, ++itout)//处理每个像素    {        //计算离目标颜色的距离        if (getDistance(*it) < minDist)        {            *itout = 255;        }        else        {            *itout = 0;        }    }        return result;}int _tmain(int argc, _TCHAR* argv[]){    //1.创建图像处理的对象    ColorDetector cdetect;    //2.读取输入图像    cv::Mat image = cv::imread("boldt.jpg");    if (!image.data)    {        return 0;    }    //3.设置输入参数    cdetect.setTargetColor(130, 190, 230);//蓝天的颜色    cv::namedWindow("result");    //4.处理并显示结果    cv::imshow("result", cdetect.process(image));    cv::waitKey();    return 0;}

感谢你能够认真阅读完这篇文章,希望小编分享的“C++中如何使用OpenCV实现证件照蓝底换成白底功能”这篇文章对大家有帮助,同时也希望大家多多支持创新互联,关注创新互联行业资讯频道,更多相关知识等着你来学习!


分享名称:C++中如何使用OpenCV实现证件照蓝底换成白底功能
当前链接:http://myzitong.com/article/iihhoj.html