本文节选自论文《基于半监督和主动学习相结合的图像的检索研究》,并结合我对LIRe中FCTH源码进行分析、解读和研究。

模糊颜色和纹理直方图(Fuzzy Color and Texture Histogram,FCTH),FCTH特征可从3个模糊单元的组合求得结果。先将图像划分成若干分块,在第一个模糊单元中以HSV颜色空间的三个信道为输入,经模糊系统最终产生10-bin的直方图。在第二个模糊单元修改每个颜色的色调后,经模糊系统最终产生24-bin的直方图。以上两个模糊单元在颜色描述子中章节中已详细作了解释,且模糊颜色描述子与CEDD中所提的颜色描述子是同一个概念,在此不再累述。在第三个模糊单元中,将图像分块经Harr小波变换成一组纹理元素,模糊系统以这些纹理元素集为输入将24-bin直方图转换成192-bin的直方图。最后是描述FCTH特征提取的实现。

1 FCTH原理

1.1 模糊纹理分割

模糊系统如图2-8所示,展示了模糊纹理直方图的求解过程,图像分块经Harr小波变换得到三个纹理元素fLH,fHL和fHH。这三个纹理元素作为模糊系统的输入,可得到8-bin直方图,8bins对应的区域分别是:(0)低能量线性区,(1)低能量水平激活区,(2)低能量垂直激活区,(3)低能量水平和垂直激活区,(4)高能量线性区,(5)高能量水平激活区,(6)高能量垂直激活区,(7)高能量水平和垂直激活区。事实证明fLH,fHL和fHH等纹理元素能够有效辨别图像的纹理。

1.2 FCTH的实现

首先定义与提取颜色信息相关的单元为颜色单元,与提取纹理信息相关的单元为纹理单元,如图2-9所示,纹理单元所在的模糊系统产生了8个区间,颜色单元所在的模糊系统产生了24个独立的区间,这样最终的直方图将产生8*24=192bin区域。为了塑造这个直方图,衡量图像的细节与计算要求,现将图像分割成1600个分块。如果定义纹理单元的bin为N并且颜色单元的bin为M,那么该图像分块的直方图位置将为:N*24+M。

整个FCTH的实现模型如图2-9所示,分为纹理单元模块与颜色单元模块。

a) 在纹理单元模块中,每个图像分块经Harr小波变换得到三个纹理元素fLH,fHL和fHH的值,经模糊关联系统分类可将该图像分块归类于8-bin直方图中的一种。假设该图像分块被归类到第二bin中,则它对应的纹理应为低能量水平激活区。

b)在颜色单元模块中,每个图像分块被转换到HSV颜色空间。信道色调H,饱和度S,亮度V组成模糊系统的输入,得到输出为10-bin的直方图。假设输出结果为第4bin,对应的颜色为红色。第二个模糊系统(24-bin 模糊关联)将原先的每个色调再次分割成3色调,改变亮度V为两个模糊区间,得出输出为24-bin直方图。再假设输出结果为第4bin,此时对应的颜色却为深红色。合并这三个模糊系统最终可将该图像分块归类为27bin(1*24+3)。

c) 反复对图像的所有分块执行(a),(b)两个步骤,得到整张图像的直方图,直方图会归一于{0-1}区间内,而每个直方图可量化为3比特。

1.3 FCTH特征的相似度量

为了计算FCTH特征向量的相似性距离我们选择使用Tanimoto 系数。

2 源码分析

在lire.jar中FCTH源码的位置如下:

以下为我对源码的分析和解读。

