from keras.models import load_model

# 加载您的 CNN-LSTM 模型
model = load_model(r'C:\Users\jack8\OneDrive\LSTM and ARIMA\LSTM\cnn_lstm_model.h5')


import numpy as np

def image_to_patches(image, patch_size):
    patches = []
    positions = []
    img_height, img_width = image.shape[:2]
    patch_height, patch_width = patch_size
    for y in range(0, img_height, patch_height):
        for x in range(0, img_width, patch_width):
            patch = image[y:y+patch_height, x:x+patch_width]
            # 如果最后的块尺寸不足，进行填充
            if patch.shape[0] != patch_height or patch.shape[1] != patch_width:
                pad_height = patch_height - patch.shape[0]
                pad_width = patch_width - patch.shape[1]
                patch = np.pad(patch, ((0, pad_height), (0, pad_width), (0, 0)), mode='constant')
            patches.append(patch)
            positions.append((y, x))
    return np.array(patches), positions

def patches_to_image(patches, positions, image_shape):
    reconstructed_image = np.zeros(image_shape)
    patch_height, patch_width = patches.shape[2:4]  # 注意维度顺序
    for patch, (y, x) in zip(patches, positions):
        reconstructed_image[y:y+patch_height, x:x+patch_width] = patch[..., :image_shape[0]-y, :image_shape[1]-x]
    return reconstructed_image

from keras_preprocessing.image import img_to_array, load_img

# 加载大图
input_img_path = r"C:\Users\jack8\OneDrive\LSTM and ARIMA\LSTM\data\south\Finish\segmentation-vidas\2020.jpg"
new_img = load_img(input_img_path)
new_img_array = img_to_array(new_img) / 255.0

# 获取原始图像的尺寸
original_height, original_width = new_img_array.shape[:2]


timesteps = 3  # 与训练时一致
patch_size = (128, 128)  # 根据您的模型的输入尺寸调整

# 将大图切割成小块
patches, positions = image_to_patches(new_img_array, patch_size)

predicted_patches = []
for patch in patches:
    # 创建时间序列数据，通过重复同一个小块
    patch_sequence = np.array([patch] * timesteps)
    # 扩展维度以匹配模型输入形状
    patch_input = np.expand_dims(patch_sequence, axis=0)  # 形状为 (1, timesteps, height, width, channels)
    # 进行预测
    prediction = model.predict(patch_input)
    predicted_patches.append(prediction[0])
predicted_patches = np.array(predicted_patches)


# 将预测结果二值化
prediction_binary_patches = (predicted_patches > 0.5).astype(np.uint8)

# 重建预测的掩膜图
prediction_mask = patches_to_image(prediction_binary_patches, positions, (original_height, original_width, 1))



from skimage.transform import resize

# 加载并预处理实际的掩膜图像（mask）
mask_img_path = r"C:\Users\jack8\OneDrive\LSTM and ARIMA\LSTM\data\south\Finish\cover\2020.jpg"
mask_img = load_img(mask_img_path, color_mode='grayscale')
mask_img_array = img_to_array(mask_img) / 255.0
mask_img_array = mask_img_array[:, :, 0]  # 只保留单通道

# 确保实际掩膜的尺寸与预测掩膜一致
if mask_img_array.shape != prediction_mask.shape[:2]:
    # 如果尺寸不一致，调整实际掩膜的尺寸
    mask_img_array_resized = resize(mask_img_array, prediction_mask.shape[:2], preserve_range=True)
else:
    mask_img_array_resized = mask_img_array



    import numpy as np
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, mean_absolute_error, mean_squared_error

# 将预测的掩膜转换为 0 和 1 的二值图像
predicted_mask_binary = prediction_mask[:, :, 0].astype(np.uint8)

# 二值化处理（确保是 0 或 1）
true_values = (mask_img_array_resized > 0.5).astype(np.uint8).flatten()
predicted_values = predicted_mask_binary.flatten()

# 计算评估指标
accuracy = accuracy_score(true_values, predicted_values)
precision = precision_score(true_values, predicted_values, zero_division=0)
recall = recall_score(true_values, predicted_values, zero_division=0)
f1 = f1_score(true_values, predicted_values, zero_division=0)

# 计算 IoU
intersection = np.logical_and(true_values, predicted_values).sum()
union = np.logical_or(true_values, predicted_values).sum()
iou_score = intersection / union if union != 0 else 1

# 计算 Dice 系数
dice_score = 2 * intersection / (true_values.sum() + predicted_values.sum()) if (true_values.sum() + predicted_values.sum()) != 0 else 1

# 输出结果
print("Accuracy (%): {:.2f}%".format(accuracy * 100))
print("Precision (%): {:.2f}%".format(precision * 100))
print("Recall (%): {:.2f}%".format(recall * 100))
print("F1 Score (%): {:.2f}%".format(f1 * 100))
print("IoU (Jaccard Index): {:.4f}".format(iou_score))
print("Dice Coefficient: {:.4f}".format(dice_score))

# 计算 MAE、RMSE、MAPE
mae = mean_absolute_error(true_values, predicted_values)
rmse = np.sqrt(mean_squared_error(true_values, predicted_values))

def mean_absolute_percentage_error(y_true, y_pred):
    non_zero_indices = y_true != 0
    y_true_non_zero = y_true[non_zero_indices]
    y_pred_non_zero = y_pred[non_zero_indices]
    if len(y_true_non_zero) == 0:
        print("Warning: No non-zero elements in y_true. MAPE is undefined.")
        mape = np.nan
    else:
        mape = np.mean(np.abs((y_true_non_zero - y_pred_non_zero) / y_true_non_zero)) * 100
    return mape

mape = mean_absolute_percentage_error(true_values, predicted_values)

print(f"MAE: {mae}")
print(f"RMSE: {rmse}")
print(f"MAPE: {mape}%")


import matplotlib.pyplot as plt

plt.figure(figsize=(18, 6))

# 实际掩膜
plt.subplot(1, 3, 1)
plt.title('Ground Truth Mask')
plt.imshow(mask_img_array_resized, cmap='gray')

# 预测的掩膜
plt.subplot(1, 3, 2)
plt.title('Predicted Mask')
plt.imshow(prediction_mask[:, :, 0], cmap='gray')

# 预测的二值化掩膜
plt.subplot(1, 3, 3)
plt.title('Binary Predicted Mask')
plt.imshow(predicted_mask_binary, cmap='gray')

plt.show()


ValueError: could not broadcast input array from shape (128,128,1) into shape (128,1,1)