您的位置:首页 > 移动开发 > IOS开发

ios--OpenCV--cvCompareHist使用直方图模型(CvHistogram)比对两张图片

2014-04-10 11:13 736 查看
此方法使用直方图模型比对两张图片,如果两张图片一模一样的话,结果为0.00;比对的结果越小,图片相似性越高;

适用于比较两张尺寸大小一致的图片,对于大小不一致的图片,只能比较其相似性;

-(double)CompareHist:(IplImage*)image1 withParam2:(IplImage*)image2
{
int hist_size = 256;
float range[] = {0,255};

IplImage *gray_plane = cvCreateImage(cvGetSize(image1), 8, 1);
cvCvtColor(image1, gray_plane, CV_BGR2GRAY);
CvHistogram *gray_hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY);
cvCalcHist(&gray_plane, gray_hist);

IplImage *gray_plane2 = cvCreateImage(cvGetSize(image2), 8, 1);
cvCvtColor(image2, gray_plane2, CV_BGR2GRAY);
CvHistogram *gray_hist2 = cvCreateHist(1, &hist_size, CV_HIST_ARRAY);
cvCalcHist(&gray_plane2, gray_hist2);

return cvCompareHist(gray_hist, gray_hist2, CV_COMP_BHATTACHARYYA);
}


以下的方法是比较两个尺寸大小不一样的图片:

#import "UIImage+OpenCV.h"

#import "MyViewController.h"
#import <opencv2/highgui/ios.h>
#import <opencv2/imgproc/imgproc_c.h>
#import <opencv2/core/core_c.h>
#import <opencv2/features2d/features2d.hpp>
#import <opencv2/nonfree/features2d.hpp>

// Aperture value to use for the Canny edge detection
const int kCannyAperture = 7;

@interface MyViewController ()
- (void)processFrame;
@end

@implementation MyViewController

@synthesize imageView = _imageView;
@synthesize imageView1 = _imageView1;

- (void)viewDidLoad
{
[super viewDidLoad];

//[self TakeColorFromImageHSV];
UIImage *mImage = [UIImage imageNamed:@"防伪标签005.jpg"];
//self.imageView.image = mImage;
IplImage *srcIpl = [self convertToIplImage:mImage];
IplImage *dscIpl = cvCreateImage(cvGetSize(srcIpl), srcIpl->depth, 1);
[self SkinDetect:srcIpl withParam:dscIpl];
IplImage *dscIplNew = cvCreateImage(cvGetSize(srcIpl), IPL_DEPTH_8U, 3);
cvCvtColor(dscIpl, dscIplNew, CV_GRAY2BGR);
//self.imageView.image = [self convertToUIImage:dscIplNew];
self.imageView.image = mImage;

UIImage *mImage1 = [UIImage imageNamed:@"防伪标签004.jpg"];
//self.imageView1.image = mImage1;
IplImage *srcIpl1 = [self convertToIplImage:mImage1];
IplImage *dscIpl1 = cvCreateImage(cvGetSize(srcIpl1), srcIpl1 ->depth, 1);
[self SkinDetect:srcIpl1 withParam:dscIpl1];
IplImage *dscIplNew1 = cvCreateImage(cvGetSize(srcIpl1), IPL_DEPTH_8U, 3);
cvCvtColor(dscIpl1, dscIplNew1, CV_GRAY2BGR);
//self.imageView1.image = [self convertToUIImage:dscIplNew1];

[self ComparePPKHist:srcIpl withParam2:srcIpl1];
}