public void extract(BufferedImage bimg) {bimg = ImageUtils.get8BitRGBImage(bimg);this.histogram = this.Apply(bimg);
}public double[] Apply(BufferedImage image) {//10-bin的直方图Fuzzy10Bin Fuzzy10 = new Fuzzy10Bin(false);//24-bin的直方图Fuzzy24Bin Fuzzy24 = new Fuzzy24Bin(false);FuzzyFCTHpart FuccyFCTH = new FuzzyFCTHpart();double[] Fuzzy10BinResultTable = new double[10];double[] Fuzzy24BinResultTable = new double[24];//192-bin的直方图double[] FuzzyHistogram192 = new double[192];byte Method = 2;int width = image.getWidth();int height = image.getHeight();for(int HSVConverter = 0; HSVConverter < 192; ++HSVConverter) {FuzzyHistogram192[HSVConverter] = 0.0D;}RGB2HSV var48 = new RGB2HSV();int[] HSV = new int[3];new WaveletMatrixPlus();double[][] ImageGrid = new double[width][height];int[][] ImageGridRed = new int[width][height];int[][] ImageGridGreen = new int[width][height];int[][] ImageGridBlue = new int[width][height];BufferedImage image_rgb = new BufferedImage(width, height, 4);image_rgb.getGraphics().drawImage(image, 0, 0, (ImageObserver)null);int[] pixels = ((DataBufferInt)image_rgb.getRaster().getDataBuffer()).getData();int Step_X;int Step_Y;for(int NumberOfBlocks = 0; NumberOfBlocks < width; ++NumberOfBlocks) {for(Step_X = 0; Step_X < height; ++Step_X) {int pixel = pixels[Step_X * width + NumberOfBlocks];int b = pixel >> 16 & 255;int g = pixel >> 8 & 255;int r = pixel & 255;ImageGridRed[NumberOfBlocks][Step_X] = r;ImageGridGreen[NumberOfBlocks][Step_X] = g;ImageGridBlue[NumberOfBlocks][Step_X] = b;Step_Y = (int)(0.114D * (double)b + 0.587D * (double)g + 0.299D * (double)r);ImageGrid[NumberOfBlocks][Step_X] = (double)Step_Y;}}/** 最终的直方图将产生 8*24=192bin 区域。为了塑造这个直方图,* 衡量图像的细节与计算要求,先将图像分割成 1600 个分块。*/short var49 = 1600;Step_X = (int)Math.floor((double)width / Math.sqrt((double)var49));Step_Y = (int)Math.floor((double)height / Math.sqrt((double)var49));if(Step_X % 2 != 0) {--Step_X;}if(Step_Y % 2 != 0) {--Step_Y;}if(Step_Y < 4) {Step_Y = 4;}if(Step_X < 4) {Step_X = 4;}for(int TotalSum = 0; TotalSum < height - Step_Y; TotalSum += Step_Y) {for(int x = 0; x < width - Step_X; x += Step_X) {double[][] Quant = new double[4][4];int[][] BlockR = new int[4][4];int[][] BlockG = new int[4][4];int[][] BlockB = new int[4][4];int[][] BlockCount = new int[4][4];int[] CororRed = new int[Step_Y * Step_X];int[] CororGreen = new int[Step_Y * Step_X];int[] CororBlue = new int[Step_Y * Step_X];int[] CororRedTemp = new int[Step_Y * Step_X];int[] CororGreenTemp = new int[Step_Y * Step_X];int[] CororBlueTemp = new int[Step_Y * Step_X];int MeanRed = 0;int MeanGreen = 0;int MeanBlue = 0;boolean CurrentPixelX = false;boolean CurrentPixelY = false;int TempSum;int i;for(TempSum = 0; TempSum < 4; ++TempSum) {for(i = 0; i < 4; ++i) {Quant[TempSum][i] = 0.0D;BlockCount[TempSum][i] = 0;}}TempSum = 0;int j;for(i = 0; i < Step_X; ++i) {for(j = 0; j < Step_Y; ++j) {byte var53 = 0;byte var54 = 0;if(i >= Step_X / 4) {var53 = 1;}if(i >= Step_X / 2) {var53 = 2;}if(i >= 3 * Step_X / 4) {var53 = 3;}if(j >= Step_Y / 4) {var54 = 1;}if(j >= Step_Y / 2) {var54 = 2;}if(j >= 3 * Step_Y / 4) {var54 = 3;}Quant[var53][var54] += ImageGrid[x + i][TotalSum + j];++BlockCount[var53][var54];BlockR[var53][var54] = ImageGridRed[x + i][TotalSum + j];BlockG[var53][var54] = ImageGridGreen[x + i][TotalSum + j];BlockB[var53][var54] = ImageGridBlue[x + i][TotalSum + j];CororRed[TempSum] = BlockR[var53][var54];CororGreen[TempSum] = BlockG[var53][var54];CororBlue[TempSum] = BlockB[var53][var54];CororRedTemp[TempSum] = BlockR[var53][var54];CororGreenTemp[TempSum] = BlockG[var53][var54];CororBlueTemp[TempSum] = BlockB[var53][var54];++TempSum;}}for(i = 0; i < 4; ++i) {for(j = 0; j < 4; ++j) {Quant[i][j] /= (double)BlockCount[i][j];}}WaveletMatrixPlus Matrix = this.singlePassThreshold(Quant, 1);for(i = 0; i < Step_Y * Step_X; ++i) {MeanRed += CororRed[i];MeanGreen += CororGreen[i];MeanBlue += CororBlue[i];}MeanRed /= Step_Y * Step_X;MeanGreen /= Step_Y * Step_X;MeanBlue /= Step_Y * Step_X;HSV = var48.ApplyFilter(MeanRed, MeanGreen, MeanBlue);if(!this.Compact) {//在第一个模糊单元中以 HSV 颜色空间的三个信道为输入,经模糊系统最终产生 10-bin 的直方图。Fuzzy10BinResultTable = Fuzzy10.ApplyFilter((double)HSV[0], (double)HSV[1], (double)HSV[2], Method);//在第二个模糊单元修改每个颜色的色调后,经模糊系统最终产生 24-bin 的直方图。Fuzzy24BinResultTable = Fuzzy24.ApplyFilter((double)HSV[0], (double)HSV[1], (double)HSV[2], Fuzzy10BinResultTable, Method);//在第三个模糊单元中,将图像分块经 Harr 小波变换成一组纹理元素,模糊系统以这些纹理元素集为输入将 24-bin 直方图转换成 192-bin 的直方图。FuzzyHistogram192 = FuccyFCTH.ApplyFilter(Matrix.F3, Matrix.F2, Matrix.F1, Fuzzy24BinResultTable, Method, 24);} else {Fuzzy10BinResultTable = Fuzzy10.ApplyFilter((double)HSV[0], (double)HSV[1], (double)HSV[2], Method);FuzzyHistogram192 = FuccyFCTH.ApplyFilter(Matrix.F3, Matrix.F2, Matrix.F1, Fuzzy10BinResultTable, Method, 10);}}}double var50 = 0.0D;int var51;for(var51 = 0; var51 < 192; ++var51) {var50 += FuzzyHistogram192[var51];}for(var51 = 0; var51 < 192; ++var51) {FuzzyHistogram192[var51] /= var50;}FCTHQuant var52 = new FCTHQuant();FuzzyHistogram192 = var52.Apply(FuzzyHistogram192);return FuzzyHistogram192;}

Reference:

http://blog.csdn.net/leixiaohua1020/article/details/16883143

http://kns.cnki.net/KCMS/detail/detail.aspx?dbcode=CMFD&dbname=CMFD2011&filename=1011042472.nh&uid=WEEvREcwSlJHSldRa1FhdXNXYXJwTmxwNmcxQUU0VCtNVGNPSmIvM3pORT0=$9A4hF_YAuvQ5obgVAqNKPCYcEjKensW4ggI8Fm4gTkoUKaID8j8gFw!!&v=MTk2MjRIN084SE5YTHJaRWJQSVI4ZVgxTHV4WVM3RGgxVDNxVHJXTTFGckNVUkwyZlkrUnVGeW5uVXJ6TFZGMjY=

LIRe图像检索:FCTH算法原理与源码分析相关推荐

  1. LIRe图像检索:CEDD算法原理与源码分析

    本文节选自论文<Android手机上图像分类技术的研究>,并结合我对LIRe中CEDD源码进行分析.解读和研究. 颜色和边缘方向性描述符(Color and EdgeDirectivity ...

  2. Spark 随机森林算法原理、源码分析及案例实战

    图 1. Spark 与其它大数据处理工具的活跃程度比较 回页首 环境要求 操作系统:Linux,本文采用的 Ubuntu 10.04,大家可以根据自己的喜好使用自己擅长的 Linux 发行版 Jav ...

  3. LIRE原理与源码分析(二)——相关接口

    1. LIRE原理与源码分析(二)-- 代码结构 2. LIRE原理与源码分析(二)-- 相关接口 上一篇文章介绍了LIRE的基本内容和源码的代码结构.本文针对LIRE中主要的三个接口(LireFea ...

  4. ConcurrentHashMap实现原理及源码分析

    ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对HashMap的实现原理还不甚了解,可参考我的另一篇文章HashMap实现原理及源码分析),Con ...

  5. concurrenthashmap_ConcurrentHashMap实现原理及源码分析

    ConcurrentHashMap是Java并发包中提供的一个线程安全且高效的HashMap实现(若对HashMap的实现原理还不甚了解,可参考我的另一篇文章HashMap实现原理及源码分析),Con ...

  6. SIFT原理与源码分析:DoG尺度空间构造

    <SIFT原理与源码分析>系列文章索引:http://blog.csdn.net/xiaowei_cqu/article/details/8069548 尺度空间理论 自然界中的物体随着观 ...

  7. 深入理解Spark 2.1 Core (十二):TimSort 的原理与源码分析

    在博文<深入理解Spark 2.1 Core (十):Shuffle Map 端的原理与源码分析 >中我们提到了: 使用Sort等对数据进行排序,其中用到了TimSort 这篇博文我们就来 ...

  8. 深入理解Spark 2.1 Core (十):Shuffle Map 端的原理与源码分析

    在上一篇<深入理解Spark 2.1 Core (九):迭代计算和Shuffle的原理与源码分析>提到经过迭代计算后, SortShuffleWriter.write中: // 根据排序方 ...

  9. 深入理解Spark 2.1 Core (六):Standalone模式运行的原理与源码分析

    我们讲到了如何启动Master和Worker,还讲到了如何回收资源.但是,我们没有将AppClient是如何启动的,其实它们的启动也涉及到了资源是如何调度的.这篇博文,我们就来讲一下AppClient ...

最新文章

  1. 分布式服务框架-原理与实践:14---流量控制-学习笔记(理论篇)
  2. 如何让决策树中有样本的索引
  3. 推荐|5种商业AI产品的技术架构设计!
  4. 老焦专栏 | 如何做一个有说服力的方案?
  5. 关于System.Web.Caching的“未将对象引用设置到对象的实例”错误
  6. 演示方法:有抱负的分析师
  7. windows下使用cpanm进行模块安装
  8. RedHat系统安装nextcloud
  9. acegis连接使用方法_铝型材配件间隔连接块的分类与使用方法
  10. ArcGIS 对DEM数据进行剖面分析
  11. 教育类App原型制作分享-Busuu
  12. Ubuntu 11.10ibus万能五笔
  13. mbr引导的启动盘制作方法
  14. 《目标检测蓝皮书》第4篇 经典热门网络结构
  15. PostgreSQL 技术内幕(二) Greenplum-AO表
  16. 计算机毕业设计基于Android二手车交易网站系统app
  17. 知名APP(支付宝、微信、花瓣等)首页设计技巧及原型实例讲解
  18. 如何用c语言计算三角形面积
  19. linux下eclipse修改tab,eclipse 更改 tab 缩进字符数
  20. 马斯洛提出动机理论_【错题本】马斯洛的需要层次理论

热门文章

  1. 乔布斯4大经营理念:不纠结于错误 创意需要时间
  2. onreadystatechange事件
  3. 这篇文章教会你Python自动化测试需要学什么?怎么去学?从哪里开始学?看完本文学习python目标明确,学习简单粗暴。
  4. Could not connect to SMTP host: smtp.126.com, port: 25
  5. Flutter ListView详解
  6. 任务调度框架 Quartz 用法指南(超详细)
  7. refs win10_在refs格式下可不可以装windows 10
  8. 正则表达式匹配非,以及非字符串的匹配
  9. Jsp中request.getParameter(@param)值为[object HTMLInputElement]
  10. 你要知道的21道软件设计 + 面向对象的面试题