LIRe图像检索:FCTH算法原理与源码分析
2017-04-21 11:46
501 查看
本文节选自论文《基于半监督和主动学习相结合的图像的检索研究》,并结合我对LIRe中FCTH源码进行分析、解读和研究。
模糊颜色和纹理直方图(Fuzzy Color and Texture Histogram,FCTH),FCTH特征可从3个模糊单元的组合求得结果。先将图像划分成若干分块,在第一个模糊单元中以HSV颜色空间的三个信道为输入,经模糊系统最终产生10-bin的直方图。在第二个模糊单元修改每个颜色的色调后,经模糊系统最终产生24-bin的直方图。以上两个模糊单元在颜色描述子中章节中已详细作了解释,且模糊颜色描述子与CEDD中所提的颜色描述子是同一个概念,在此不再累述。在第三个模糊单元中,将图像分块经Harr小波变换成一组纹理元素,模糊系统以这些纹理元素集为输入将24-bin直方图转换成192-bin的直方图。最后是描述FCTH特征提取的实现。
整个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比特。
以下为我对源码的分析和解读。
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=
模糊颜色和纹理直方图(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图像检索:CEDD算法原理与源码分析
- LIRe图像检索:Tamura纹理特征算法源码分析
- OpenCV学习笔记(29)KAZE 算法原理与源码分析(三)特征检测与描述
- OpenCV学习笔记(31)KAZE 算法原理与源码分析(五)KAZE的源码优化及与SIFT的比较
- 实习日记:图像检索算法 LSH 的总结与分析(matlab)
- 图像检索:FCTH(Fuzzy Color and Texture Histogram)算法
- LIRE原理与源码分析(一)——代码结构
- OpenCV学习笔记(29)KAZE 算法原理与源码分析(三)特征检测与描述
- 聚类分析算法在图像检索系统中的应用
- LIRe提供的图像检索算法的速度
- 图像检索:FCTH(Fuzzy Color and Texture Histogram)算法
- OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
- SIFT算法原理与OpenCV源码分析4:方向赋值
- KAZE 算法原理与源码分析(四)KAZE特征的性能分析与比较
- OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
- OpenCV学习笔记(30)KAZE 算法原理与源码分析(四)KAZE特征的性能分析与比较
- SIFT算法原理与OpenCV源码分析6:OpenCV实现SIFT算法,特征检测器FeatureDetector
- LIRe提供的图像检索算法的速度
- OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波
- LIRE原理与源码分析(二)——相关接口