-(void)ComparePPKHist:(IplImage*) srcIpl withParam2:(IplImage*)srcIpl1
{
if (srcIpl->width==srcIpl1->width && srcIpl->height==srcIpl1->height) {
printf("匹配结果为:%f\n",[self CompareHist:srcIpl withParam2:srcIpl1]);
}
else if (srcIpl->width<srcIpl1->width && srcIpl->height==srcIpl1->height) {
printf("匹配结果为:%f\n",[self CompareHistWithSmallWidthIpl:srcIpl withBigWidthIplImg:srcIpl1]);
}
else if (srcIpl->width>srcIpl1->width && srcIpl->height==srcIpl1->height) {
printf("匹配结果为:%f\n",[self CompareHistWithSmallWidthIpl:srcIpl1 withBigWidthIplImg:srcIpl]);
}
else if (srcIpl->width==srcIpl1->width && srcIpl->height<srcIpl1->height) {
printf("匹配结果为:%f\n",[self CompareHistWithSmallHeightIpl:srcIpl withBigHeightIplImg:srcIpl1]);
}
else if (srcIpl->width==srcIpl1->width && srcIpl->height>srcIpl1->height) {
printf("匹配结果为:%f\n",[self CompareHistWithSmallHeightIpl:srcIpl1 withBigHeightIplImg:srcIpl]);
}
else if (srcIpl->width<srcIpl1->width && srcIpl->height<srcIpl1->height) {
printf("匹配结果为:%f\n",[self CompareHistWithSmallIpl:srcIpl withBigIplImg:srcIpl1]);
}
else if (srcIpl->width>srcIpl1->width && srcIpl->height>srcIpl1->height)
{
printf("匹配结果为:%f\n",[self CompareHistWithSmallIpl:srcIpl1 withBigIplImg:srcIpl]);
}
}

-(double)CompareHistWithSmallWidthIpl:(IplImage*)srcIpl withBigWidthIplImg:(IplImage*)srcIpl1
{
//当前匹配结果,越接近于0.0匹配度越高
double dbRst=1.0;
//匹配结果,-1表示正在匹配,0表示匹配失败,1表示匹配成功
int tfFound = -1;
//裁剪后的图片
IplImage *cropImage;
for (int j=0; j<srcIpl1->width-srcIpl->width; j++)
{
//裁剪图片
cvSetImageROI(srcIpl1, cvRect(j, 0, srcIpl->width, srcIpl->height));
cropImage = cvCreateImage(cvGetSize(srcIpl), IPL_DEPTH_8U, 3);
cvCopy(srcIpl1, cropImage);
cvResetImageROI(srcIpl1);
//匹配图片
double dbRst1 =[self CompareHist:srcIpl withParam2:cropImage];
printf("匹配结果为:%f\n",dbRst1);
if (dbRst1<=0.01)
{
//匹配成功
tfFound = 1;
break;
}
else if(dbRst==1.0 || dbRst1<dbRst)
{
//本次匹配有进步,更新结果
cvReleaseImage(&cropImage);
dbRst = dbRst1;
}
else if(dbRst1>dbRst)
{
cvReleaseImage(&cropImage);
}
}
return dbRst;
}

-(double)CompareHistWithSmallHeightIpl:(IplImage*)srcIpl withBigHeightIplImg:(IplImage*)srcIpl1
{
//当前匹配结果,越接近于0.0匹配度越高
double dbRst=1.0;
//匹配结果,-1表示正在匹配,0表示匹配失败,1表示匹配成功
int tfFound = -1;
//裁剪后的图片
IplImage *cropImage;
for (int j=0; j<srcIpl1->height-srcIpl->height; j++)
{
//裁剪图片
cvSetImageROI(srcIpl1, cvRect(0, j, srcIpl->height, srcIpl->height));
cropImage = cvCreateImage(cvGetSize(srcIpl), IPL_DEPTH_8U, 3);
cvCopy(srcIpl1, cropImage);
cvResetImageROI(srcIpl1);
//匹配图片
double dbRst1 =[self CompareHist:srcIpl withParam2:cropImage];
printf("匹配结果为:%f\n",dbRst1);
if (dbRst1<=0.01)
{
//匹配成功
tfFound = 1;
break;
}
else if(dbRst==1.0 || dbRst1<dbRst)
{
//本次匹配有进步,更新结果
cvReleaseImage(&cropImage);
dbRst = dbRst1;
}
else if(dbRst1>dbRst)
{
cvReleaseImage(&cropImage);
}
}
return dbRst;
}

