by小凡君m---2024.8.24
随机森林土地利用分类代码详解
1. 导入必要的工具包
import numpy as np
from PIL import Image
from sklearn.ensemble import RandomForestClassifier
import matplotlib.pyplot as plt
import rasterio
numpy
:这是一个非常强大的数学库,主要用于处理数组和矩阵。在这个代码中,我们用它来处理图像数据。PIL (Python Imaging Library)
:这个库用于打开、处理和保存各种图片格式。在这里,我们用它来加载和处理图片。sklearn.ensemble.RandomForestClassifier
:这是一个机器学习库,特别是用来创建和训练“随机森林”分类器,它是一种很强大的分类模型,可以根据输入的数据来预测结果。matplotlib.pyplot
:这是一个绘图库,能够将数据以图像的形式展示出来。我们用它来显示分类后的图片。rasterio
:这个库专门用于处理地理空间数据,比如卫星图像。如果你处理的是卫星图像,这个库会很有用。
2. 定义土地利用类型
land_use_classes = {
0: 'Forest',
1: 'Farmland',
2: 'Water',
3: 'Urban'
}
land_use_classes
:这是一个字典,类似于一个对照表。它将每种土地利用类型(比如森林、耕地、水体、城镇)对应到一个数字。这些数字将用于模型的训练和预测。
3. 加载普通图片
def load_image(image_path):
with Image.open(image_path) as img:
img = img.convert('RGB') # 转换为RGB
return np.array(img)
load_image
:这个函数用来从文件中加载一张图片。- 它首先打开图片 (
Image.open(image_path)
),然后将图片转换为RGB格式(红、绿、蓝三色)——这一步是为了确保图片是彩色的。 - 最后,它将图片转换为一个NumPy数组,这样我们就可以像处理数据一样来处理图片了。
- 它首先打开图片 (
4. 加载卫星图片
def load_satellite_image(image_path):
with rasterio.open(image_path) as dataset:
img = dataset.read([1, 2, 3]) # 读取前三个波段
return np.transpose(img, (1, 2, 0)) # 转置以匹配(R, G, B)
load_satellite_image
:这个函数是用来加载卫星图像的。- 它使用
rasterio
来读取图像文件,并且只读取前三个波段(通常代表红、绿、蓝),因为我们只关心这些颜色信息。 - 然后,它会转置数据,使得它的结构与普通RGB图片一致。
- 它使用
5. 手动选择特征点
def define_feature_points(image):
feature_points = {
'Forest': np.array([[15, 20], [25, 35], [40, 45]]),
'Farmland': np.array([[55, 60], [65, 75], [70, 85]]),
'Water': np.array([[105, 110], [115, 120], [125, 130]]),
'Urban': np.array([[155, 160], [165, 170], [175, 180]])
}
X, y = [], []
for class_name, points in feature_points.items():
label = list(land_use_classes.keys())[list(land_use_classes.values()).index(class_name)]
for point in points:
x, y_coord = point
X.append(image[y_coord, x, :])
y.append(label)
return np.array(X), np.array(y)
define_feature_points
:这个函数的作用是手动选择一些代表性的像素点,并将它们标记为不同的土地利用类型(如森林、耕地等)。feature_points
是一个字典,其中每个类别(如Forest
、Farmland
等)都对应一组手动选择的像素坐标(x, y)。- 在这个函数中,我们会遍历每个类别,并提取这些像素的颜色值(RGB)。这些颜色值会存储在
X
数组中,类别标签会存储在y
数组中。 - 最后返回两个数组:
X
包含颜色值,y
包含对应的类别标签。
6. 使用模型对整张图片进行分类
def classify_image(image, model):
X = image.reshape(-1, 3)
y_pred = model.predict(X)
return y_pred.reshape(image.shape[:2])
classify_image
:这个函数将训练好的模型应用于整张图片,以预测每个像素的类别。- 首先,它将图片展平为一个二维数组
X
,其中每个元素是一个像素的RGB值。 - 然后,它使用模型来预测每个像素的类别。
- 最后,它将预测结果重新整形成图片的原始形状,以便我们可以直接查看分类结果。
- 首先,它将图片展平为一个二维数组
7. 主函数
def main():
image_path = 'path_to_your_image.jpg' # 替换为你的图片路径
satellite_path = 'path_to_your_satellite_image.tif' # 卫星图片路径(若有)
image = load_image(image_path)
# 如果使用卫星图片,替换上面的 image 变量
# image = load_satellite_image(satellite_path)
X, y = define_feature_points(image)
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X, y)
classified_image = classify_image(image, rf)
plt.figure(figsize=(10, 10))
plt.imshow(classified_image, cmap='viridis')
plt.title('Classified Land Use')
plt.show()
classified_image_pil = Image.fromarray(classified_image.astype(np.uint8))
classified_image_pil.save('classified_image.jpg')
print("分类完成,结果已保存为 'classified_image.jpg'.")
main
:- 这是程序的主入口,代码会从这里开始执行。
- 首先,它会加载你指定的图片(普通图片或卫星图像)。
- 接着,它会通过
define_feature_points
函数生成训练数据。 - 然后,它会创建一个随机森林模型,并使用手动选择的特征点进行训练。
- 模型训练完成后,会对整张图片进行分类。
- 最后,它会将分类结果显示出来,并保存为一张新图片。
8. 执行主程序
if __name__ == '__main__':
main()
__name__ == '__main__'
:这部分确保当你直接运行这个脚本时,main
函数会被调用,从而开始整个分类过程。
总结
这个代码实现了一个简单的土地利用分类器,通过手动选择代表不同土地利用类型的像素点,使用随机森林模型来对整张图片进行分类。整个过程包括加载图片、选择特征点、训练模型、分类图片,并最终将分类结果保存为新图片。这个模型的效果很大程度上取决于你手动选择的特征点的准确性。
Comments NOTHING