圖片相似性比較

圖片相似性比較

主要分成以下幾個步驟

  • 縮小圖片尺寸:將圖片縮小到一定尺寸(一般是8*8)撩扒。去除圖像細節(jié)幔嗦,只保留結構/明暗基本信息
  • 簡化色彩:將縮小后的圖像锋恬,轉(zhuǎn)換為64級灰度桶蝎,所有的像素點總共只有64種顏色
  • 計算平均值:計算所有像素的灰度平均值
  • 比較像素的灰度:將每個像素的灰度声邦,與平均值進行比較乏奥,大于或等于平均值記為1,小于平均值記為0
  • 計算哈希值:將上一步的結果組合在一起亥曹,就構成了一個64位的整數(shù)邓了,這就是這張圖像的指紋。組合的次序并不重要媳瞪,只要保證所有圖像都采用同樣次序就行了
  • 得到指紋骗炉,比較不同的圖像(有多少位不一樣)

代碼如下:

//
//  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;
- (void)setImgAWidthImg:(UIImage*)img;
- (void)setImgBWidthImg:(UIImage*)img;
- (Similarity)getSimilarityValue; 
+ (Similarity)getSimilarityValueWithImgA:(UIImage*)imga ImgB:(UIImage*)imgb;
@end
//
//  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 100
typedef enum workday
{
    SizeA,
    SizeB,
}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;
}
//+ (double)getSimilarityValueWithImgA:(UIImage *)imga ImgB:(UIImage *)imgb
+ (Similarity)getSimilarityValueWithImgA:(UIImage *)imga ImgB:(UIImage *)imgb
{
    GetSimilarity * getSimilarity = [[GetSimilarity 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];

    a[ArrSize] = 0;
    b[ArrSize] = 0;
    CGPoint point;
    for (i = 0 ; i < cursize; i++) {//計算a的灰度
        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);//灰度平均值
    for (i = 0 ; i < cursize; i++) {//計算b的灰度
        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);//灰度平均值
    for (i = 0 ; i < ArrSize ; i++)//灰度分布計算
    {
        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
{
    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)
{
    unsigned int blue   = (rgb & 0x000000FF) >> 0;
    unsigned int green  = (rgb & 0x0000FF00) >> 8;
    unsigned int red    = (rgb & 0x00FF0000) >> 16;
    return ( red*38 +  green * 75 +  blue * 15 )>>7;
}

- (unsigned int)UIcolorToRGB:(UIColor*)color
{
    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{
    // Cancel if point is outside image coordinates
    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 are 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

找了一些資料,這個的比較效果是最好的蛇受。簡單的圖像相似性比較可以使用句葵,對于高階的使用可以使用Opencv官網(wǎng)中文站opencv中文站

參考:http://www.cnblogs.com/kongkaikai/p/5251543.html

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市兢仰,隨后出現(xiàn)的幾起案子乍丈,更是在濱河造成了極大的恐慌,老刑警劉巖把将,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轻专,死亡現(xiàn)場離奇詭異,居然都是意外死亡察蹲,警方通過查閱死者的電腦和手機请垛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門催训,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人宗收,你說我怎么就攤上這事瞳腌。” “怎么了镜雨?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵嫂侍,是天一觀的道長。 經(jīng)常有香客問我荚坞,道長挑宠,這世上最難降的妖魔是什么虏劲? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任脏嚷,我火速辦了婚禮,結果婚禮上犬性,老公的妹妹穿的比我還像新娘诡挂。我一直安慰自己碎浇,他們只是感情好,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布璃俗。 她就那樣靜靜地躺著奴璃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪城豁。 梳的紋絲不亂的頭發(fā)上苟穆,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機與錄音唱星,去河邊找鬼雳旅。 笑死,一個胖子當著我的面吹牛间聊,可吹牛的內(nèi)容都是我干的攒盈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼哎榴,長吁一口氣:“原來是場噩夢啊……” “哼型豁!你這毒婦竟也來了?” 一聲冷哼從身側響起叹话,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤偷遗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后驼壶,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體氏豌,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年热凹,在試婚紗的時候發(fā)現(xiàn)自己被綠了泵喘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泪电。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖纪铺,靈堂內(nèi)的尸體忽然破棺而出相速,到底是詐尸還是另有隱情,我是刑警寧澤鲜锚,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布突诬,位于F島的核電站,受9級特大地震影響芜繁,放射性物質(zhì)發(fā)生泄漏旺隙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一骏令、第九天 我趴在偏房一處隱蔽的房頂上張望蔬捷。 院中可真熱鬧,春花似錦榔袋、人聲如沸周拐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妥粟。三九已至,卻和暖如春聪黎,著一層夾襖步出監(jiān)牢的瞬間罕容,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工稿饰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人露泊。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓喉镰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親惭笑。 傳聞我的和親對象是個殘疾皇子侣姆,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 姓名:尤學強 學號:17101223374 轉(zhuǎn)載自:http://mp.weixin.qq.com/s/pD7G4...
    51fb659a6d6f閱讀 705評論 0 0
  • 2011年,Google把“相似圖片搜索”正式放上了首頁沉噩。你可以用一張圖片捺宗,搜索互聯(lián)網(wǎng)上所有與它相似的圖片。點擊搜...
    余平的余_余平的平閱讀 1,948評論 0 7
  • 不同圖像灰度不同川蒙,邊界處一般會有明顯的邊緣蚜厉,利用此特征可以分割圖像。需要說明的是:邊緣和物體間的邊界并不等同畜眨,邊緣...
    大川無敵閱讀 13,851評論 0 29
  • 這些年計算機視覺識別和搜索這個領域非常熱鬧昼牛,后期出現(xiàn)了很多的創(chuàng)業(yè)公司术瓮,大公司也在這方面也花了很多力氣在做。做視覺搜...
    方弟閱讀 6,497評論 6 24
  • 下午郵局大叔打電話給我說有兩封信被拒簽了贰健,讓我過去看看胞四,可惜他打電話的時候我還在上課,沒來得及去看伶椿,準備明天去郵局...
    江木晨閱讀 73評論 0 0