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

 

[置顶] 基于直方图特征的图像搜索

分类: 图像处理   507人阅读  评论(9)  收藏  举报
图像搜索 特征值 直方图

目录(?)[+]

概述


  182人阅读  评论(0)  收藏  举报

出处:http://www.cnblogs.com/saintbird/archive/2008/10/07/1229154.html

 最近一直在做数字图像处理方面的项目,其中基于内容的图像搜索是自己最感兴趣的一个方向,项目还在进行中,今天先对之前的工作做一个小结。

     提到基于内容的图像搜索,就不能不提基于文本的图像搜索。  当前几乎所有的商用图像搜索引擎如Google、百度、雅虎等都是采用基于文本的检索方式,这种方式存在很大的弊端:首先图像一般都具有丰富的细节和它的引申意义,这是难以用文字描述出来的,仅靠几个关键字或简单的注释是远远不够的;其次,对同样一幅图像,每个人都会有不同的理解,这使得利用文本标注准确的响应用户查询非常困难;第三、对图像进行文本标注只能通过手工完成,这在图像数量较少时还基本可行,但如果图像数量增长过快或总量巨大时,依靠手工来完成文本的标注将变得十分困难。而基于内容的图像检索技术很好的解决了这些问题,通过提取图像本身的特征进行检索,获得的结果将是客观而全面的,并且整个过程都是计算机自动完成的,无需人工介入,速度和精度都有了很大提高。 

     什么是基于内容的图像搜索?举个简单的例子:某年某月某天,你在路上偶遇一ppmm,并用随身携带的手机拍了一张照片,可除了这张照片再没有其他任何的信息。这个时候如果有一个基于内容的图像搜索引擎,只需将手上的图片上传,系统会自动提取图片中的特征,然后自动寻找与该特征匹配的相关信息。嘿嘿,有了照片就有了一切。不过,这暂时还只是一个美好的梦想而已,基于内容的图像搜索目前还只停留在研发阶段,就技术成熟度来说,还只能应用于站内搜索,要想推到整个互联网,真的是路漫漫其修远兮。google做这项研究已经很多年了,一直到前不久发布的Picasa2上才发现与“基于内容的图像搜索”相关的一个功能,而且只是测试功能。有兴趣的朋友可以下载试用一下,该软件中的“按色彩搜索功能”就是基于内容的图像搜索算法中的一种。有兴趣的朋友还可以看看这个网站: http://www.like.com/ ,这表面上是个购物网站,但实际上完全是为了测试他们的图像检索功能而搭建的测试站,做得确实很不错。
    

      基于内容的图像搜索技术早在70年代就有机构在做相关的研究,目前比较成功的有IBM的QBIC系统,Virage公司的图像检索系统,MIT的Photobook及美国加州大学开发的Chabot。基于内容的图像检索最关键的就是找到适合用于搜索的特征,常用的特征提取算法有:

      基于颜色特征:颜色直方图、颜色集、颜色矩、颜色聚合向量、MEPG7颜色布局算子;

      基于纹理特征:Tamura纹理特征、自回归纹理模型、Gabor变换、小波变换、MPEG7边缘直方图;

      基于形状特征:傅立叶形状描述符、形状无关矩、小波轮廓描述符;

      如果是视频文件的话,还有基于运动的特征提取算法,以上各种算法都有自己的优缺点,适用场合也不尽相同,通常需要多个特征组合在一起才能得到比较好的结果。 


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

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

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

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

原理

       巴氏系数(Bhattacharyyacoefficient)算法

基于直方图特征的图像搜索_第1张图片

       其中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] ++;

 源码


三维直方图表示

