标签:
刚好手头上有一张证件照,尝试把蓝色底换成红色或白色底,网上搜的资料不多,且大多数都是基于opencv1写的,于是尝试写了下opencv2的。主要步骤为:
1.把RGB图像转换到HSV空间
2.取背景的一小块20*20,计算蓝色背景的平均色调和饱和度
3.设置阈值,取出蓝色背景替换为红色背景
4.把HSV图像转换会RGB空间
5.滤波器去除边缘效应
具体代码为:
// change_color.cpp : 定义控制台应用程序的入口点。
//证件照从蓝色底换成红色底
#include "stdafx.h"
#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
using namespace cv;
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
char *origin="Original";
char *window="Image";
char *str="D:\\jiangshan\\change_color\\IMG_1047.jpg";
namedWindow(origin,1);
namedWindow(window,1);
Mat image=imread(str);
if(!image.data)
{
cout<<"图像载入出现问题"<<endl;
return 0;
}
Mat roi=image(Rect(20,20,20,20));
Mat hsvImg;
cvtColor(image, hsvImg, CV_BGR2HSV); //将图像转换到HSV颜色空间
//分离HSV空间,v[0]为H色调,v[1]为S饱和度,v[2]为v灰度
vector<Mat> 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<uchar>(j,i))+SumH;
SumS=int(roiS.at<uchar>(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<nl; j++)
{
for(int i=0; i<nc; i++)
{
//以H.S两个通道做阈值分割,把蓝色替换成红色
if((v[0].at<uchar>(j,i))<=(avgH+5) && v[0].at<uchar>(j,i)>=(avgH-5)
&&(v[1].at<uchar>(j,i))<=(avgS+40) && v[1].at<uchar>(j,i)>=(avgS-40))
{
//cout<<int(v[0].at<uchar>(j,i))<<endl;
v[0].at<uchar>(j,i)=0;
/*cout<<int(v[0].at<uchar>(j,i))<<endl;*/
}
}
}
Mat finImg;
merge(v,finImg);
Mat rgbImg;
cvtColor(finImg,rgbImg, CV_HSV2BGR); //将图像转换回RGB空间
imshow(origin,image);
imshow(window,rgbImg);
//加个滤波把边缘部分的值滤掉(此处应该用低通滤波器,但感觉不太好,还是不用了。)
//Mat result;
//GaussianBlur(rgbImg,result,Size(3,3),0.5);
/*imshow(window,result);*/
waitKey(0);
//system("pause");
return 0;
}
////遍历整个图像
//int nl=hsvImg.rows;
//int nc=hsvImg.cols * hsvImg.channels();
//for(int j=0; j<nl; j++)
//{
// uchar *data=hsvImg.ptr<uchar>(j);
// for(int i=0; i<nc; i++)
// {
// cout<<int(data[i])<<" ";
// }
//}
标签:
原文地址:http://blog.csdn.net/jiang111_111shan/article/details/46272429