LIRe图像检索:Tamura纹理特征算法源码分析

2023-10-23 19:51

本文主要是介绍LIRe图像检索:Tamura纹理特征算法源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 Tamura概述

Tamura纹理特征包括了粗糙度(coarseness)、对比度(contrast)、方向度(directionality)、线性度(linelikeness)、规则度(regularity)、粗略度(roughness)。最原始的Tamura论文有《Textural Features Correspondingto Visual Perception》。Tamura纹理特征要比灰度共生矩阵得到的纹理特征更直观,在视觉效果上更有优势。LIRe实现了Tamura纹理特征,包括粗糙度、对比度和方向。

2 源码分析

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


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

public class Tamura implements GlobalFeature {private static final int MAX_IMG_HEIGHT = 64;private int[][] grayScales;private int imgWidth;private int imgHeight;private double[] histogram;private static final double[][] filterH = new double[][]{{-1.0D, 0.0D, 1.0D}, {-1.0D, 0.0D, 1.0D}, {-1.0D, 0.0D, 1.0D}};private static final double[][] filterV = new double[][]{{-1.0D, -1.0D, -1.0D}, {0.0D, 0.0D, 0.0D}, {1.0D, 1.0D, 1.0D}};private static final String TAMURA_NAME = "tamura";public Tamura() {}//第一个指标coarseness 粗糙度public double coarseness(int n0, int n1) {double result = 0.0D;for(int i = 1; i < n0 - 1; ++i) {for(int j = 1; j < n1 - 1; ++j) {result += Math.pow(2.0D, (double)this.sizeLeadDiffValue(i, j));}}result = 1.0D / (double)(n0 * n1) * result;return result;}public double averageOverNeighborhoods(int x, int y, int k) {double result = 0.0D;double border = Math.pow(2.0D, (double)(2 * k));boolean x0 = false;boolean y0 = false;for(int i = 0; (double)i < border; ++i) {for(int j = 0; (double)j < border; ++j) {int var12 = x - (int)Math.pow(2.0D, (double)(k - 1)) + i;int var13 = y - (int)Math.pow(2.0D, (double)(k - 1)) + j;if(var12 < 0) {var12 = 0;}if(var13 < 0) {var13 = 0;}if(var12 >= this.imgWidth) {var12 = this.imgWidth - 1;}if(var13 >= this.imgHeight) {var13 = this.imgHeight - 1;}result += (double)this.grayScales[var12][var13];}}result = 1.0D / Math.pow(2.0D, (double)(2 * k)) * result;return result;}public double differencesBetweenNeighborhoodsHorizontal(int x, int y, int k) {double result = 0.0D;result = Math.abs(this.averageOverNeighborhoods(x + (int)Math.pow(2.0D, (double)(k - 1)), y, k) - this.averageOverNeighborhoods(x - (int)Math.pow(2.0D, (double)(k - 1)), y, k));return result;}public double differencesBetweenNeighborhoodsVertical(int x, int y, int k) {double result = 0.0D;result = Math.abs(this.averageOverNeighborhoods(x, y + (int)Math.pow(2.0D, (double)(k - 1)), k) - this.averageOverNeighborhoods(x, y - (int)Math.pow(2.0D, (double)(k - 1)), k));return result;}public int sizeLeadDiffValue(int x, int y) {double result = 0.0D;int maxK = 1;for(int k = 0; k < 3; ++k) {double tmp = Math.max(this.differencesBetweenNeighborhoodsHorizontal(x, y, k), this.differencesBetweenNeighborhoodsVertical(x, y, k));if(result < tmp) {maxK = k;result = tmp;}}return maxK;}//第二个指标Contrast,对比度public double contrast() {double result = 0.0D;double my4 = 0.0D;double alpha4 = 0.0D;double my = this.calculateMy();double sigma = this.calculateSigma(my);if(sigma <= 0.0D) {return 0.0D;} else {for(int x = 0; x < this.imgWidth; ++x) {for(int y = 0; y < this.imgHeight; ++y) {my4 += Math.pow((double)this.grayScales[x][y] - my, 4.0D);}}alpha4 = my4 / Math.pow(sigma, 4.0D);result = sigma / Math.pow(alpha4, 0.25D);return result;}}public double calculateMy() {double mean = 0.0D;for(int x = 0; x < this.imgWidth; ++x) {for(int y = 0; y < this.imgHeight; ++y) {mean += (double)this.grayScales[x][y];}}mean /= (double)(this.imgWidth * this.imgHeight);return mean;}public double calculateSigma(double mean) {double result = 0.0D;for(int x = 0; x < this.imgWidth; ++x) {for(int y = 0; y < this.imgHeight; ++y) {result += Math.pow((double)this.grayScales[x][y] - mean, 2.0D);}}result /= (double)(this.imgWidth * this.imgHeight);return Math.sqrt(result);}//第三个指标 Directionality,方向度public double[] directionality() {double[] histogram = new double[16];double maxResult = 3.0D;double binWindow = maxResult / (double)(histogram.length - 1);boolean bin = true;for(int x = 1; x < this.imgWidth - 1; ++x) {for(int y = 1; y < this.imgHeight - 1; ++y) {int var9 = (int)((1.5707963267948966D + Math.atan(this.calculateDeltaV(x, y) / this.calculateDeltaH(x, y))) / binWindow);++histogram[var9];}}return histogram;}public double calculateDeltaH(int x, int y) {double result = 0.0D;for(int i = 0; i < 3; ++i) {for(int j = 0; j < 3; ++j) {result += (double)this.grayScales[x - 1 + i][y - 1 + j] * filterH[i][j];}}return result;}public double calculateDeltaV(int x, int y) {double result = 0.0D;for(int i = 0; i < 3; ++i) {for(int j = 0; j < 3; ++j) {result += (double)this.grayScales[x - 1 + i][y - 1 + j] * filterV[i][j];}}return result;}public double getDistance(double[] targetFeature, double[] queryFeature) {double result = 0.0D;for(int i = 2; i < targetFeature.length; ++i) {result += Math.pow(targetFeature[i] - queryFeature[i], 2.0D);}return result;}public void extract(BufferedImage image) {this.histogram = new double[18];ColorConvertOp op = new ColorConvertOp(image.getColorModel().getColorSpace(), ColorSpace.getInstance(1003), new RenderingHints(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY));BufferedImage bimg = op.filter(image, (BufferedImage)null);bimg = ImageUtils.scaleImage(bimg, 64);WritableRaster raster = bimg.getRaster();int[] tmp = new int[3];this.grayScales = new int[raster.getWidth()][raster.getHeight()];int i;for(i = 0; i < raster.getWidth(); ++i) {for(int j = 0; j < raster.getHeight(); ++j) {raster.getPixel(i, j, tmp);this.grayScales[i][j] = tmp[0];}}this.imgWidth = bimg.getWidth();this.imgHeight = bimg.getHeight();//第一个指标 Coarseness,粗糙度this.histogram[0] = this.coarseness(bimg.getWidth(), bimg.getHeight());//第二个指标 Contrast,对比度this.histogram[1] = this.contrast();//第三个指标 Directionality,方向度double[] directionality = this.directionality();for(i = 2; i < this.histogram.length; ++i) {this.histogram[i] = directionality[i - 2];}}public byte[] getByteArrayRepresentation() {return SerializationUtils.toByteArray(this.histogram);}public void setByteArrayRepresentation(byte[] in) {this.histogram = SerializationUtils.toDoubleArray(in);}public void setByteArrayRepresentation(byte[] in, int offset, int length) {this.histogram = SerializationUtils.toDoubleArray(in, offset, length);}public double[] getFeatureVector() {return this.histogram;}public double getDistance(LireFeature feature) {if(!(feature instanceof Tamura)) {throw new UnsupportedOperationException("Wrong descriptor.");} else {Tamura tamura = (Tamura)feature;return this.getDistance(tamura.histogram, this.histogram);}}public String getFeatureName() {return "Tamura Features";}public String getFieldName() {return "TAMURA";}
}
Reference:

