图像分类任务中的特征提取与融合策略研究
本文探讨了不同特征提取和融合技术在图像分类任务中的效果。实验基于1000张图片,覆盖10个类别,应用SVM、决策树、KNN和朴素贝叶斯算法,对比了直方图、HOG、LBP和颜色矩特征。发现直方图特征在SVM中表现最佳,准确率达0.8600。实验有局限性,仅供参考。
本文探讨了不同特征提取和融合技术在图像分类任务中的效果。实验基于1000张图片,覆盖10个类别,应用SVM、决策树、KNN和朴素贝叶斯算法,对比了直方图、HOG、LBP和颜色矩特征。发现直方图特征在SVM中表现最佳,准确率达0.8600。实验有局限性,仅供参考。
目录
第一步:准备数据
for i in range(10): for f in os.listdir(f"photo2/{i}"): X.append(os.path.join(f"photo2/{i}", f)) Y.append(i) X = np.array(X) Y = np.array(Y) X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=1)
第二步:图像特征提取函数解析
在图像处理与模式识别领域,特征提取是识别和分类图像的关键步骤。以下是四个常用的特征提取函数,它们分别提取图像的直方图特征、HOG特征、LBP特征和颜色矩特征。
1. 直方图特征提取 (extract_histogram_features)
该函数用于提取图像的颜色直方图特征,它捕捉了图像的颜色分布信息。
def extract_histogram_features(image_path):
image = cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), cv2.IMREAD_COLOR)
img = cv2.resize(image, (256, 256), interpolation=cv2.INTER_CUBIC)
hist = cv2.calcHist([img], [0, 1], None, [256, 256], [0.0, 255.0, 0.0, 255.0])
return (hist / 255).flatten()
cv2.imdecode和np.fromfile用于从文件路径加载图像。cv2.resize将图像调整为统一的大小(256x256),以便于处理。cv2.calcHist计算图像的直方图,其中[0, 1]表示对蓝色和绿色通道进行直方图计算,[256, 256]表示直方图的bin数量,[0.0, 255.0, 0.0, 255.0]为直方图的值域。- 直方图的值被归一化并展平,以便于后续处理。
2. HOG特征提取 (extract_hog_features)
HOG(Histogram of Oriented Gradients)特征提取函数用于提取图像中的梯度方向信息,这有助于描述图像中物体的形状和轮廓。
def extract_hog_features(image_path):
image = cv2.imread(image_path, cv2.IMREAD_COLOR)
if len(image.shape) > 2 and image.shape[2] == 3:
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
features = hog(image, orientations=8, pixels_per_cell=(16, 16), cells_per_block=(1, 1), block_norm='L2')
return features
cv2.imread用于读取图像。- 如果图像是彩色的,
cv2.cvtColor将其转换为灰度图像。 hog函数计算HOG特征,orientations=8表示梯度的方向数量,pixels_per_cell和cells_per_block控制单元的大小和块的划分,block_norm='L2'是块的归一化方法。
3. LBP特征提取 (extract_lbp_features)
局部二值模式(LBP)是一种纹理描述符,它捕捉图像中的局部纹理信息,对光照变化具有较好的鲁棒性。
def extract_lbp_features(image_path):
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
lbp = local_binary_pattern(image, P=8, R=1, method='uniform')
lbp_8u = cv2.convertScaleAbs(lbp)
hist = cv2.calcHist([lbp_8u], [0], None, [256], [0, 256])
return hist.flatten()
cv2.imread以灰度模式读取图像。local_binary_pattern计算LBP特征。cv2.convertScaleAbs将LBP图像转换为8位无符号整数。cv2.calcHist计算LBP图像的直方图,并展平结果。
4. 颜色矩特征提取 (extract_color_moments_features)
颜色矩特征基于图像颜色分布的统计特征,包括均值、标准差等。
def extract_color_moments_features(image_path):
image = cv2.imread(image_path, cv2.IMREAD_COLOR)
img = cv2.resize(image, (256, 256), interpolation=cv2.INTER_CUBIC)
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
l, a, b = cv2.split(lab)
mean_l = np.mean(l)
std_l = np.std(l)
mean_a = np.mean(a)
std_a = np.std(a)
mean_b = np.mean(b)
std_b = np.std(b)
return np.array([mean_l, std_l, mean_a, std_a, mean_b, std_b])
cv2.imread读取图像。cv2.resize调整图像大小。cv2.cvtColor将图像从BGR颜色空间转换到LAB颜色空间。cv2.split分离LAB颜色空间的三个通道。- 计算每个通道的均值和标准差,并将结果组合成一个特征数组。
第三步:特征增强与组合
在图像分类任务中,特征增强是一种提升特征表达能力的技术,它可以帮助改善模型的性能。
# 初始化PowerTransformer
pt = PowerTransformer(method='box-cox')
PowerTransformer是 scikit-learn 库中的一个类,用于执行幂变换,这里特别使用的是 Box-Cox 变换,这是一种用于稳定数据方差和使数据更接近正态分布的变换方法。
# 定义特征增强变换函数
def feature_enhancement(features, level):
if level == 1:
return features
elif level == 2:
return features * 1.2 # 特征放大
elif level == 3:
return np.log1p(features) # 对数变换
elif level == 4:
return np.sqrt(features) # 平方根变换
elif level == 5:
features_positive = features - np.min(features) + 1 # 平移并加1以确保所有值都是正数
return pt.fit_transform(features_positive.reshape(-1, 1)).flatten() # Box-Cox变换
feature_enhancement函数根据传入的level参数对特征进行不同的增强操作。level == 1时,特征不做变换。level == 2时,特征进行放大,乘以1.2。level == 3时,特征进行对数变换,使用np.log1p来避免对0取对数。level == 4时,特征进行平方根变换。level == 5时,特征进行 Box-Cox 变换,首先确保所有值都是正数,然后应用变换。
# 定义特征提取函数列表
feature_funcs = [
extract_histogram_features,
extract_hog_features,
extract_lbp_features,
extract_color_moments_features
]
feature_funcs是一个包含四个特征提取函数的列表,每个函数对应于一种特征提取方法。
def combine_features(image_path, feature_funcs):
features = np.hstack([func(image_path) for func in feature_funcs])
return features
combine_features函数接受一个图像路径和特征提取函数列表作为参数。- 它通过列表推导式调用每个特征提取函数,并将结果水平堆叠(
np.hstack)成一个统一的特征向量。 - 这个特征向量包含了从同一图像中提取的所有特征,可以用于后续的模型训练和测试。
这一步骤通过特征增强和特征组合,为模型提供了更丰富、更具表达力的特征集。特征增强可以帮助模型捕捉到数据中的更多信息,而特征组合则允许模型从多个角度理解图像内容,从而提高分类的准确性。这种方法在处理高维数据和复杂问题时尤为重要,能够显著提升模型的性能。
第四步:模型训练与评估
在完成了特征提取和增强之后,下一步是对分类模型进行训练和评估。
def evaluate_accuracy(clf, XX_train, Y_train, XX_test, Y_test):
clf.fit(XX_train, Y_train)
Y_pred = clf.predict(XX_test)
return accuracy_score(Y_test, Y_pred)
evaluate_accuracy函数接受一个分类器clf和训练、测试数据集作为参数。- 使用
clf.fit对训练数据进行拟合(训练)。 - 使用
clf.predict对测试数据进行预测。 - 使用
accuracy_score计算预测结果的准确率。
# 测试不同的特征提取方法
features_methods = {
'histogram': extract_histogram_features,
'hog': extract_hog_features,
'lbp': extract_lbp_features,
'color_moments': extract_color_moments_features,
}
features_methods字典包含了四种不同的特征提取方法,每个方法对应一个函数。
# 存储准确率结果
accuracy_results = {}
accuracy_results字典用于存储每种特征提取方法和增强级别下的准确率结果。
# 进度条
total_iterations = len(features_methods)*5 # 5 levels
pbar = tqdm(total=total_iterations, desc="Processing", unit="method")
- 初始化一个进度条,用于显示处理进度。总共需要处理
features_methods中的每个方法在5个增强级别下的情况。
# 定义一个函数来训练和评估模型
def train_and_evaluate(feature_name, feature_func, level):
XX_train_features = np.array([feature_enhancement(feature_func(i), level) for i in X_train])
XX_test_features = np.array([feature_enhancement(feature_func(i), level) for i in X_test])
classifiers = {
'SVM': SVC(kernel="linear", probability=True),
'Decision Tree': DecisionTreeClassifier(),
'KNN': KNeighborsClassifier(n_neighbors=11),
'Naive Bayes': BernoulliNB()
}
for classifier_name, clf in classifiers.items():
accuracy = evaluate_accuracy(clf, XX_train_features, Y_train, XX_test_features, Y_test)
print(f"Feature: {feature_name}, Level: {level}, {classifier_name}: {accuracy:.4f}")
accuracy_results[(feature_name, level, classifier_name)] = accuracy
pbar.update(1) # 更新进度条
train_and_evaluate函数接受特征名称、特征提取函数和增强级别作为参数。- 对训练和测试数据集中的每个图像路径应用特征提取和增强函数,生成特征矩阵。
- 遍历所有分类器,对每种分类器使用
evaluate_accuracy函数评估准确率,并打印结果。 - 将结果存储在
accuracy_results字典中,并更新进度条。
# 使用线程池来并行执行训练和评估
with ThreadPoolExecutor(max_workers=4) as executor:
# 提交任务到线程池
for feature_name, feature_func in features_methods.items():
for level in range(1, 6): # 五档特征处理
executor.submit(train_and_evaluate, feature_name, feature_func, level)
pbar.close()
- 使用
ThreadPoolExecutor并行执行训练和评估任务,以提高效率。 - 对每种特征提取方法和每个增强级别,提交一个
train_and_evaluate任务到线程池。 - 关闭进度条。
运行结果
| 特征提取方法 | 分类器 | Level 1 | Level 2 | Level 3 | Level 4 | Level 5 |
|---|---|---|---|---|---|---|
| histogram | SVM | 0.7950 | 0.7950 | 0.8100 | 0.8600 | 0.8350 |
| 决策树 | 0.5650 | 0.5500 | 0.5600 | 0.5650 | 0.5000 | |
| KNN | 0.5600 | 0.5600 | 0.5750 | 0.6950 | 0.6250 | |
| 朴素贝叶斯 | 0.6250 | 0.6250 | 0.6250 | 0.6250 | 0.6250 | |
| hog | SVM | 0.7600 | 0.7600 | 0.7600 | 0.7600 | 0.7400 |
| 决策树 | 0.3600 | 0.4000 | 0.3750 | 0.3950 | 0.2800 | |
| KNN | 0.3300 | 0.3300 | 0.3650 | 0.4000 | 0.4950 | |
| 朴素贝叶斯 | 0.3650 | 0.3650 | 0.3650 | 0.3650 | 0.7000 | |
| lbp | SVM | 0.7150 | 0.7200 | 0.6300 | 0.7100 | 0.0650 |
| 决策树 | 0.5800 | 0.5750 | 0.5550 | 0.5700 | 0.0800 | |
| KNN | 0.6000 | 0.6000 | 0.6500 | 0.6050 | 0.0850 | |
| 朴素贝叶斯 | 0.0650 | 0.0650 | 0.0650 | 0.0650 | 0.0650 | |
| color_moments | SVM | 0.6850 | 0.6900 | 0.6200 | 0.7000 | 0.5450 |
| 决策树 | 0.6900 | 0.6650 | 0.6550 | 0.6600 | 0.5550 | |
| KNN | 0.6650 | 0.6650 | 0.6600 | 0.6900 | 0.5850 | |
| 朴素贝叶斯 | 0.0650 | 0.0650 | 0.0650 | 0.0650 | 0.1600 |
更多推荐



所有评论(0)