iOS比较两张图的相似度

 1、下载openCV

2、导入openCV的framework

3、导入:

  • opencv2

  • Accelerate

  • AssetsLibrary

  • AVFoundation

  • CoreGraphics

  • CoreImage

  • CoreMedia

  • CoreVideo

  • QuartzCore

  • UIKit

  • Foundation

4、修改配置 accordingtype --->ObjectiveC++

 

#ifdef __cplusplus

#import <opencv2/opencv.hpp>

#endif

 

 

+ (BOOL)isImage:(UIImage *)image1 likeImage:(UIImage *)image2

{

    IplImage *iplimage1 = [self convertToIplImage:image1];

    IplImage *iplimage2 = [self convertToIplImage:image2];

    

    double sililary = [self ComparePPKHist:iplimage1 withParam2:iplimage2];

    

    if (sililary < 0.3) {

        return YES;

    }

    

    return NO;

}

 

+ (double)ComparePPKHist:(IplImage*) srcIpl withParam2:(IplImage*)srcIpl1

{

    if (srcIpl->width==srcIpl1->width && srcIpl->height==srcIpl1->height) {

        return [self CompareHist:srcIpl withParam2:srcIpl1];

    }

    else if (srcIpl->width<srcIpl1->width && srcIpl->height==srcIpl1->height) {

        return [self CompareHistWithSmallWidthIpl:srcIpl withBigWidthIplImg:srcIpl1];

    }

    else if (srcIpl->width>srcIpl1->width && srcIpl->height==srcIpl1->height) {

        return [self CompareHistWithSmallWidthIpl:srcIpl1 withBigWidthIplImg:srcIpl];

    }

    else if (srcIpl->width==srcIpl1->width && srcIpl->height<srcIpl1->height) {

        return [self CompareHistWithSmallHeightIpl:srcIpl withBigHeightIplImg:srcIpl1];

    }

    else if (srcIpl->width==srcIpl1->width && srcIpl->height>srcIpl1->height) {

        return [self CompareHistWithSmallHeightIpl:srcIpl1 withBigHeightIplImg:srcIpl];

    }

    else if (srcIpl->width<srcIpl1->width && srcIpl->height<srcIpl1->height) {

        return [self CompareHistWithSmallIpl:srcIpl withBigIplImg:srcIpl1];

    }

    else if (srcIpl->width>srcIpl1->width && srcIpl->height>srcIpl1->height)

    {

        return [self CompareHistWithSmallIpl:srcIpl1 withBigIplImg:srcIpl];

    }

    

    return 1.f;

}

 

+ (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;

}

iOS比较两张图的相似度,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。