zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    前端vue使用js-xlsx导出excel的三种方法
    vue使用echarts绘制河南地图并实现个人轨迹
    VUE中使用Echarts绘制柱状图
    springboot项目配置拦截器
    springboot+mybatis的多数据源配置
    Java后端高频面试题汇总
    Java基础专题
    Java集合专题
    Java并发专题
    JVM专题javascript:;
  • 原文地址:https://www.cnblogs.com/kongkaikai/p/5251543.html
Copyright © 2011-2022 走看看