测试图片:
方法1:
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
/*
*
*
*opencvchina.com每周一练第十三期
*
*作者:opencvchina.com会员 ---> zhongguo
*/
void getAverage(IplImage* image,float* avg);
//计算图像sampleImageName hsv三个通道的均值
//hSampleAvg:h通道的均值
//sSampleAvg:s通道的均值
//vSampleAvg:v通道的均值
void init(char* sampleImageName , float* hSampleAvg , float* sSampleAvg, float* vSampleAvg)
{
IplImage *srcColor;
srcColor = cvLoadImage(sampleImageName,CV_LOAD_IMAGE_COLOR);
if(!srcColor)
{
printf("fail to load Image \n");
exit(0);
}
IplImage* hsvFloat = cvCreateImage(cvGetSize(srcColor),32,3);
IplImage* srcColorFloat = cvCreateImage(cvGetSize(srcColor),32,3);
cvConvertScale(srcColor,srcColorFloat);
cvCvtColor(srcColorFloat,hsvFloat,CV_BGR2HSV);
IplImage* h = cvCreateImage(cvGetSize(srcColor),32,1);
IplImage* s = cvCreateImage(cvGetSize(srcColor),32,1);
IplImage* v = cvCreateImage(cvGetSize(srcColor),32,1);
cvSplit(hsvFloat,h,s,v,NULL);
getAverage(h,hSampleAvg);
getAverage(s,sSampleAvg);
getAverage(v,vSampleAvg);
cvReleaseImage(&srcColor);
cvReleaseImage(&hsvFloat);
cvReleaseImage(&srcColorFloat);
cvReleaseImage(&h);
cvReleaseImage(&s);
cvReleaseImage(&v);
}
//计算图像的均值
void getAverage(IplImage* image,float* avg)
{
int x,y;
float sum = 0 ;
for(y=0;y<image->height;y++)
for(x=0;x<image->width;x++)
{
float value = cvGetReal2D(image,y,x);
sum = sum + value;
}
*avg = sum/(float)(image->height*image->width);
}
int main(int argc, char* argv[])
{
float hSampleAvg , sSampleAvg, vSampleAvg , minH,maxH,disH;
//加载样本图片 并计算hsv三个通道的均值
init("sample1.jpg" , &hSampleAvg , &sSampleAvg, &vSampleAvg);
IplImage *srcColor , *hsvFloat ,*srcColorFloat,*h,*s,*v;
//加载样本证件照图像
srcColor = cvLoadImage("1.jpg",CV_LOAD_IMAGE_COLOR);
if(!srcColor)
{
printf("fail to load image\n");
return 0;
}
hsvFloat = cvCreateImage(cvGetSize(srcColor),32,3);
srcColorFloat = cvCreateImage(cvGetSize(srcColor),32,3);
cvConvertScale(srcColor,srcColorFloat);
//颜色空间转换 BGR-->HSV
cvCvtColor(srcColorFloat,hsvFloat,CV_BGR2HSV);
h = cvCreateImage(cvGetSize(srcColor),32,1);
s = cvCreateImage(cvGetSize(srcColor),32,1);
v = cvCreateImage(cvGetSize(srcColor),32,1);
//分离h s v三个通道
cvSplit(hsvFloat,h,s,v,NULL);
for(int y=0;y<hsvFloat->height;y++)
{
for(int x=0;x<hsvFloat->width;x++)
{
float hValue = cvGetReal2D(h,y,x);
float sValue = cvGetReal2D(s,y,x);
float vValue = cvGetReal2D(v,y,x);
minH = hValue < hSampleAvg ? hValue : hSampleAvg ;
maxH = hValue > hSampleAvg ? hValue : hSampleAvg ;
disH = MIN(maxH-minH,360-maxH+minH);
//与样本图像的h s v三个通道的均值比较
if((fabs(sValue-sSampleAvg)<0.2) && disH<40 && (fabs(vValue - vSampleAvg)<40))
{
cvSet2D(srcColor,y,x,cvScalar(255,255,255,0));
}
}
}
//显示证件照图像
cvNamedWindow("src");
cvShowImage("src",srcColor);
cvWaitKey(0);
//释放图像资源
cvReleaseImage(&srcColor);
cvReleaseImage(&hsvFloat);
cvReleaseImage(&srcColorFloat);
cvReleaseImage(&h);
cvReleaseImage(&s);
cvReleaseImage(&v);
return 0;
}
方法2:
#include "cv.h"
#include "highgui.h"
#include <iostream>
using namespace std;
/*
*
*
*opencvchina.com每周一练第十三期
*
*作者:opencvchina.com会员 ---> JL2012JL
*/
int main()
{
IplImage*src=cvLoadImage("people.jpg");
cvNamedWindow("cr");
IplImage*ycrcb=cvCloneImage(src);
IplImage*crdst=cvCloneImage(src);
IplImage*s1=cvCreateImage(cvGetSize(src),8,1);
cvCvtColor(src,ycrcb,CV_BGR2YCrCb);
cvSplit(ycrcb,NULL,s1,NULL,NULL);
int crh=255;
int crl=115;
cvCreateTrackbar("crh","cr",&crh,256,NULL);
cvCreateTrackbar("crl","cr",&crl,256,NULL);
cvShowImage("cr",s1);
cvShowImage("src",src);
while(1)
{
cvSplit(ycrcb,NULL,s1,NULL,NULL);
cvInRangeS(s1,cvScalarAll(crl),cvScalarAll(crh),s1);
cvDilate(s1,s1);
cvErode(s1,s1);
cvZero(crdst);
cvCopy(src,crdst,s1);
cvShowImage("crdst",crdst);
if(cvWaitKey(10)==27)break;
}
cvNot(s1,s1);
cvSet(crdst,cvScalarAll(255),s1);
cvShowImage("dst",crdst);
cvWaitKey(0);
cvDestroyWindow("cr");
cvReleaseImage(&src);
cvReleaseImage(&ycrcb);
cvReleaseImage(&s1);
cvReleaseImage(&crdst);
return 0;
}