http://blog.sina.com.cn/s/blog_5ae7a1de01012r03.html

http://blog.csdn.net/jzwong/article/details/51584535


这篇关于LIRe图像检索:Tamura纹理特征算法源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/270106

相关文章

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三

Mysql的主从同步/复制的原理分析

《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意

java -jar命令运行 jar包时运行外部依赖jar包的场景分析

《java-jar命令运行jar包时运行外部依赖jar包的场景分析》:本文主要介绍java-jar命令运行jar包时运行外部依赖jar包的场景分析,本文给大家介绍的非常详细,对大家的学习或工作... 目录Java -jar命令运行 jar包时如何运行外部依赖jar包场景:解决:方法一、启动参数添加: -Xb

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

c/c++的opencv图像金字塔缩放实现

《c/c++的opencv图像金字塔缩放实现》本文主要介绍了c/c++的opencv图像金字塔缩放实现,通过对原始图像进行连续的下采样或上采样操作,生成一系列不同分辨率的图像,具有一定的参考价值,感兴... 目录图像金字塔简介图像下采样 (cv::pyrDown)图像上采样 (cv::pyrUp)C++ O

Apache 高级配置实战之从连接保持到日志分析的完整指南

《Apache高级配置实战之从连接保持到日志分析的完整指南》本文带你从连接保持优化开始,一路走到访问控制和日志管理,最后用AWStats来分析网站数据,对Apache配置日志分析相关知识感兴趣的朋友... 目录Apache 高级配置实战:从连接保持到日志分析的完整指南前言 一、Apache 连接保持 - 性

Linux中的more 和 less区别对比分析

《Linux中的more和less区别对比分析》在Linux/Unix系统中,more和less都是用于分页查看文本文件的命令,但less是more的增强版,功能更强大,:本文主要介绍Linu... 目录1. 基础功能对比2. 常用操作对比less 的操作3. 实际使用示例4. 为什么推荐 less?5.