123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- import os
- import pandas as pd
- from PIL import Image
- from sklearn.decomposition import PCA
- from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
- import cv2
- import numpy as np
- from skimage import feature
- from skimage.feature import graycomatrix, graycoprops, hog
- from skimage import io, color, img_as_ubyte, exposure
- import matplotlib.pyplot as plt
- def read_and_process_images(folder_path, target_shape):
- image_data = []
- image_labels = []
- image_names = []
- image_paths = []
- for root, dirs, files in os.walk(folder_path):
- for file in files:
- fileLower = file.lower()
- if fileLower.endswith(".jpg") or fileLower.endswith(".png") or fileLower.endswith(".jpeg"): # 仅处理 jpg 和 png 格式的图像文件
- image_path = os.path.join(root, file)
- image = Image.open(image_path).convert('L') # 转换为灰度图像
- resized_image = image.resize(target_shape) # 调整图像大小
- image_array = np.array(resized_image).reshape(-1) # 将图像转换为一维数组
- image_data.append(image_array)
- image_labels.append(os.path.basename(root)) # 文件夹名称作为标签
- image_names.append(file)
- image_paths.append(image_path)
- image_data = np.array(image_data)
- image_labels = np.array(image_labels)
- image_names = np.array(image_names)
- image_paths = np.array(image_paths)
- return image_data, image_labels, image_names, image_paths
- def save_to_csv(data, labels, names, paths, pca_projection, lda_projection, output_file):
- num_pca_components = pca_projection.shape[1]
- num_lda_components = lda_projection.shape[1]
- columns = ['类别', '图片名', '图片路径'] + [f'pca_{i}' for i in range(num_pca_components)] + [f'lda_{i}' for i in range(num_lda_components)]
- df = pd.DataFrame(columns=columns)
- for i in range(len(data)):
- row_data = np.concatenate(([labels[i]], [names[i]], [paths[i]], pca_projection[i], lda_projection[i]))
- df.loc[i] = row_data
- df.to_csv(output_file, index=False)
- print(f"Data saved to {output_file}")
- '''将keypoints转换为可以使用的向量'''
- def keypoints_to_vector(keypoints):
- # 创建一个空的向量列表
- vectors = []
- # 遍历所有关键点
- for kp in keypoints:
- # 提取关键点的属性
- x = kp.pt[0] # x 坐标
- y = kp.pt[1] # y 坐标
- scale = kp.size # 尺度
- orientation = kp.angle # 方向
- # 将关键点属性组合成一个向量
- vector = np.array([x, y, scale, orientation])
- # 添加到向量列表中
- vectors.append(vector)
- # 将列表转换为 numpy 数组
- vectors = np.array(vectors)
- return vectors
- def feature_glcm(input_img_path,blockPlt=True):
- gray_image = io.imread(input_img_path)
- # gray_image = io.imread('data/TRAIN/BTR70/HB04039.004.jpeg')
- gray_image = img_as_ubyte(gray_image)
- # 定义GLCM参数
- distances = [1, 2, 3, 4] # 邻距离
- angles = [0, np.pi / 4, np.pi / 2, 3 * np.pi / 4] # 邻角度
- # 计算GLCM
- glcm = graycomatrix(gray_image, distances=distances, angles=angles, symmetric=True, normed=True)
- # 计算GLCM特征
- contrast = graycoprops(glcm, prop='contrast')
- dissimilarity = graycoprops(glcm, prop='dissimilarity')
- homogeneity = graycoprops(glcm, prop='homogeneity')
- energy = graycoprops(glcm, prop='energy')
- correlation = graycoprops(glcm, prop='correlation')
- # 打印GLCM特征
- # print("Contrast:", contrast)
- # print("Dissimilarity:", dissimilarity)
- # print("Homogeneity:", homogeneity)
- # print("Energy:", energy)
- # print("Correlation:", correlation)
- # 保存GLCM特征图,保持目录结构
- glcm_dir = 'glcm'
- glcm_img_path = os.path.join(glcm_dir, input_img_path)
- glcm_img_dir = os.path.dirname(glcm_img_path)
- os.makedirs(glcm_img_dir, exist_ok=True)
- # 保存GLCM Energy特征图
- io.imsave(glcm_img_path, energy)
- fea = np.concatenate([contrast,dissimilarity,homogeneity,energy,correlation]).flatten()
- return fea
- def feature_hog(input_img_path, blockPlt=True):
- image = io.imread(input_img_path)
- # 提取HOG特征
- features, hog_image = hog(image, pixels_per_cell=(8, 8), cells_per_block=(2, 2), visualize=True)
- # # 可视化HOG图像
- # fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
- # print(len(features))
- # print(hog_image.shape)
- # 对HOG图像进行对比度增强
- hog_image_rescaled = exposure.rescale_intensity(hog_image, in_range=(0, 10))
- # plt.imshow(hog_image_rescaled,cmap='gray')
- # 保存HOG图像,保持目录结构
- hog_dir = 'hog'
- hog_img_path = os.path.join(hog_dir, input_img_path)
- hog_img_dir = os.path.dirname(hog_img_path)
- os.makedirs(hog_img_dir, exist_ok=True)
- io.imsave(hog_img_path, hog_image_rescaled)
- return features
- def feature_lbp(input_img_path,blockPlt=True):
- # 定义LBP算子的计算函数
- def calculate_lbp_pixel(center, pixels):
- lbp_code = 0
- for i, pixel in enumerate(pixels):
- lbp_code |= (pixel >= center) << i
- return lbp_code
- # 定义LBP特征提取函数
- def extract_lbp_features(image, radius, num_points):
- gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
- height, width = gray.shape
- lbp_image = np.zeros((height, width), dtype=np.uint8)
- for y in range(radius, height - radius):
- for x in range(radius, width - radius):
- center = gray[y, x]
- pixels = [
- gray[y - radius, x - radius],
- gray[y - radius, x],
- gray[y - radius, x + radius],
- gray[y, x + radius],
- gray[y + radius, x + radius],
- gray[y + radius, x],
- gray[y + radius, x - radius],
- gray[y, x - radius]
- ]
- lbp_code = calculate_lbp_pixel(center, pixels)
- lbp_image[y, x] = lbp_code
- hist = np.histogram(lbp_image, bins=np.arange(0, num_points + 2), range=(0, num_points + 1))[0]
- hist = hist.astype("float")
- hist /= (hist.sum() + 1e-6) # 归一化
- return hist
- # 加载图像
- image = cv2.imread(input_img_path)
- # 读取图像并转换为灰度图
- # image = cv2.imread('./data/TRAIN/2S1/HB19404.jpg', cv2.IMREAD_GRAYSCALE)
- # image = io.imread('./data/TRAIN/2S1/HB19404.jpg')#color.rgb2gray(image)
- # print(image.shape)
- # 设置LBP算子的半径和邻域点数
- radius = 1
- num_points = 8 * radius
- # 提取LBP特征
- lbp_features = extract_lbp_features(image, radius, num_points)
- # 打印特征向量
- # print("LBP特征向量:")
- # print(lbp_features)
- # 计算LBP特征
- image = io.imread(input_img_path)
- radius = 1
- n_points = 8 * radius
- lbp_image = feature.local_binary_pattern(image, n_points, radius, method='uniform')
- # 保存LBP特征图,保持目录结构
- lbp_dir = 'lbp'
- lbp_img_path = os.path.join(lbp_dir, input_img_path)
- lbp_img_dir = os.path.dirname(lbp_img_path)
- os.makedirs(lbp_img_dir, exist_ok=True)
- cv2.imwrite(lbp_img_path, lbp_image)
- return lbp_features
- def feature_orb(input_img_path,blockPlt=True):
- image = io.imread(input_img_path)
- # 创建ORB对象
- orb = cv2.ORB_create()
- # 检测ORB特征点
- keypoints, descriptors = orb.detectAndCompute(image, None)
- # 绘制特征点
- image_with_keypoints = cv2.drawKeypoints(image, keypoints, None)
- # 保存带有特征点的图像,保持目录结构
- orb_dir = 'orb'
- orb_img_path = os.path.join(orb_dir, input_img_path)
- orb_img_dir = os.path.dirname(orb_img_path)
- os.makedirs(orb_img_dir, exist_ok=True)
- cv2.imwrite(orb_img_path, image_with_keypoints)
- fea_keypoints = keypoints_to_vector(keypoints)
- fea_keypoints = fea_keypoints.flatten()
- return fea_keypoints
- def feature_shift(input_img_path,blockPlt=True):
- image = io.imread(input_img_path)
- # 创建SIFT特征检测器
- sift = cv2.SIFT_create()
- # 检测关键点和提取描述符
- keypoints, descriptors = sift.detectAndCompute(image, None)
- # print(keypoints)
- # print(descriptors)
- # 显示关键点
- output_image = cv2.drawKeypoints(image, keypoints, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
- # 保存带有特征点的图像,保持目录结构
- sift_dir = 'sift'
- sift_img_path = os.path.join(sift_dir, input_img_path)
- sift_img_dir = os.path.dirname(sift_img_path)
- os.makedirs(sift_img_dir, exist_ok=True)
- cv2.imwrite(sift_img_path, output_image)
- fea_keypoints = keypoints_to_vector(keypoints)
- fea_keypoints = fea_keypoints.flatten()
- return fea_keypoints
- #
- #
- # def batch_pca_lda():
- # # 文件夹路径
- # # folder_path = 'data/TEST/'
- # folder_path = 'data/TRAIN/'
- # # 图像调整大小
- # target_shape = (100, 100)
- # # PCA 和 LDA 的主成分数量
- # pca_components = 128
- # lda_components = 7 # lda降维数目不能超过类别数目
- # # 输出 CSV 文件名
- # # output_file = 'sar_test_pca_lda.csv'
- # output_file = 'sar_train_pca_lda.csv'
- #
- # # 读取并处理图像数据
- # image_data, image_labels, image_names, image_paths = read_and_process_images(folder_path, target_shape)
- #
- # # 使用 PCA 进行降维
- # pca = PCA(n_components=pca_components)
- # pca_projection = pca.fit_transform(image_data)
- #
- # # 使用 LDA 进行降维
- # lda = LDA(n_components=lda_components)
- # lda_projection = lda.fit_transform(image_data, image_labels)
- #
- # # 保存数据到 CSV 文件
- # save_to_csv(image_data, image_labels, image_names, image_paths, pca_projection, lda_projection, output_file)
- # 传入输入图像路径以及需要展示的特征,展示特征图像
- def display_feature(input_img_path, fea_type):
- fea_dir = fea_type
- fea_img_path = os.path.join(fea_dir, input_img_path)
- if os.path.exists(fea_img_path):
- fea_img = io.imread(fea_img_path)
- plt.imshow(fea_img, cmap='gray')
- plt.show()
- else:
- print(f"Feature image not found at {fea_img_path}")
- if __name__ == '__main__':
- # batch_pca_lda()
- img_path = 'D:\\hiddz\\SAR\\test_data\\TEST\\2S1\\HB14936.JPG'
- fea = feature_glcm(img_path, False)
- fea = feature_hog(img_path, False)
- fea = feature_lbp(img_path,False)
- fea = feature_orb(img_path,False)
- fea = feature_shift(img_path,False)
- print(fea)
- display_feature(img_path,'glcm')
- display_feature(img_path, 'hog')
- display_feature(img_path,'lbp')
- display_feature(img_path,'orb')
- display_feature(img_path,'sift')
|