216 lines
7.0 KiB
Python
216 lines
7.0 KiB
Python
# coding: utf-8
|
||
# The code is written by Linghui
|
||
|
||
import numpy as np
|
||
from skimage import data
|
||
from matplotlib import pyplot as plt
|
||
import get_glcm
|
||
import time
|
||
from PIL import Image
|
||
import spectral
|
||
import os
|
||
import warnings
|
||
warnings.filterwarnings('ignore')
|
||
|
||
# 使用get_glcm模块进行GLCM计算
|
||
|
||
def main():
|
||
pass
|
||
|
||
|
||
def load_hyperspectral_data(image_path, band_index=None):
|
||
"""
|
||
加载高光谱数据并可选地提取指定波段
|
||
|
||
参数:
|
||
- image_path: 高光谱图像文件路径
|
||
- band_index: 要提取的波段索引,如果为None则返回整个图像
|
||
|
||
返回:
|
||
- img: 处理后的图像数据
|
||
- h, w: 图像尺寸
|
||
"""
|
||
print(f'正在读取高光谱图像: {image_path}')
|
||
|
||
try:
|
||
# 使用spectral库读取ENVI格式
|
||
img_obj = spectral.open_image(image_path)
|
||
hyperspectral_data = img_obj.load()
|
||
print(f'使用spectral库读取成功,数据形状: {hyperspectral_data.shape}')
|
||
except Exception as e:
|
||
print(f'spectral库读取失败: {e}')
|
||
raise ValueError(f"无法读取图像文件: {image_path}")
|
||
|
||
# 检查数据维度
|
||
if len(hyperspectral_data.shape) != 3:
|
||
raise ValueError(f"高光谱数据应该是3维的,当前形状: {hyperspectral_data.shape}")
|
||
|
||
h, w, bands = hyperspectral_data.shape
|
||
print(f'图像尺寸: {h}x{w}, 波段数: {bands}')
|
||
|
||
# 如果指定了波段索引,提取该波段
|
||
if band_index is not None:
|
||
if band_index < 0 or band_index >= bands:
|
||
raise ValueError(f"波段索引 {band_index} 超出范围 [0, {bands-1}]")
|
||
|
||
print(f'提取波段 {band_index}...')
|
||
img = hyperspectral_data[:, :, band_index].astype(np.float32)
|
||
|
||
# 归一化到0-255范围
|
||
img_min, img_max = img.min(), img.max()
|
||
if img_max > img_min:
|
||
img = np.uint8(255.0 * (img - img_min) / (img_max - img_min))
|
||
else:
|
||
img = np.zeros_like(img, dtype=np.uint8)
|
||
|
||
print(f'提取的波段数据范围: [{img_min:.2f}, {img_max:.2f}] -> [0, 255]')
|
||
else:
|
||
# 如果没有指定波段,返回第一个波段作为示例
|
||
print('未指定波段,使用第一个波段...')
|
||
img = hyperspectral_data[:, :, 0].astype(np.float32)
|
||
img_min, img_max = img.min(), img.max()
|
||
if img_max > img_min:
|
||
img = np.uint8(255.0 * (img - img_min) / (img_max - img_min))
|
||
else:
|
||
img = np.zeros_like(img, dtype=np.uint8)
|
||
|
||
return img, h, w
|
||
|
||
|
||
if __name__ == '__main__':
|
||
|
||
main()
|
||
|
||
start = time.time()
|
||
|
||
print('---------------0. Parameter Setting-----------------')
|
||
nbit = 64 # gray levels
|
||
mi, ma = 0, 255 # max gray and min gray
|
||
slide_window = 7 # sliding window
|
||
# step = [2, 4, 8, 16] # step
|
||
# angle = [0, np.pi/4, np.pi/2, np.pi*3/4] # angle or direction
|
||
step = [2]
|
||
angle = [0]
|
||
|
||
# 指定波段索引(可以修改)
|
||
band_index = 25 # 要处理的波段索引,从0开始
|
||
|
||
print('-------------------1. Load Data---------------------')
|
||
# 修改为高光谱图像路径
|
||
image_path = r"C:\Program Files\Spectronon3\_internal\examples\leaf_small.bip.hdr"
|
||
# image_path = r"./test.tif" # 备用的TIFF图像路径
|
||
|
||
# 检查文件是否存在
|
||
if not os.path.exists(image_path):
|
||
print(f"警告: 指定的图像文件不存在: {image_path}")
|
||
print("请确保文件路径正确,或使用其他可用的图像文件")
|
||
exit(1)
|
||
|
||
# 加载高光谱数据
|
||
img, h, w = load_hyperspectral_data(image_path, band_index)
|
||
print('------------------2. 计算GLCM特征---------------------')
|
||
img = img.squeeze()
|
||
# 使用get_glcm计算GLCM特征
|
||
glcm = get_glcm.calcu_glcm(img, mi, ma, nbit, slide_window, step, angle)
|
||
|
||
print('GLCM计算完成!')
|
||
print('-----------------3. 提取纹理特征-------------------')
|
||
|
||
# 提取纹理特征用于显示
|
||
# 只计算最后一个step和angle的特征用于显示
|
||
i, j = len(step)-1, len(angle)-1 # 使用最后一个配置
|
||
glcm_cut = glcm[:, :, i, j, :, :]
|
||
mean = get_glcm.calcu_glcm_mean(glcm_cut, nbit)
|
||
variance = get_glcm.calcu_glcm_variance(glcm_cut, nbit)
|
||
homogeneity = get_glcm.calcu_glcm_homogeneity(glcm_cut, nbit)
|
||
contrast = get_glcm.calcu_glcm_contrast(glcm_cut, nbit)
|
||
dissimilarity = get_glcm.calcu_glcm_dissimilarity(glcm_cut, nbit)
|
||
entropy = get_glcm.calcu_glcm_entropy(glcm_cut, nbit)
|
||
energy = get_glcm.calcu_glcm_energy(glcm_cut, nbit)
|
||
correlation = get_glcm.calcu_glcm_correlation(glcm_cut, nbit)
|
||
Auto_correlation = get_glcm.calcu_glcm_Auto_correlation(glcm_cut, nbit)
|
||
print('---------------4. Display and Result----------------')
|
||
print(f'使用的波段: {band_index}')
|
||
print(f'GLCM参数: distances={step}, angles={[f"{a*180/np.pi:.0f}°" for a in angle]}')
|
||
|
||
plt.figure(figsize=(10, 4.5))
|
||
font = {'family' : 'Times New Roman',
|
||
'weight' : 'normal',
|
||
'size' : 12,
|
||
}
|
||
|
||
plt.subplot(2,5,1)
|
||
plt.tick_params(labelbottom=False, labelleft=False)
|
||
plt.axis('off')
|
||
plt.imshow(img, cmap ='gray')
|
||
plt.title(f'Band {band_index}', font)
|
||
|
||
plt.subplot(2,5,2)
|
||
plt.tick_params(labelbottom=False, labelleft=False)
|
||
plt.axis('off')
|
||
plt.imshow(mean, cmap ='gray')
|
||
plt.title('Mean', font)
|
||
|
||
plt.subplot(2,5,3)
|
||
plt.tick_params(labelbottom=False, labelleft=False)
|
||
plt.axis('off')
|
||
plt.imshow(variance, cmap ='gray')
|
||
plt.title('Variance', font)
|
||
|
||
plt.subplot(2,5,4)
|
||
plt.tick_params(labelbottom=False, labelleft=False)
|
||
plt.axis('off')
|
||
plt.imshow(homogeneity, cmap ='gray')
|
||
plt.title('Homogeneity', font)
|
||
|
||
plt.subplot(2,5,5)
|
||
plt.tick_params(labelbottom=False, labelleft=False)
|
||
plt.axis('off')
|
||
plt.imshow(contrast, cmap ='gray')
|
||
plt.title('Contrast', font)
|
||
|
||
plt.subplot(2,5,6)
|
||
plt.tick_params(labelbottom=False, labelleft=False)
|
||
plt.axis('off')
|
||
plt.imshow(dissimilarity, cmap ='gray')
|
||
plt.title('Dissimilarity', font)
|
||
|
||
plt.subplot(2,5,7)
|
||
plt.tick_params(labelbottom=False, labelleft=False)
|
||
plt.axis('off')
|
||
plt.imshow(entropy, cmap ='gray')
|
||
plt.title('Entropy', font)
|
||
|
||
plt.subplot(2,5,8)
|
||
plt.tick_params(labelbottom=False, labelleft=False)
|
||
plt.axis('off')
|
||
plt.imshow(energy, cmap ='gray')
|
||
plt.title('Energy', font)
|
||
|
||
plt.subplot(2,5,9)
|
||
plt.tick_params(labelbottom=False, labelleft=False)
|
||
plt.axis('off')
|
||
plt.imshow(correlation, cmap ='gray')
|
||
plt.title('Correlation', font)
|
||
|
||
plt.subplot(2,5,10)
|
||
plt.tick_params(labelbottom=False, labelleft=False)
|
||
plt.axis('off')
|
||
plt.imshow(Auto_correlation, cmap ='gray')
|
||
plt.title('Auto Correlation', font)
|
||
|
||
plt.tight_layout(pad=0.5)
|
||
|
||
# 创建输出文件名,包含波段信息
|
||
output_filename = f'GLCM_Features_Band{band_index}.png'
|
||
plt.savefig(output_filename
|
||
, format='png'
|
||
, bbox_inches = 'tight'
|
||
, pad_inches = 0
|
||
, dpi=300)
|
||
print(f'结果图像已保存到: {output_filename}')
|
||
|
||
|
||
end = time.time()
|
||
print('Code run time:', end - start)
|