[java]  view plain copy print ?
  1. /** 
  2.      * 求三维的灰度直方图 
  3.      * @param srcPath 
  4.      * @return 
  5.      */  
  6.     public static double[][] getHistgram(String srcPath) {  
  7.         BufferedImage img = ImageDigital.readImg(srcPath);  
  8.         return getHistogram(img);  
  9.     }  
  10.     /** 
  11.      * hist[0][]red的直方图,hist[1][]green的直方图,hist[2][]blue的直方图 
  12.      * @param img 要获取直方图的图像 
  13.      * @return 返回r,g,b的三维直方图 
  14.      */  
  15.     public static double[][] getHistogram(BufferedImage img) {  
  16.         int w = img.getWidth();  
  17.         int h = img.getHeight();  
  18.         double[][] hist = new double[3][256];   
  19.         int r, g, b;  
  20.         int pix[] = new int[w*h];   
  21.         pix = img.getRGB(00, w, h, pix, 0, w);  
  22.         for(int i=0; i<w*h; i++) {  
  23.             r = pix[i]>>16 & 0xff;  
  24.             g = pix[i]>>8 & 0xff;  
  25.             b = pix[i] & 0xff;  
  26.             /*hr[r] ++; 
  27.             hg[g] ++; 
  28.             hb[b] ++;*/  
  29.             hist[0][r] ++;  
  30.             hist[1][g] ++;  
  31.             hist[2][b] ++;  
  32.         }  
  33.         for(int j=0; j<256; j++) {  
  34.             for(int i=0; i<3; i++) {  
  35.                 hist[i][j] = hist[i][j]/(w*h);  
  36.                 //System.out.println(hist[i][j] + "  ");  
  37.             }  
  38.         }  
  39.         return hist;  
  40.     }  
  41.     public double indentification(String srcPath, String destPath) {  
  42.         BufferedImage srcImg = ImageDigital.readImg(srcPath);  
  43.         BufferedImage destImg = ImageDigital.readImg(destPath);  
  44.         return indentification(srcImg, destImg);  
  45.     }  
  46.       
  47.     public double indentification(BufferedImage srcImg, BufferedImage destImg) {  
  48.         double[][] histR = getHistogram(srcImg);  
  49.         double[][] histD = getHistogram(destImg);  
  50.         return indentification(histR, histD);  
  51.     }  
  52.       
  53.     public static double indentification(double[][] histR, double[][] histD) {  
  54.         double p = (double0.0;  
  55.         for(int i=0; i<histR.length; i++) {  
  56.             for(int j=0; j<histR[0].length; j++) {  
  57.                 p += Math.sqrt(histR[i][j]*histD[i][j]);  
  58.             }  
  59.         }  
  60.         return p/3;  
  61.     }  
  62. /** 
  63.      * 用三维灰度直方图求图像的相似度 
  64.      * @param n 
  65.      * @param str1 
  66.      * @param str2 
  67.      */  
  68.     public static void histogramIditification(int n, String str1, String str2) {  
  69.         double p = 0;  
  70.         double[][] histR = GreyIdentification.getHistgram(str1);   
  71.         double[][] histD = null;  
  72.         for(int i=0; i<n; i++) {  
  73.             histD = GreyIdentification.getHistgram(str2 + (i+1) + ".jpg");  
  74.             p = GreyIdentification.indentification(histR, histD);  
  75.             System.out.print((i+1) + "--" + p + "    ");  
  76.         }  
  77.     }  

一维直方图表示

[java]  view plain copy print ?
  1. /** 
  2.      * 求一维的灰度直方图 
  3.      * @param srcPath 
  4.      * @return 
  5.      */  
  6.     public static double[] getHistgram2(String srcPath) {  
  7.         BufferedImage img = ImageDigital.readImg(srcPath);  
  8.         return getHistogram2(img);  
  9.     }  
  10.     /** 
  11.      * 求一维的灰度直方图 
  12.      * @param img 
  13.      * @return 
  14.      */  
  15.     public static double[] getHistogram2(BufferedImage img) {  
  16.         int w = img.getWidth();  
  17.         int h = img.getHeight();  
  18.         int series = (int) Math.pow(2, GRAYBIT);    //GRAYBIT=4;用12位的int表示灰度值,前4位表示red,中间4们表示green,后面4位表示blue  
  19.         int greyScope = 256/series;  
  20.         double[] hist = new double[series*series*series];   
  21.         int r, g, b, index;  
  22.         int pix[] = new int[w*h];   
  23.         pix = img.getRGB(00, w, h, pix, 0, w);  
  24.         for(int i=0; i<w*h; i++) {  
  25.             r = pix[i]>>16 & 0xff;  
  26.             r = r/greyScope;  
  27.             g = pix[i]>>8 & 0xff;  
  28.             g = g/greyScope;  
  29.             b = pix[i] & 0xff;  
  30.             b = b/greyScope;  
  31.             index = r<<(2*GRAYBIT) | g<<GRAYBIT | b;   
  32.             hist[index] ++;  
  33.         }  
  34.         for(int i=0; i<hist.length; i++) {  
  35.             hist[i] = hist[i]/(w*h);  
  36.             //System.out.println(hist[i] + "  ");  
  37.         }  
  38.         return hist;  
  39.     }  
  40.     public double indentification2(String srcPath, String destPath) {  
  41.         BufferedImage srcImg = ImageDigital.readImg(srcPath);  
  42.         BufferedImage destImg = ImageDigital.readImg(destPath);  
  43.         return indentification2(srcImg, destImg);  
  44.     }  
  45.       
  46.     public double indentification2(BufferedImage srcImg, BufferedImage destImg) {  
  47.         double[] histR = getHistogram2(srcImg);  
  48.         double[] histD = getHistogram2(destImg);  
  49.         return indentification2(histR, histD);  
  50.     }  
  51.       
  52.     public static double indentification2(double[] histR, double[] histD) {  
  53.         double p = (double0.0;  
  54.         for(int i=0; i<histR.length; i++) {  
  55.             p += Math.sqrt(histR[i]*histD[i]);  
  56.         }  
  57.         return p;  
  58.     }  
  59. /** 
  60.      * 用一维直方图求图像的相似度 
  61.      * @param n 
  62.      * @param str1 
  63.      * @param str2 
  64.      */  
  65.     public static void histogramIditification2(int n, String str1, String str2) {  
  66.         double p = 0;  
  67.         double[] histR = GreyIdentification.getHistgram2(str1);   
  68.         double[] histD = null;  
  69.         for(int i=0; i<n; i++) {  
  70.             histD = GreyIdentification.getHistgram2(str2 + (i+1) + ".jpg");  
  71.             p = GreyIdentification.indentification2(histR, histD);  
  72.             System.out.print((i+1) + "--" + p + "    ");  
  73.         }  
  74.     }  

效果

源图像(要搜索的图像)

基于直方图特征的图像搜索_第2张图片

要被搜索的图像

基于直方图特征的图像搜索_第3张图片

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

基于直方图特征的图像搜索_第4张图片

你可能感兴趣的:(图像处理)