卫星图像中的船舶检测Python实例
卫星图像是数据科学家可以使用的最丰富的数据源之一。本文将使用Kaggle上的机器学习数据集(https://www.kaggle.com/rhammell/ships-in-satellite-imagery),此机器学习数据:
- 包括4000个80x80 RGB图像,标记为“ship”或“no-ship”分类,值为1或0。
- 机器学习数据集为.png图像,图像文件名遵循特定格式:{label} __ {scene id} __ {longitude} _ {latitude} .png
- longitude_latitude:图像中心点的经度和纬度坐标
- dataset也作为JSON格式的文本文件分发,包含:data,label,scene_ids和location list
- 单个图像的像素值数据存储为19200个整数的列表:第一个6400包含红色通道,下一个6400包含绿色,最后的6400包含蓝色。
- labels,scene_ids和位置中的索引i处的列表值,每个对应于数据列表中的第i个图像
- 类标签:“ship”类包括1000个图像,靠近单个船体的中心。“no-ship”类包括3000幅图像,1/3是不同土地覆盖特征的随机抽样(不包括船舶的任何部分),1/3是“部分船只”,1/3是先前被错误标记的图像。
我们想要实现的目标:检测卫星图像中船舶的位置,可用于解决以下问题:监控港口活动和供应链分析。
导入Python库
import json, sys, random import numpy as np from keras.models import Sequential from keras.layers import Dense, Flatten, Activation from keras.layers import Dropout from keras.layers.convolutional import Conv2D, MaxPooling2D from keras.utils import np_utils from keras.optimizers import SGD import keras.callbacks from PIL import Image, ImageDraw from matplotlib import pyplot as plt
读取和准备数据
除了常规的Keras: sequence、density、Flatten、Activation和Dropout也将使用Conv2D和MaxPooling2D。现在让我们研究机器学习数据集:
# Download and study the data set f = open(r'../ships-in-satellite-imagery/shipsnet.json') dataset = json.load(f) f.close() input_data = np.array(dataset['data']).astype('uint8') output_data = np.array(dataset['labels']).astype('uint8') # the data set contains 4000 images. # One image is represented as a vector of lenght 19200 elements = [(image size: 80x80=6400) * 3 RGB bands] input_data.shape
(4000, 19200)
input_data
# to be able to read an image we need to reshape the array/input_data n_spectrum = 3 # color chanel RGB weight = 80 height = 80 X = input_data.reshape([-1, n_spectrum, weight, height]) X[0].shape
(3, 80, 80)
# get one channel pic = X[3] red_spectrum = pic[0] green_spectrum = pic[1] blue_spectrum = pic[2]
在3个通道上绘制照片:
plt.figure(2, figsize = (5*3, 5*1)) plt.set_cmap('jet') #show each channel plt.subplot(1, 3, 1) plt.imshow(red_spectrum) plt.subplot(1, 3, 2) plt.imshow(green_spectrum) plt.subplot(1, 3, 3) plt.imshow(blue_spectrum) plt.show()
如果X[0]的一些照片可能具有所有3个bands RGB相同,不要灰心,只要尝试另一个X[3]。
我们的输出是4000个元素的向量:
output_data.shape
(4000,)
output_data
array([1, 1, 1, ..., 0, 0, 0], dtype=uint8)
np.bincount(output_data)
array([3000, 1000])
为keras准备数据
首先对标签进行分类编码:
# output encoding y = np_utils.to_categorical(output_data, 2)
shuffle所有索引:
# shuffle all indexes indexes = np.arange(4000) np.random.shuffle(indexes)
选择X_train,y_train:
X_train = X[indexes].transpose([0,2,3,1]) y_train = y[indexes]
当然还有归一化:
# normalization X_train = X_train/255
训练模型/神经网络
np.random.seed(42) # network design model = Sequential() model.add(Conv2D(32, (3, 3), padding='same', input_shape=(80, 80, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) #40x40 model.add(Dropout(0.25)) model.add(Conv2D(32, (3, 3), padding='same', activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) #20x20 model.add(Dropout(0.25)) model.add(Conv2D(32, (3, 3), padding='same', activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) #10x10 model.add(Dropout(0.25)) model.add(Conv2D(32, (10, 10), padding='same', activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) #5x5 model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(512, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(2, activation='softmax'))
设置优化器
# optimization setup sgd = SGD(lr=0.01, momentum=0.9, nesterov=True) model.compile( loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
训练神经网络
# training model.fit( X_train, y_train, batch_size=32, epochs=18, validation_split=0.2, shuffle=True, verbose=2)
在图像上应用模型和搜索
image = Image.open(r'../ships-in-satellite-imagery/scenes/sfbay_1.png') pix = image.load() plt.imshow(image)
'plt.imshow(image)'如果你想快速浏览一下,为了能够正确使用它,我们需要创建一个向量:
n_spectrum = 3 width = image.size[0] height = image.size[1] # creat vector picture_vector = [] for chanel in range(n_spectrum): for y in range(height): for x in range(width): picture_vector.append(pix[x, y][chanel]) picture_vector = np.array(picture_vector).astype('uint8') picture_tensor = picture_vector.reshape([n_spectrum, height, width]).transpose(1, 2, 0) plt.figure(1, figsize = (15, 30)) plt.subplot(3, 1, 1) plt.imshow(picture_tensor) plt.show()
现在让我们在图像上搜索船只
picture_tensor = picture_tensor.transpose(2,0,1) # Search on the image def cutting(x, y): area_study = np.arange(3*80*80).reshape(3, 80, 80) for i in range(80): for j in range(80): area_study[0][i][j] = picture_tensor[0][y+i][x+j] area_study[1][i][j] = picture_tensor[1][y+i][x+j] area_study[2][i][j] = picture_tensor[2][y+i][x+j] area_study = area_study.reshape([-1, 3, 80, 80]) area_study = area_study.transpose([0,2,3,1]) area_study = area_study / 255 sys.stdout.write(' X:{0} Y:{1} '.format(x, y)) return area_study def not_near(x, y, s, coordinates): result = True for e in coordinates: if x+s > e[0][0] and x-s < e[0][0] and y+s > e[0][1] and y-s < e[0][1]: result = False return result def show_ship(x, y, acc, thickness=5): for i in range(80): for ch in range(3): for th in range(thickness): picture_tensor[ch][y+i][x-th] = -1 for i in range(80): for ch in range(3): for th in range(thickness): picture_tensor[ch][y+i][x+th+80] = -1 for i in range(80): for ch in range(3): for th in range(thickness): picture_tensor[ch][y-th][x+i] = -1 for i in range(80): for ch in range(3): for th in range(thickness): picture_tensor[ch][y+th+80][x+i] = -1 step = 10; coordinates = [] for y in range(int((height-(80-step))/step)): for x in range(int((width-(80-step))/step) ): area = cutting(x*step, y*step) result = model.predict(area) if result[0][1] > 0.90 and not_near(x*step,y*step, 88, coordinates): coordinates.append([[x*step, y*step], result]) print(result) plt.imshow(area[0]) plt.show()
正如您所看到的那样:它确实分类为具有直线和明亮像素的船舶图像。
再试一次:
现在让我们理解标签并在图像上找到它们:
for e in coordinates: show_ship(e[0][0], e[0][1], e[1][0][1]) #picture_tensor = picture_tensor.transpose(2,0,1) picture_tensor = picture_tensor.transpose(1,2,0) picture_tensor.shape
(1777, 2825, 3)
plt.figure(1, figsize = (15, 30)) plt.subplot(3,1,1) plt.imshow(picture_tensor) plt.show()
相关推荐
YENCSDN 2020-11-17
lsjweiyi 2020-11-17
houmenghu 2020-11-17
Erick 2020-11-17
HeyShHeyou 2020-11-17
以梦为马不负韶华 2020-10-20
lhtzbj 2020-11-17
夜斗不是神 2020-11-17
pythonjw 2020-11-17
dingwun 2020-11-16
lhxxhl 2020-11-16
坚持是一种品质 2020-11-16
染血白衣 2020-11-16
huavhuahua 2020-11-20
meylovezn 2020-11-20
逍遥友 2020-11-20
weiiron 2020-11-16