图像相似度(测试)--基于直方图特征的图像搜索

转自:http://blog.csdn.net/jia20003/article/details/7771651#comments

图像处理之相似图片识别(直方图应用篇)

算法概述:

首先对源图像与要筛选的图像进行直方图数据采集,对采集的各自图像直方图进行归一化再

使用巴氏系数算法对直方图数据进行计算,最终得出图像相似度值,其值范围在[0, 1]之间

0表示极其不同,1表示极其相似(相同)。

算法步骤详解:

大致可以分为两步,根据源图像与候选图像的像素数据,生成各自直方图数据。第二步:使

用第一步输出的直方图结果,运用巴氏系数(Bhattacharyya coefficient)算法,计算出相似程

度值。

第一步:直方图计算

直方图分为灰度直方图与RGB直方图,对于灰度图像直方图计算十分简单,只要初始化一

个大小为256的直方图数组H,然后根据像素值完成频率分布统计,假设像素值为124,则

H[124] += 1, 而对于彩色RGB像素来说直方图表达有两种方式,一种是单一直方图,另外一

种是三维直方图,三维直方图比较简单明了,分别对应RGB三种颜色,定义三个直方图HR,

HG, HB, 假设某一个像素点P的RGB值为(4, 231,129), 则对于的直方图计算为HR[4] += 1,

HG[231] += 1, HB[129] += 1, 如此对每个像素点完成统计以后,RGB彩色直方图数据就生成了。

而RGB像素的单一直方图SH表示稍微复杂点,每个颜色的值范围为0 ~ 255之间的,假设

可以分为一定范围等份,当8等份时,每个等份的值范围为32, 16等份时,每个等份值范

围为16,当4等份时候,每个等份值的范围为64,假设RGB值为(14, 68, 221), 16等份之

后,它对应直方图索引值(index)分别为: (0, 4, 13), 根据计算索引值公式:index = R + G*16 + B*16*16


对应的直方图index = 0 + 4*16 + 13 * 16 * 16, SH[3392] += 1

如此遍历所有RGB像素值,完成直方图数据计算。

第二步:巴氏系数计算,计算公式如下:


其中P, P’分别代表源与候选的图像直方图数据,对每个相同i的数据点乘积开平方以后相加

得出的结果即为图像相似度值(巴氏系数因子值),范围为0到1之间。

程序效果:


相似度超过99%以上,极其相似


相似度为:72%, 一般相似

程序直方图计算源代码如下:

  1. public void setGreenBinCount(int greenBinCount) { 
  2.     this.greenBins = greenBinCount; 
  3.  
  4. public void setBlueBinCount(int blueBinCount) { 
  5.     this.blueBins = blueBinCount; 
  6.  
  7. public float[] filter(BufferedImage src, BufferedImage dest) { 
  8.     int width = src.getWidth(); 
  9.        int height = src.getHeight(); 
  10.         
  11.        int[] inPixels = new int[width*height]; 
  12.        float[] histogramData = new float[redBins * greenBins * blueBins]; 
  13.        getRGB( src, 0, 0, width, height, inPixels ); 
  14.        int index = 0
  15.        int redIdx = 0, greenIdx = 0, blueIdx =0
  16.        int singleIndex = 0
  17.        float total = 0
  18.        for(int row=0; row<height; row++) { 
  19.         int ta = 0, tr = 0, tg =0, tb = 0
  20.         for(int col=0; col<width; col++) { 
  21.             index = row * width + col; 
  22.             ta = (inPixels[index] >> 24) &0xff
  23.                tr = (inPixels[index] >> 16) & 0xff
  24.                tg = (inPixels[index] >> 8) &0xff
  25.                tb = inPixels[index] & 0xff
  26.                redIdx = (int)getBinIndex(redBins, tr,255); 
  27.                greenIdx = (int)getBinIndex(greenBins, tg,255); 
  28.                blueIdx = (int)getBinIndex(blueBins, tb,255); 
  29.                singleIndex = redIdx + greenIdx * redBins + blueIdx * redBins * greenBins; 
  30.                histogramData[singleIndex] += 1
  31.                total += 1
  32.         } 
  33.        } 
  34.         
  35.        // start to normalize the histogram data 
  36.        for (int i =0; i < histogramData.length; i++) 
  37.        { 
  38.         histogramData[i] = histogramData[i] / total; 
  39.        } 
  40.         
  41.        return histogramData; 
	public void setGreenBinCount(int greenBinCount) {
		this.greenBins = greenBinCount;
	}

	public void setBlueBinCount(int blueBinCount) {
		this.blueBins = blueBinCount;
	}

	public float[] filter(BufferedImage src, BufferedImage dest) {
		int width = src.getWidth();
        int height = src.getHeight();
        
        int[] inPixels = new int[width*height];
        float[] histogramData = new float[redBins * greenBins * blueBins];
        getRGB( src, 0, 0, width, height, inPixels );
        int index = 0;
        int redIdx = 0, greenIdx = 0, blueIdx = 0;
        int singleIndex = 0;
        float total = 0;
        for(int row=0; row<height; row++) {
        	int ta = 0, tr = 0, tg = 0, tb = 0;
        	for(int col=0; col<width; col++) {
        		index = row * width + col;
        		ta = (inPixels[index] >> 24) & 0xff;
                tr = (inPixels[index] >> 16) & 0xff;
                tg = (inPixels[index] >> 8) & 0xff;
                tb = inPixels[index] & 0xff;
                redIdx = (int)getBinIndex(redBins, tr, 255);
                greenIdx = (int)getBinIndex(greenBins, tg, 255);
                blueIdx = (int)getBinIndex(blueBins, tb, 255);
                singleIndex = redIdx + greenIdx * redBins + blueIdx * redBins * greenBins;
                histogramData[singleIndex] += 1;
                total += 1;
        	}
        }
        
        // start to normalize the histogram data
        for (int i = 0; i < histogramData.length; i++)
        {
        	histogramData[i] = histogramData[i] / total;
        }
        
        return histogramData;
	}
计算巴氏系数的代码如下:

  1. /**
  2. * Bhattacharyya Coefficient
  3. * http://www.cse.yorku.ca/~kosta/CompVis_Notes/bhattacharyya.pdf
  4. *
  5. * @return
  6. */ 
  7. public double modelMatch() { 
  8.     HistogramFilter hfilter = new HistogramFilter(); 
  9.     float[] sourceData = hfilter.filter(sourceImage,null); 
  10.     float[] candidateData = hfilter.filter(candidateImage,null); 
  11.     double[] mixedData =new double[sourceData.length]; 
  12.     for(int i=0; i<sourceData.length; i++ ) { 
  13.         mixedData[i] = Math.sqrt(sourceData[i] * candidateData[i]); 
  14.     } 
  15.      
  16.     // The values of Bhattacharyya Coefficient ranges from 0 to 1, 
  17.     double similarity = 0
  18.     for(int i=0; i<mixedData.length; i++ ) { 
  19.         similarity += mixedData[i]; 
  20.     } 
  21.      
  22.     // The degree of similarity 
  23.     return similarity; 
	/**
	 * Bhattacharyya Coefficient
	 * http://www.cse.yorku.ca/~kosta/CompVis_Notes/bhattacharyya.pdf
	 * 
	 * @return
	 */
	public double modelMatch() {
		HistogramFilter hfilter = new HistogramFilter();
		float[] sourceData = hfilter.filter(sourceImage, null);
		float[] candidateData = hfilter.filter(candidateImage, null);
		double[] mixedData = new double[sourceData.length];
		for(int i=0; i<sourceData.length; i++ ) {
			mixedData[i] = Math.sqrt(sourceData[i] * candidateData[i]);
		}
		
		// The values of Bhattacharyya Coefficient ranges from 0 to 1,
		double similarity = 0;
		for(int i=0; i<mixedData.length; i++ ) {
			similarity += mixedData[i];
		}
		
		// The degree of similarity
		return similarity;
	}
转载文章请务必注明出自本博客
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值