137 lines
4.8 KiB
Python
137 lines
4.8 KiB
Python
import cv2
|
|
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
from PIL import Image
|
|
import os
|
|
from znzh_x import PredictionVisualizer
|
|
|
|
class SimpleChangeVisualizer:
|
|
def __init__(self):
|
|
self.fig_size = (15, 10)
|
|
|
|
def visualize_change_detection(self, img1_path, img2_path, mask_path, save_path=None):
|
|
"""
|
|
简单的变化检测可视化
|
|
|
|
Args:
|
|
img1_path: 第一期影像路径
|
|
img2_path: 第二期影像路径
|
|
mask_path: 预测掩膜路径
|
|
save_path: 保存路径(可选)
|
|
"""
|
|
# 读取图像
|
|
img1 = cv2.imread(img1_path)
|
|
img2 = cv2.imread(img2_path)
|
|
mask = cv2.imread(mask_path, cv2.IMREAD_GRAYSCALE)
|
|
|
|
if img1 is None or img2 is None or mask is None:
|
|
print("错误:无法读取图像文件")
|
|
return
|
|
|
|
# 转换颜色空间
|
|
img1_rgb = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
|
|
img2_rgb = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)
|
|
|
|
# 创建变化区域的彩色掩膜
|
|
change_mask = np.zeros_like(img2_rgb)
|
|
change_mask[mask > 127] = [255, 0, 0] # 红色表示变化
|
|
|
|
# 创建叠加图像
|
|
overlay1 = cv2.addWeighted(img1_rgb, 0.7, change_mask, 0.3, 0)
|
|
overlay2 = cv2.addWeighted(img2_rgb, 0.7, change_mask, 0.3, 0)
|
|
|
|
# 创建subplot
|
|
fig, axes = plt.subplots(2, 3, figsize=self.fig_size)
|
|
fig.suptitle('变化检测结果可视化', fontsize=16, fontweight='bold')
|
|
|
|
# 第一行:原始图像
|
|
axes[0, 0].imshow(img1_rgb)
|
|
axes[0, 0].set_title('第一期影像', fontsize=12)
|
|
axes[0, 0].axis('off')
|
|
|
|
axes[0, 1].imshow(img2_rgb)
|
|
axes[0, 1].set_title('第二期影像', fontsize=12)
|
|
axes[0, 1].axis('off')
|
|
|
|
axes[0, 2].imshow(mask, cmap='gray')
|
|
axes[0, 2].set_title('变化检测掩膜', fontsize=12)
|
|
axes[0, 2].axis('off')
|
|
|
|
# 第二行:叠加结果
|
|
axes[1, 0].imshow(overlay1)
|
|
axes[1, 0].set_title('第一期影像+变化区域', fontsize=12)
|
|
axes[1, 0].axis('off')
|
|
|
|
axes[1, 1].imshow(overlay2)
|
|
axes[1, 1].set_title('第二期影像+变化区域', fontsize=12)
|
|
axes[1, 1].axis('off')
|
|
|
|
# 变化统计
|
|
total_pixels = mask.size
|
|
changed_pixels = np.sum(mask > 127)
|
|
change_ratio = (changed_pixels / total_pixels) * 100
|
|
|
|
stats_text = f"""变化统计信息:
|
|
|
|
总像素数: {total_pixels:,}
|
|
变化像素数: {changed_pixels:,}
|
|
变化比例: {change_ratio:.2f}%
|
|
"""
|
|
|
|
axes[1, 2].text(0.1, 0.5, stats_text, fontsize=11,
|
|
verticalalignment='center', transform=axes[1, 2].transAxes,
|
|
bbox=dict(boxstyle="round,pad=0.3", facecolor="lightblue"))
|
|
axes[1, 2].set_title('统计信息', fontsize=12)
|
|
axes[1, 2].axis('off')
|
|
|
|
plt.tight_layout()
|
|
|
|
if save_path:
|
|
plt.savefig(save_path, dpi=300, bbox_inches='tight')
|
|
print(f"可视化结果已保存到: {save_path}")
|
|
|
|
plt.show()
|
|
|
|
return fig
|
|
|
|
def batch_visualize(self, img1_dir, img2_dir, mask_dir, output_dir):
|
|
"""
|
|
批量可视化处理
|
|
"""
|
|
os.makedirs(output_dir, exist_ok=True)
|
|
|
|
mask_files = [f for f in os.listdir(mask_dir) if f.endswith('.png')]
|
|
|
|
for mask_file in mask_files:
|
|
base_name = os.path.splitext(mask_file)[0]
|
|
|
|
img1_path = os.path.join(img1_dir, base_name + '.png')
|
|
img2_path = os.path.join(img2_dir, base_name + '.png')
|
|
mask_path = os.path.join(mask_dir, mask_file)
|
|
save_path = os.path.join(output_dir, f'{base_name}_visualization.png')
|
|
|
|
if os.path.exists(img1_path) and os.path.exists(img2_path):
|
|
print(f"处理: {base_name}")
|
|
self.visualize_change_detection(img1_path, img2_path, mask_path, save_path)
|
|
else:
|
|
print(f"跳过: {base_name} (缺少对应的影像文件)")
|
|
|
|
# 使用示例
|
|
if __name__ == "__main__":
|
|
visualizer = SimpleChangeVisualizer()
|
|
|
|
# 单个文件可视化示例
|
|
# visualizer.visualize_change_detection(
|
|
# img1_path="path/to/image1.png",
|
|
# img2_path="path/to/image2.png",
|
|
# mask_path="path/to/mask.png",
|
|
# save_path="path/to/result.png"
|
|
# )
|
|
|
|
# 批量处理示例
|
|
img1_dir = "/media/data0/HL/2025-7-6/val/image1"
|
|
img2_dir = "/media/data0/HL/2025-7-6/val/image2"
|
|
mask_dir = "/media/data0/HL/CropLand-CD-main_3/CropLand-CD-main/save"
|
|
output_dir = "/media/data0/HL/CropLand-CD-main_3/CropLand-CD-main/visualizations"
|
|
|
|
visualizer.batch_visualize(img1_dir, img2_dir, mask_dir, output_dir) |