图像纹理是图像中像素之间的复杂关系,其反映了图像的光滑、粗糙、混乱、有序等特征。因此,对于许多图像处理和分析任务,包括目标分类、目标检测、图像信息检索等,从图像纹理中提取特征已成为一项重要的技术。
一、纹理特征提取方法
在图像纹理特征提取方面,常用的方法可以分为基于结构的方法和基于统计的方法。
1.基于结构的方法
基于结构的方法主要关注图像中重复的空间结构,并利用这些结构来提取特征。其中一种常见的方法就是利用小波变换进行纹理分析。小波变换将信号分解为不同尺度和方向上的子带,能够很好地描述图像中不同频率的细节信息。因此,通过小波变换可以提取图像纹理的局部结构特征,如纹理点、线和方向等。
代码示例:
import pywt import cv2 img = cv2.imread('texture.jpg', 0) coeffs = pywt.dwt2(img, 'haar') # 利用haar小波进行二维小波变换 cA, (cH, cV, cD) = coeffs # 获取LL、LH、HL和HH系数
2.基于统计的方法
基于统计的方法则关注图像中的纹理统计特征,包括纹理的灰度分布、梯度方向、梯度幅值和空间结构等,这些特征往往涵盖一些局部的信息和全局的信息。由于统计特征具有不变性和稳定性,因此这些特征在目标分类和图像检索中具有广泛应用。
代码示例:
import cv2 img = cv2.imread('texture.jpg', 0) mean = cv2.mean(img)[0] # 获取图像的灰度平均值 var = cv2.meanStdDev(img)[1][0][0] # 获取图像灰度方差 gX = cv2.Sobel(img, cv2.CV_32F, 1, 0, ksize=3) # X方向梯度 gY = cv2.Sobel(img, cv2.CV_32F, 0, 1, ksize=3) # Y方向梯度 gMag, gDir = cv2.cartToPolar(gX, gY, angleInDegrees=True) # 计算梯度幅值和梯度方向
二、常用的纹理特征描述方法
在图像纹理特征描述方面,常用的方法可以分为直方图和统计方法两种。
1.直方图
直方图通常用于描述图像的灰度分布特征,将灰度级分为若干个区间,统计每个区间内像素的个数,得到的直方图表示了图像的灰度分布情况。在纹理特征描述中,可以利用直方图来描述图像纹理的灰度分布特征和梯度分布特征等。
代码示例:
import cv2 img = cv2.imread('texture.jpg', 0) hist = cv2.calcHist([img], [0], None, [256], [0, 256]) # 计算灰度直方图 hist_norm = cv2.normalize(hist, hist) # 将直方图归一化到[0, 1]范围
2.统计方法
统计方法则关注图像中的纹理统计特征,包括纹理的灰度分布、梯度方向、梯度幅值和空间结构等,这些特征往往涵盖一些局部的信息和全局的信息。统计方法常用的描述方法有灰度共生矩阵、灰度差异矩阵和局部二值模式等。
代码示例:
import cv2 img = cv2.imread('texture.jpg', 0) glcm = cv2.calcGLCM(img, [1], [0, np.pi/4, np.pi/2, 3*np.pi/4], symmetric=True) # 计算灰度共生矩阵 contrast = cv2.compareHist(cv2.normalize(glcm, glcm).flatten(), np.array([1]), cv2.HISTCMP_CHISQR_ALT) # 计算对比度 entropy = -np.sum(glcm*np.log2(glcm + 1e-10)) # 计算熵
三、常用的图像纹理特征分类算法
在对图像纹理特征进行提取和描述之后,通常需要将这些特征用于分类和识别。常用的分类算法有:K近邻算法、支持向量机算法、随机森林算法和神经网络算法等。
1.K近邻算法
K近邻算法是一种基于实例的分类算法,其基本思想是在训练数据集中寻找与测试数据样本最相似的K个邻居,然后根据这K个邻居的标签信息对测试样本进行分类。在使用K近邻算法进行图像纹理分类时,可以利用某个像素周围的纹理信息作为该像素的特征,然后将这些特征作为训练数据进行分类。
代码示例:
import cv2 from sklearn.neighbors import KNeighborsClassifier def extract_features(img, x, y): # 提取以(x, y)为中心的9个像素的纹理特征 features = [] for i in range(x-1, x+2): for j in range(y-1, y+2): if i != x and j != y: features.append(img[i, j]) return features img = cv2.imread('textures.jpg', 0) h, w = img.shape X = [] y = [] for i in range(1, h-1): for j in range(1, w-1): features = extract_features(img, i, j) X.append(features) y.append(label) knn = KNeighborsClassifier(n_neighbors=3, weights='distance') knn.fit(X, y)
2.支持向量机算法
支持向量机算法是一种二分类算法,其基本思想是利用一个超平面将不同类别的样本分开。在图像纹理分类中,可以将提取的图像纹理特征作为样本,然后利用支持向量机将这些特征进行分类。
代码示例:
import cv2 from sklearn.svm import SVC img = cv2.imread('textures.jpg', 0) h, w = img.shape X = [] y = [] for i in range(1, h-1): for j in range(1, w-1): features = extract_features(img, i, j) X.append(features) y.append(label) svm = SVC(kernel='linear', C=1, gamma='auto') svm.fit(X, y)
3.随机森林算法
随机森林算法是一种集成学习算法,其基本思想是将多个决策树合并成一个森林,然后利用不同的随机采样和特征采样方法来增强模型的泛化能力。在图像纹理分类中,可以将提取的图像纹理特征作为决策树的训练数据,然后利用随机森林对这些特征进行分类。
代码示例:
import cv2 from sklearn.ensemble import RandomForestClassifier img = cv2.imread('textures.jpg', 0) h, w = img.shape X = [] y = [] for i in range(1, h-1): for j in range(1, w-1): features = extract_features(img, i, j) X.append(features) y.append(label) rf = RandomForestClassifier(n_estimators=100) rf.fit(X, y)
4.神经网络算法
神经网络算法是一种常见的深度学习方法,其基本思想是通过多层神经元的计算和反向传播算法来训练模型,实现从输入到输出的映射。在图像纹理分类中,可以将提取的图像纹理特征作为神经网络的输入,然后训练神经网络进行分类。
代码示例:
import cv2 import keras from keras.models import Sequential from keras.layers import Dense, Dropout, Activation img = cv2.imread('textures.jpg', 0) h, w = img.shape X = [] y = [] for i in range(1, h-1): for j in range(1, w-1): features = extract_features(img, i, j) X.append(features) y.append(label) model = Sequential() model.add(Dense(64, activation='relu')) model.add(Dense(32, activation='relu')) model.add(Dense(10, activation='softmax')) model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy']) model.fit(X, keras.utils.to_categorical(y, num_classes=10), epochs=50, batch_size=32)