iOS,OC,圖片相似度比較,圖片指紋


上周,正在忙,突然有個同學找我幫忙,說有個需求:圖片相似度比較。

網上搜了一下,感覺不是很難,就寫了下,這里分享給需要的小伙伴。

首先,本次采用的是OpenCV,圖片哈希值:

先說一下基本思路:

1.      縮小尺寸:將圖像縮小到8*8的尺寸,總共64個像素。這一步的作用是去除圖像的細節,只保留結構/明暗等基本信息,摒棄不同尺寸/比例帶來的圖像差異;

注:實際操作時,采取了兩種尺寸作對比(10*10,100*100)尺寸再大的話就會性能影響就會較大了,我實現了兩種,目的是為了展示怎么設定不同尺寸。

2.      簡化色彩:將縮小后的圖像,轉為64級灰度,即所有像素點總共只有64種顏色;

注:關於多少灰度級的問題,我並沒有太在意,采取了一個合適的RGB to GRAY 算法就好,個人理解

3.      計算平均值:計算所有64個像素的灰度平均值;

4.      比較像素的灰度:將每個像素的灰度,與平均值進行比較,大於或等於平均值記為1,小於平均值記為0;

5.      計算哈希值:將上一步的比較結果,組合在一起,就構成了一個64位的整數,這就是這張圖像的指紋。組合的次序並不重要,只要保證所有圖像都采用同樣次序就行了;

6.      得到指紋以后,就可以對比不同的圖像

參考博客:http://blog.csdn.net/fengbingchun/article/details/42153261

 

類文件下載鏈接:http://files.cnblogs.com/files/kongkaikai/GetSimilarity.zip

GetSimilarity.h

 1 //
 2 //  GetSimilarity.h
 3 //  imgsimlartest
 4 //
 5 //  Created by test on 16/3/3.
 6 //  Copyright © 2016年 com.facishare.CoreTest. All rights reserved.
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 #import <UIKit/UIKit.h>
11 typedef double Similarity;
12 
13 @interface GetSimilarity : NSObject
14 - (void)setImgWithImgA:(UIImage*)imgA ImgB:(UIImage*)imgB;//設置需要對比的圖片
15 - (void)setImgAWidthImg:(UIImage*)img;
16 - (void)setImgBWidthImg:(UIImage*)img;
17 - (Similarity)getSimilarityValue; //獲取相似度
18 + (Similarity)getSimilarityValueWithImgA:(UIImage*)imga ImgB:(UIImage*)imgb;//類方法
19 @end

GetSimilarity.m

  1 //
  2 //  GetSimilarity.m
  3 //  imgsimlartest
  4 //
  5 //  Created by test on 16/3/3.
  6 //  Copyright © 2016年 com.facishare.CoreTest. All rights reserved.
  7 //
  8 
  9 #import "GetSimilarity.h"
 10 #define ImgSizeA 10
 11 #define ImgSizeB 100
 12 typedef enum workday
 13 {
 14     SizeA,
 15     SizeB,
 16 }GetSimilarityType;
 17 
 18 
 19 @interface GetSimilarity()
 20 @property (nonatomic,assign) Similarity similarity;
 21 @property (nonatomic,strong) UIImage *imga;
 22 @property (nonatomic,strong) UIImage *imgb;
 23 @end
 24 
 25 @implementation GetSimilarity
 26 - (instancetype)init
 27 {
 28     self = [super init];
 29     if (self) {
 30         self.imga = [[UIImage alloc]init];
 31         self.imgb = [[UIImage alloc]init];
 32     }
 33     return self;
 34 }
 35 
 36 - (void)setImgWithImgA:(UIImage*)imgA ImgB:(UIImage*)imgB
 37 {
 38     _imga = imgA;
 39     _imgb = imgB;
 40 }
 41 
 42 - (void)setImgAWidthImg:(UIImage*)img
 43 {
 44     self.imga = img;
 45 }
 46 
 47 - (void)setImgBWidthImg:(UIImage*)img
 48 {
 49     self.imgb = img;
 50 }
 51 
 52 - (Similarity)getSimilarityValue
 53 {
 54     self.similarity = MAX([self getSimilarityValueWithType:SizeA], [self getSimilarityValueWithType:SizeB]);
 55     return self.similarity;
 56 } 
 57 + (Similarity)getSimilarityValueWithImgA:(UIImage *)imga ImgB:(UIImage *)imgb
 58 {
 59     GetSimilarity * getSimilarity = [[GetSimilarity alloc]init];
 60     [getSimilarity setImgWithImgA:imga ImgB:imgb];
 61     return [getSimilarity getSimilarityValue];
 62 }
 63 - (Similarity)getSimilarityValueWithType:(GetSimilarityType)type;//
 64 {
 65     int cursize = (type == SizeA ? ImgSizeA : ImgSizeB);
 66     int ArrSize = cursize * cursize + 1,a[ArrSize],b[ArrSize],i,j,grey,sum = 0;
 67     CGSize size = {cursize,cursize};
 68     UIImage * imga = [self reSizeImage:self.imga toSize:size];
 69     UIImage * imgb = [self reSizeImage:self.imgb toSize:size];//縮小圖片尺寸
 70 
 71     a[ArrSize] = 0;
 72     b[ArrSize] = 0;
 73     CGPoint point;
 74     for (i = 0 ; i < cursize; i++) {//計算a的灰度
 75         for (j = 0; j < cursize; j++) {
 76             point.x = i;
 77             point.y = j;
 78             grey = ToGrey([self UIcolorToRGB:[self colorAtPixel:point img:imga]]);
 79             a[cursize * i + j] = grey;
 80             a[ArrSize] += grey;
 81         }
 82     }
 83     a[ArrSize] /= (ArrSize - 1);//灰度平均值
 84     for (i = 0 ; i < cursize; i++) {//計算b的灰度
 85         for (j = 0; j < cursize; j++) {
 86             point.x = i;
 87             point.y = j;
 88             grey = ToGrey([self UIcolorToRGB:[self colorAtPixel:point img:imgb]]);
 89             b[cursize * i + j] = grey;
 90             b[ArrSize] += grey;
 91         }
 92     }
 93     b[ArrSize] /= (ArrSize - 1);//灰度平均值
 94     for (i = 0 ; i < ArrSize ; i++)//灰度分布計算
 95     {
 96         a[i] = (a[i] < a[ArrSize] ? 0 : 1);
 97         b[i] = (b[i] < b[ArrSize] ? 0 : 1);
 98     }
 99     ArrSize -= 1;
100     for (i = 0 ; i < ArrSize ; i++)
101     {
102         sum += (a[i] == b[i] ? 1 : 0);
103     }
104     
105     return sum * 1.0 / ArrSize;
106 }
107 
108 - (UIImage *)reSizeImage:(UIImage *)image toSize:(CGSize)reSize//重新設定圖片尺寸
109 {
110     UIGraphicsBeginImageContext(CGSizeMake(reSize.width, reSize.height));
111     [image drawInRect:CGRectMake(0, 0, reSize.width, reSize.height)];
112     UIImage *reSizeImage = UIGraphicsGetImageFromCurrentImageContext();
113     UIGraphicsEndImageContext();
114     return reSizeImage;
115 }
116 
117 unsigned int ToGrey(unsigned int rgb)//RGB計算灰度
118 {
119     unsigned int blue   = (rgb & 0x000000FF) >> 0;
120     unsigned int green  = (rgb & 0x0000FF00) >> 8;
121     unsigned int red    = (rgb & 0x00FF0000) >> 16;
122     return ( red*38 +  green * 75 +  blue * 15 )>>7;
123 }
124 
125 - (unsigned int)UIcolorToRGB:(UIColor*)color//UIColor轉16進制RGB
126 {
127     unsigned int RGB,R,G,B;
128     RGB = R = G = B = 0x00000000;
129     CGFloat r,g,b,a;
130     [color getRed:&r green:&g blue:&b alpha:&a];
131     R = r * 256 ;
132     G = g * 256 ;
133     B = b * 256 ;
134     RGB = (R << 16) | (G << 8) | B ;
135     return RGB;
136 }
137 
138 - (UIColor *)colorAtPixel:(CGPoint)point img:(UIImage*)img{//獲取指定point位置的RGB
139     // Cancel if point is outside image coordinates
140     if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, img.size.width, img.size.height), point)) { return nil; }
141     
142     NSInteger   pointX  = trunc(point.x);
143     NSInteger   pointY  = trunc(point.y);
144     CGImageRef  cgImage = img.CGImage;
145     NSUInteger  width   = img.size.width;
146     NSUInteger  height  = img.size.height;
147     int bytesPerPixel   = 4;
148     int bytesPerRow     = bytesPerPixel * 1;
149     NSUInteger bitsPerComponent = 8;
150     unsigned char pixelData[4] = { 0, 0, 0, 0 };
151     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
152     CGContextRef context = CGBitmapContextCreate(pixelData, 1, 1, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
153     
154     CGColorSpaceRelease(colorSpace);
155     CGContextSetBlendMode(context, kCGBlendModeCopy);
156     
157     // Draw the pixel we are interested in onto the bitmap context
158     CGContextTranslateCTM(context, -pointX, pointY-(CGFloat)height);
159     CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), cgImage);
160     CGContextRelease(context);
161     // Convert color values [0..255] to floats [0.0..1.0]
162   
163     CGFloat red   = (CGFloat)pixelData[0] / 255.0f;
164     CGFloat green = (CGFloat)pixelData[1] / 255.0f;
165     CGFloat blue  = (CGFloat)pixelData[2] / 255.0f;
166     CGFloat alpha = (CGFloat)pixelData[3] / 255.0f;
167     return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
168 }
169 @end

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM