基于直方图特征的图像搜索

原创 2013年03月19日 12:49:30

概述

       图像搜索现实的一般过程:

提取图像特征值→对特征值进行处理→匹配特征值

       图像的特征值有很多,基于颜色特征,纹理特征,形状特征等,下面是基于图像颜色直方图特征的图像搜索。

(参考文章:http://blog.csdn.net/jia20003/article/details/7771651#comments )

原理

       巴氏系数(Bhattacharyyacoefficient)算法


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

得出的结果即为图像相似度值(巴氏系数因子值),范围为01之间。为什么是到1之间,这是数学的问题,就不追究了。

步骤

一、     求源图像和要被搜索图像的直方图特征

二、     根据直方图特征,用巴氏系数算法求出源图像和要搜索图像的相似度

       彩色图像的每个像素由red,green,blue三种组成,如何好地表示彩色图像的直方图更呢?一般有两种方式:

       一种是用三维的直方图表示,这种方式简单明了,如hist[][]hist[0][]表示red的直方图,hist[1][]表示green的直方图,hist[2][]表示blue的直方图;如一个像素为(156,72,89),hist[0][156]++; hist[0][72]++, hist[0][89]++;

       另一种方式是降低灰度的级数,用一维直方图表示,如将256级的灰度降至16级,可用12位的int表示灰度值,前4位表示red,中间4们表示green,后面4位表示blue;一个像素为(156,72,89), r=156/16=9; g=72/16=4,b=89/16=5; index = r<<(2*4) | g<<4 | b; hist[index] ++;

 源码


三维直方图表示

/**
	 * 求三维的灰度直方图
	 * @param srcPath
	 * @return
	 */
	public static double[][] getHistgram(String srcPath) {
		BufferedImage img = ImageDigital.readImg(srcPath);
		return getHistogram(img);
	}
	/**
	 * hist[0][]red的直方图,hist[1][]green的直方图,hist[2][]blue的直方图
	 * @param img 要获取直方图的图像
	 * @return 返回r,g,b的三维直方图
	 */
	public static double[][] getHistogram(BufferedImage img) {
		int w = img.getWidth();
		int h = img.getHeight();
		double[][] hist = new double[3][256]; 
		int r, g, b;
		int pix[] = new int[w*h]; 
		pix = img.getRGB(0, 0, w, h, pix, 0, w);
		for(int i=0; i<w*h; i++) {
			r = pix[i]>>16 & 0xff;
			g = pix[i]>>8 & 0xff;
			b = pix[i] & 0xff;
			/*hr[r] ++;
			hg[g] ++;
			hb[b] ++;*/
			hist[0][r] ++;
			hist[1][g] ++;
			hist[2][b] ++;
		}
		for(int j=0; j<256; j++) {
			for(int i=0; i<3; i++) {
				hist[i][j] = hist[i][j]/(w*h);
				//System.out.println(hist[i][j] + "  ");
			}
		}
		return hist;
	}
	public double indentification(String srcPath, String destPath) {
		BufferedImage srcImg = ImageDigital.readImg(srcPath);
		BufferedImage destImg = ImageDigital.readImg(destPath);
		return indentification(srcImg, destImg);
	}
	
	public double indentification(BufferedImage srcImg, BufferedImage destImg) {
		double[][] histR = getHistogram(srcImg);
		double[][] histD = getHistogram(destImg);
		return indentification(histR, histD);
	}
	
	public static double indentification(double[][] histR, double[][] histD) {
		double p = (double) 0.0;
		for(int i=0; i<histR.length; i++) {
			for(int j=0; j<histR[0].length; j++) {
				p += Math.sqrt(histR[i][j]*histD[i][j]);
			}
		}
		return p/3;
	}
/**
	 * 用三维灰度直方图求图像的相似度
	 * @param n
	 * @param str1
	 * @param str2
	 */
	public static void histogramIditification(int n, String str1, String str2) {
		double p = 0;
		double[][] histR = GreyIdentification.getHistgram(str1); 
		double[][] histD = null;
		for(int i=0; i<n; i++) {
			histD = GreyIdentification.getHistgram(str2 + (i+1) + ".jpg");
			p = GreyIdentification.indentification(histR, histD);
			System.out.print((i+1) + "--" + p + "    ");
		}
	}

一维直方图表示

/**
	 * 求一维的灰度直方图
	 * @param srcPath
	 * @return
	 */
	public static double[] getHistgram2(String srcPath) {
		BufferedImage img = ImageDigital.readImg(srcPath);
		return getHistogram2(img);
	}
	/**
	 * 求一维的灰度直方图
	 * @param img
	 * @return
	 */
	public static double[] getHistogram2(BufferedImage img) {
		int w = img.getWidth();
		int h = img.getHeight();
		int series = (int) Math.pow(2, GRAYBIT);	//GRAYBIT=4;用12位的int表示灰度值,前4位表示red,中间4们表示green,后面4位表示blue
		int greyScope = 256/series;
		double[] hist = new double[series*series*series]; 
		int r, g, b, index;
		int pix[] = new int[w*h]; 
		pix = img.getRGB(0, 0, w, h, pix, 0, w);
		for(int i=0; i<w*h; i++) {
			r = pix[i]>>16 & 0xff;
			r = r/greyScope;
			g = pix[i]>>8 & 0xff;
			g = g/greyScope;
			b = pix[i] & 0xff;
			b = b/greyScope;
			index = r<<(2*GRAYBIT) | g<<GRAYBIT | b; 
			hist[index] ++;
		}
		for(int i=0; i<hist.length; i++) {
			hist[i] = hist[i]/(w*h);
			//System.out.println(hist[i] + "  ");
		}
		return hist;
	}
	public double indentification2(String srcPath, String destPath) {
		BufferedImage srcImg = ImageDigital.readImg(srcPath);
		BufferedImage destImg = ImageDigital.readImg(destPath);
		return indentification2(srcImg, destImg);
	}
	
	public double indentification2(BufferedImage srcImg, BufferedImage destImg) {
		double[] histR = getHistogram2(srcImg);
		double[] histD = getHistogram2(destImg);
		return indentification2(histR, histD);
	}
	
	public static double indentification2(double[] histR, double[] histD) {
		double p = (double) 0.0;
		for(int i=0; i<histR.length; i++) {
			p += Math.sqrt(histR[i]*histD[i]);
		}
		return p;
	}
/**
	 * 用一维直方图求图像的相似度
	 * @param n
	 * @param str1
	 * @param str2
	 */
	public static void histogramIditification2(int n, String str1, String str2) {
		double p = 0;
		double[] histR = GreyIdentification.getHistgram2(str1); 
		double[] histD = null;
		for(int i=0; i<n; i++) {
			histD = GreyIdentification.getHistgram2(str2 + (i+1) + ".jpg");
			p = GreyIdentification.indentification2(histR, histD);
			System.out.print((i+1) + "--" + p + "    ");
		}
	}

效果

源图像(要搜索的图像)


要被搜索的图像


搜索的结果,相似度从大到小


版权声明:本文为博主原创文章,未经博主允许不得用于任何商业用途,转载请注明出处。

vc++基于颜色直方图的图像检索,含代码

一. 理论和方法介绍   a) 采用颜色检索方法的目的:   对多媒体数据的检索,早期的方法是用文本将多媒体数据进行标识,这显然不是基于多媒体信息本身内容的检索,对多媒体数据中包含...
  • GarfieldEr007
  • GarfieldEr007
  • 2016年05月06日 14:15
  • 1293

颜色直方图

颜色直方图是在许多图像检索系统中被广泛采用的颜色特征。它所描述的是不同色彩在整幅图像中所占的比例,而并不关心每种色彩所处的空间位置,即无法描述图像中的对象或物体。颜色直方图特别适于描述那些难以进行自动...
  • fire_woods
  • fire_woods
  • 2007年07月26日 11:05
  • 12282

基于直方图特征的图像搜索

[置顶] 基于直方图特征的图像搜索 分类: 图像处理2013-03-19 12:49 507人阅读 评论(9) 收藏 举报 图像搜索特征值直方图 目录(?)[+] 概述 ...
  • pi9nc
  • pi9nc
  • 2013年09月18日 08:35
  • 1239

基于直方图的特征-----经典的SIFT特征

author:liumm 时间:2014/7/29-------
  • only444572170
  • only444572170
  • 2014年07月29日 09:20
  • 1015

基于颜色直方图的图片检索

  • 2014年05月27日 10:11
  • 28.53MB
  • 下载

相似图片搜索原理三(颜色直方图—c++实现)

图像的颜色直方图可以用于图像检索,适应有相同色彩,并且可以有平移、缩放、旋转不变性的图像检索,当然了这三大特点不如sift或者surf稳定性强,此外最大的局限就是如果形状内容一样,但色彩不一,结果是搜...
  • u011402197
  • u011402197
  • 2015年09月23日 11:27
  • 1026

OpenCV基于直方图特征的图像搜索

转自:http://blog.csdn.net/jia20003/article/details/7771651#comments 图像处理之相似图片识别(直方图应用篇) 算法概述: 首先对...
  • xgwdy06
  • xgwdy06
  • 2013年12月27日 15:23
  • 457

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

转自:http://blog.csdn.net/jia20003/article/details/7771651#comments 图像处理之相似图片识别(直方图应用篇) 算法概述: 首先对...
  • caiye917015406
  • caiye917015406
  • 2013年04月09日 14:19
  • 2393

OpenCV提取图像颜色直方图

输入图像: 输出直方图分布图像: 输入图像: 输出直方图分布图像: #include #include #include using namespace std; ...
  • GarfieldEr007
  • GarfieldEr007
  • 2015年11月19日 17:43
  • 3133

相似图片搜索原理三(c++)颜色直方图

图像的颜色直方图可以用于图像检索,适应有相同色彩,并且可以有平移、缩放、旋转不变性的图像检索,当然了这三大特点不如sift或者surf稳定性强,此外最大的局限就是如果形状内容一样,但色彩不一,结果是搜...
  • u013812682
  • u013812682
  • 2016年07月21日 10:39
  • 213
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:基于直方图特征的图像搜索
举报原因:
原因补充:

(最多只允许输入30个字)