-(double)CompareHistWithSmallIpl:(IplImage*)srcIpl withBigIplImg:(IplImage*)srcIpl1
{
//当前匹配结果,越接近于0.0匹配度越高
double dbRst=1.0;
//水平、竖直偏移量
int xSub=0,ySub=0;
//匹配结果,-1表示正在匹配,0表示匹配失败,1表示匹配成功
int tfFound = -1;
//裁剪后的图片
IplImage *cropImage;
//遍历方式:先竖后横
for (int j=0; j<srcIpl1->width-srcIpl->width; j++)
{
for (int i=ySub; i<srcIpl1->height-srcIpl->height; i++)
{
//裁剪图片
cvSetImageROI(srcIpl1, cvRect(j, i, srcIpl->width, srcIpl->height));
cropImage = cvCreateImage(cvGetSize(srcIpl), IPL_DEPTH_8U, 3);
cvCopy(srcIpl1, cropImage);
cvResetImageROI(srcIpl1);
//匹配图片
double dbRst1 =[self CompareHist:srcIpl withParam2:cropImage];
printf("(x=%d,y=%d),竖直匹配结果为:%f\n",j,i,dbRst1);
if (dbRst1<=0.0375)
{
//匹配成功
tfFound = 1;
break;
}
else if(dbRst==1.0 || dbRst1<dbRst)
{
//本次匹配有进步,更新结果
cvReleaseImage(&cropImage);
dbRst = dbRst1;
}
else if(dbRst1>dbRst)
{
cvReleaseImage(&cropImage);
//竖直移动到点了,该水平移动了
ySub = i-1;
for (int k=j+1;k<srcIpl1->width-srcIpl->width; k++)
{
//裁切图片
cvSetImageROI(srcIpl1, cvRect(k, i, srcIpl->width, srcIpl->height));
cropImage = cvCreateImage(cvGetSize(srcIpl), IPL_DEPTH_8U, 3);
cvCopy(srcIpl1, cropImage);
cvResetImageROI(srcIpl1);
//匹配图片
double dbRst1 =[self CompareHist:srcIpl withParam2:cropImage];
printf("(x=%d,y=%d),水平移动匹配结果为:%f\n",k,i,dbRst1);
if (dbRst1<=0.0375)
{
//匹配成功
tfFound = 1;
xSub = k;
break;
}
else if(dbRst1<dbRst)
{
//本次匹配有进步,更新结果
cvReleaseImage(&cropImage);
xSub = k;
j = xSub;
dbRst = dbRst1;
}
else
{
cvReleaseImage(&cropImage);
xSub = k;
j = xSub;
break;
}
}
}
if (tfFound==1 || tfFound==0) {
break;
}
}
if (tfFound==1 || tfFound==0) {
break;
}
}
return dbRst;
}

// 多通道彩色图片的直方图比对
-(double)CompareHist:(IplImage*)image1 withParam2:(IplImage*)image2 { int hist_size = 256; float range[] = {0,255}; IplImage *gray_plane = cvCreateImage(cvGetSize(image1), 8, 1); cvCvtColor(image1, gray_plane, CV_BGR2GRAY); CvHistogram *gray_hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY); cvCalcHist(&gray_plane, gray_hist); IplImage *gray_plane2 = cvCreateImage(cvGetSize(image2), 8, 1); cvCvtColor(image2, gray_plane2, CV_BGR2GRAY); CvHistogram *gray_hist2 = cvCreateHist(1, &hist_size, CV_HIST_ARRAY); cvCalcHist(&gray_plane2, gray_hist2); return cvCompareHist(gray_hist, gray_hist2, CV_COMP_BHATTACHARYYA); }

// 单通道彩色图片的直方图
-(double)CompareHistSignle:(IplImage*)image1 withParam2:(IplImage*)image2
{
int hist_size = 256;
float range[] = {0,255};

CvHistogram *gray_hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY);
cvCalcHist(&image1, gray_hist);

CvHistogram *gray_hist2 = cvCreateHist(1, &hist_size, CV_HIST_ARRAY);
cvCalcHist(&image2, gray_hist2);

return cvCompareHist(gray_hist, gray_hist2, CV_COMP_BHATTACHARYYA);
}

// 进行肤色检测
-(void)SkinDetect:(IplImage*)src withParam:(IplImage*)dst
{
// 创建图像头
IplImage* hsv = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3);//用于存图像的一个中间变量,是用来分通道用的,分成hsv通道
IplImage* tmpH1 = cvCreateImage( cvGetSize(src), IPL_DEPTH_8U, 1);//通道的中间变量,用于肤色检测的中间变量
IplImage* tmpS1 = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
IplImage* tmpH2 = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
IplImage* tmpS2 = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
IplImage* tmpH3 = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
IplImage* tmpS3 = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);
IplImage* H = cvCreateImage( cvGetSize(src), IPL_DEPTH_8U, 1);
IplImage* S = cvCreateImage( cvGetSize(src), IPL_DEPTH_8U, 1);
IplImage* V = cvCreateImage( cvGetSize(src), IPL_DEPTH_8U, 1);
IplImage* src_tmp1=cvCreateImage(cvGetSize(src),8,3);

// 高斯模糊
cvSmooth(src,src_tmp1,CV_GAUSSIAN,3,3); //高斯模糊

// hue色度,saturation饱和度,value纯度
cvCvtColor(src_tmp1, hsv, CV_BGR2HSV );//颜色转换
cvSplit(hsv,H,S,V,0);//分为3个通道
/*********************肤色检测部分**************/
cvInRangeS(H,cvScalar(0.0,0.0,0,0),cvScalar(20.0,0.0,0,0),tmpH1);
cvInRangeS(S,cvScalar(75.0,0.0,0,0),cvScalar(200.0,0.0,0,0),tmpS1);
cvAnd(tmpH1,tmpS1,tmpH1,0);

// Red Hue with Low Saturation
// Hue 0 to 26 degree and Sat 20 to 90
cvInRangeS(H,cvScalar(0.0,0.0,0,0),cvScalar(13.0,0.0,0,0),tmpH2);
cvInRangeS(S,cvScalar(20.0,0.0,0,0),cvScalar(90.0,0.0,0,0),tmpS2);
cvAnd(tmpH2,tmpS2,tmpH2,0);

// Red Hue to Pink with Low Saturation
// Hue 340 to 360 degree and Sat 15 to 90
cvInRangeS(H,cvScalar(170.0,0.0,0,0),cvScalar(180.0,0.0,0,0),tmpH3);
cvInRangeS(S,cvScalar(15.0,0.0,0,0),cvScalar(90.,0.0,0,0),tmpS3);
cvAnd(tmpH3,tmpS3,tmpH3,0);

// Combine the Hue and Sat detections
cvOr(tmpH3,tmpH2,tmpH2,0);
cvOr(tmpH1,tmpH2,tmpH1,0);

cvCopy(tmpH1,dst);

cvReleaseImage(&hsv);
cvReleaseImage(&tmpH1);
cvReleaseImage(&tmpS1);
cvReleaseImage(&tmpH2);
cvReleaseImage(&tmpS2);
cvReleaseImage(&tmpH3);
cvReleaseImage(&tmpS3);
cvReleaseImage(&H);
cvReleaseImage(&S);
cvReleaseImage(&V);
cvReleaseImage(&src_tmp1);
}

/// UIImage类型转换为IPlImage类型
-(IplImage*)convertToIplImage:(UIImage*)image
{
CGImageRef imageRef = image.CGImage;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
IplImage *iplImage = cvCreateImage(cvSize(image.size.width, image.size.height), IPL_DEPTH_8U, 4);
CGContextRef contextRef = CGBitmapContextCreate(iplImage->imageData, iplImage->width, iplImage->height, iplImage->depth, iplImage->widthStep, colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault);
CGContextDrawImage(contextRef, CGRectMake(0, 0, image.size.width, image.size.height), imageRef);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace);
IplImage *ret = cvCreateImage(cvGetSize(iplImage), IPL_DEPTH_8U, 3);
cvCvtColor(iplImage, ret, CV_RGB2BGR);
cvReleaseImage(&iplImage);
return ret;
}

/// IplImage类型转换为UIImage类型
-(UIImage*)convertToUIImage:(IplImage*)image
{
cvCvtColor(image, image, CV_BGR2RGB);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSData *data = [NSData dataWithBytes:image->imageData length:image->imageSize];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)data);
CGImageRef imageRef = CGImageCreate(image->width, image->height, image->depth, image->depth * image->nChannels, image->widthStep, colorSpace, kCGImageAlphaNone | kCGBitmapByteOrderDefault, provider, NULL, false, kCGRenderingIntentDefault);
UIImage *ret = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return ret;
}

- (void)viewDidUnload
{
[super viewDidUnload];
self.imageView = nil;
self.imageView1=nil;

delete _videoCapture;
_videoCapture = nil;
}

@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: