1. Reduce the size: Reduce the image to 8*8 size, a total of 64 pixels. This step is to remove the details of the image, only the structure/shading and other basic information, discard the different size/proportion of the image differences;
Note: The actual operation, take two sizes for comparison (10*10,100*100) size, then the performance impact will be larger, I realized two kinds, the purpose is to show how to set different sizes.
2. Simplify the color: the reduced image to 64 levels of gray, that is, all the pixels of a total of only 64 colors;
Note: Regarding the number of gray level issues, I did not care too much, took a suitable RGB to GRAY algorithm on good, personal understanding
3. Calculate average: Calculates the gray average of all 64 pixels;
4. Compare the grayscale of a pixel: compare the grayscale of each pixel to the average, greater than or equal to the average of 1, and less than the average to 0;
5. Calculate the hash value: Combining the results of the previous step, together, constitutes a 64-bit integer, which is the fingerprint of this image. The order of the combinations is not important, just ensure that all images are in the same order;
6. Once you've got your fingerprints, you can compare different images.
GetSimilarity.h
getsimilarity.h// imgsimlartest//// Created by test on 16/3/3.// Copyright? 2016 Com.facishare.CoreTest. All rights reserved.//#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> typedef double similarity; @interface getsimilarity:nsobject-(void) Setimgwithimga: (uiimage*) ImgA ImgB: (uiimage*) imgb;//Set picture to compare-(void) Setimgawidthimg: (uiimage*) img;-(void) setimgbwidthimg: (uiimage*) img;-(similarity) Getsimilarityvalue; Get similarity + (similarity) Getsimilarityvaluewithimga: (uiimage*) Imga ImgB: (uiimage*) imgb;//class method @end
Getsimilarity.m
getsimilarity.m//imgsimlartest////Created by test on 16/3/3.//Copyright? 2016 com.facishare.CoreTest. All rights reserved.//#import "GetSimilarity.h" #define Imgsizea 10#define Imgsizeb 100typedef enum workday{Sizea, S Izeb,}getsimilaritytype, @interface getsimilarity () @property (nonatomic,assign) similarity similarity; @property ( Nonatomic,strong) UIImage *imga, @property (nonatomic,strong) UIImage *imgb; @end @implementation getsimilarity-( Instancetype) init{self = [super init]; if (self) {self.imga = [[UIImage alloc]init]; SELF.IMGB = [[UIImage alloc]init]; } return self;} -(void) Setimgwithimga: (uiimage*) ImgA ImgB: (uiimage*) imgb{_imga = ImgA; _IMGB = IMGB;} -(void) Setimgawidthimg: (uiimage*) img{self.imga = img;} -(void) Setimgbwidthimg: (uiimage*) img{SELF.IMGB = img;} -(similarity) getsimilarityvalue{self.similarity = MAX ([self Getsimilarityvaluewithtype:sizea], [self Getsimilarityvaluewithtype:sizeb]); Return Self.similariTy;} + (Similarity) Getsimilarityvaluewithimga: (UIImage *) Imga ImgB: (UIImage *) imgb{getsimilarity * getsimilarity = [[Getsim] Ilarity Alloc]init]; [Getsimilarity Setimgwithimga:imga IMGB:IMGB]; return [getsimilarity Getsimilarityvalue];} -(similarity) Getsimilarityvaluewithtype: (getsimilaritytype) type;//{int cursize = (Type = = Sizea?) Imgsizea:imgsizeb); int arrsize = cursize * cursize + 1,a[arrsize],b[arrsize],i,j,grey,sum = 0; Cgsize size = {Cursize,cursize}; UIImage * Imga = [self reSizeImage:self.imga tosize:size]; UIImage * IMGB = [self RESIZEIMAGE:SELF.IMGB tosize:size];//reduced image size A[arrsize] = 0; B[arrsize] = 0; Cgpoint Point; for (i = 0; i < cursize; i++) {//Calculates A's grayscale for (j = 0; J < Cursize, J + +) {point.x = i; Point.y = j; Grey = Togrey ([self uicolortorgb:[self coloratpixel:point img:imga]); A[cursize * i + j] = grey; A[arrsize] + = grey; }} A[arrsize]/= (arrsize-1);//Grayscale average for (i = 0; i < cursize; i++) {//calculate B's grayscale for (j = 0; J < Cursize; J + +) {Point.x = I Point.y = j; Grey = Togrey ([self uicolortorgb:[self coloratpixel:point IMG:IMGB]); B[cursize * i + j] = grey; B[arrsize] + = grey; }} B[arrsize]/= (ArrSize-1);//gray average for (i = 0; i < arrsize; i++)//Grayscale distribution calculation {A[i] = (A[i] < A[arrsize]? 0:1); B[i] = (B[i] < b[arrsize]? 0:1); } arrsize-= 1; for (i = 0; i < arrsize; i++) {sum + = (a[i] = = B[i]? 1:0); } return sum * 1.0/arrsize;} -(UIImage *) Resizeimage: (UIImage *) image tosize: (cgsize) resize//re-set picture size {Uigraphicsbeginimagecontext (Cgsizemake ( Resize.width, Resize.height)); [Image drawinrect:cgrectmake (0, 0, Resize.width, resize.height)]; UIImage *resizeimage = Uigraphicsgetimagefromcurrentimagecontext (); Uigraphicsendimagecontext (); return resizeimage;} unsigned int togrEY (unsigned int RGB)//rgb calculates grayscale {unsigned int blue = (RGB & 0X000000FF) >> 0; unsigned int green = (RGB & 0x0000FF00) >> 8; unsigned int red = (RGB & 0x00ff0000) >> 16; Return (red*38 + green * + blue *) >>7;} -(unsigned int) Uicolortorgb: (uicolor*) Color//uicolor to 16 binary rgb{unsigned int rgb,r,g,b; RGB = R = G = B = 0x00000000; CGFloat R,g,b,a; [Color Getred:&r green:&g blue:&b alpha:&a]; R = R * 256; g = g * 256; b = b * 256; RGB = (R << 16) | (G << 8) | B return RGB;} -(Uicolor *) Coloratpixel: (cgpoint) point img: (uiimage*) img{//gets the RGB//Cancel if points of the location of the specified position is outside image Coordi Nates if (! Cgrectcontainspoint (CGRectMake (0.0f, 0.0f, Img.size.width, Img.size.height), point) {return nil;} Nsinteger Pointx = trunc (point.x); Nsinteger pointy = trunc (POINT.Y); Cgimageref cgimage = img. Cgimage; Nsuinteger width = img.size.width; NsuiNteger height = img.size.height; int bytesperpixel = 4; int bytesperrow = Bytesperpixel * 1; Nsuinteger bitspercomponent = 8; unsigned char pixeldata[4] = {0, 0, 0, 0}; Cgcolorspaceref colorspace = Cgcolorspacecreatedevicergb (); Cgcontextref context = Cgbitmapcontextcreate (Pixeldata, 1, 1, bitspercomponent, Bytesperrow, ColorSpace, Kcgimagealphapremultipliedlast | KCGBITMAPBYTEORDER32BIG); Cgcolorspacerelease (ColorSpace); Cgcontextsetblendmode (context, kcgblendmodecopy); Draw The pixel we is interested in onto the bitmap context Cgcontexttranslatectm (context,-pointx, pointy-(cgfloat) height); Cgcontextdrawimage (Context, CGRectMake (0.0f, 0.0f, (cgfloat) width, (cgfloat) height), cgimage); Cgcontextrelease (context); Convert color values [0..255] to floats [0.0..1.0] cgfloat red = (cgfloat) pixeldata[0]/255.0f; CGFloat green = (cgfloat) pixeldata[1]/255.0f; CGFloat blue = (cgfloat) pixeldata[2]/255.0f; CgfloAt alpha = (cgfloat) pixeldata[3]/255.0f; return [Uicolor colorwithred:red green:green blue:blue alpha:alpha];} @end
Comparison of iOS image similarity