测试图片:
方法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; }