衛星圖像中的船舶檢測Python實例

2021-03-02 海豚數據科學實驗室

衛星圖像是數據科學家可以使用的最豐富的數據源之一。本文將使用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('\rX:{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()

相關焦點

  • 使用Python圖像處理庫Pillow處理圖像文件
    本案例使用圖像處理庫Pillow中的模塊、對象來處理圖像:實現讀取圖像、獲取圖像信息、調整圖像大小、旋轉圖像、平滑圖像、剪切圖像等基本圖像處理任務。CS2.1 安裝PillowPillow是Python中的圖像處理庫(PIL:Python Image Library),提供了了廣泛的文件格式支持,強大的圖像處理能力,主要包括圖像儲存、圖像顯示、格式轉換以及基本的圖像處理操作等。
  • [CVPR 2019] Pose2Seg:檢測免費的人體實例分割
    本文提出了一種人類實例分割的新方法,該方法基於人體姿勢而不是提議區域檢測來分離實例。 本文的一些亮點: 介紹人體姿勢估計和分割是更好地理解人類活動的重要信息。有很多關於這個主題的研究。最流行的深度學習方法之一是Mask R-CNN,它是一個簡單而通用的對象實例分割框架。 即使像Mask-RCNN這樣的方法也可以檢測對象並為圖像中的每個實例生成分割掩碼。
  • Python+OpenCV的基礎圖像處理操作匯總
    它可以用來調整圖像的大小,以適應我們的網頁所需大小,並可以使他們銳化它可以將黑白圖像轉換成彩色照片,或者可以使用著色技術使彩色照片看起來像舊的黑白照片一樣它可以用來增強醫學影像來檢查病人的癌症或其他疾病。在本文中,我們將看到從目錄中讀取圖像、修改圖像並將其存儲在另一個目錄中的函數實現。下面是我們要討論的主要內容。
  • 基於YoloV3衛星圖像的儲油罐容積佔用率研究
    出於這個原因,許多初創公司,如Planet和Orbital Insight,都通過衛星圖像來關注各國的此類活動。Thye收集儲油罐的衛星圖像並估算儲量。但問題是,如何僅憑衛星圖像來估計儲油罐的體積?好吧,只有當儲油罐存在浮頂油罐時才有可能。這種特殊類型的油罐是專門為儲存大量石油產品而設計的,如原油或凝析油。
  • 使用Python+OpenCV實現圖像數據採集
    在Anaconda或命令提示符中鍵入conda create -n opencv python=3.6這將在Python版本3.6中創建一個名為opencv的新環境,可以用正在使用的任何版本替換它。下一步,輸入pip install opencv-python你已經成功安裝了cv2! 現在你可以開始拍照了。
  • Python中的十大圖像處理工具
    圖像處理是分析和操縱數字圖像的過程,旨在提高其質量或從中提取一些信息,然後將其用於某些方面。圖像處理中的常見任務包括顯示圖像,基本操作(如裁剪、翻轉、旋轉等),圖像分割,分類和特徵提取,圖像恢復和圖像識別等。 Python之成為圖像處理任務的最佳選擇,是因為這一科學程式語言日益普及,並且其自身免費提供許多最先進的圖像處理工具。
  • Serverless 架構下 Python 輕鬆搞定圖像分類
    簡介: 本文將會通過一個有趣的 Python 庫,快速將圖像分類的功能搭建在雲函數上,並且和 API 網關結合,對外提供 API 功能,實現一個 Serverless 架構的「圖像分類 API」。前言圖像分類是人工智慧領域的一個熱門話題。通俗解釋就是,根據各自在圖像信息中所反映的不同特徵,把不同類別的目標區分開來的圖像處理方法。
  • Python中判斷數字是否為質數的實例講解
    在本篇文章裡小編給大家分享了關於python中判斷數字是否為質數的實例講解內容,有興趣的朋友們可以學習下。
  • 深度學習中的圖像分割:方法和應用
    圖像分析有三個層次:分類 - 將整幅圖片分成「人」、「動物」、「戶外」等類別目標檢測 - 檢測圖像中的目標並在其周圍畫一個矩形,例如一個人或一隻羊。分割 - 識別圖像的部分,並理解它們屬於什麼對象。分割是進行目標檢測和分類的基礎。
  • 目標檢測之公開圖像數據集
    在PASCALVOC中是多任務的,包括圖像分類,目標檢測,語義分割和行為檢測。在目標檢測中有兩個Pascal-VOC版本:VOC07和VOC12,其中前者有5k張圖像和27k個被標註目標,後者則有11k張圖像和27k個被標註的目標。
  • Python中有哪些內置函數呢?以及內置函數實例
    #python軟體學習#>Python中有哪些內置函數呢?高級內置函數enumerate 返回一個可以枚舉的對象eval 取出 字符串中的內容,將字符串str當成有效的表達式來求指並返回計算結果exec 執行字符串或complie方法編譯過的字符串
  • 驗證碼識別實例,python簡單圖像處理和實現
    python圖像裁剪我們璇兒Python作為原型語言,因為它的庫最容易使用和部署。經過簡單搜索,我找到了PIL庫。還用到了Image模塊,用來操作圖像進行字符裁剪並將圖像作為加載為數字矩陣。:我將他打包到一個循環中,編寫了一個簡單的腳本,從該站點獲取500個驗證碼圖像,並將所有裁剪後的字符保存到一個文件夾中。
  • opencv-python獲取圖像:面向對象與面向過程
    獲取圖像的方式有:1,讀取本地圖片,2,調用筆記本自帶攝像頭或usb攝像頭,3,調用網絡攝像頭。Lena圖像在科研領域流行的原因:1.該圖適度的混合了細節、平滑區域、陰影和紋理,從而能很好的測試各種圖像處理算法。2.Lenna是個美女,對於圖像處理界的研究者(大部分都是男性)來說,美女圖可以有效地吸引他們來做研究。
  • 10個Python爬蟲入門實例
    爬蟲,準備了幾個簡單的入門實例,分享給大家。涉及主要知識點:web是如何交互的requests庫的get、post函數的應用response對象的相關函數,屬性python文件的打開,保存代碼中給出了注釋,並且可以直接運行哦如何安裝requests庫(安裝好python的朋友可以直接參考,沒有的,
  • 視角| 從衛星圖像看澳大利亞火災與隱患
    數月以來,我們可以從不同媒體中看到澳大利亞幾乎每個州都有林火在燃燒。其中維多利亞州和新南威爾斯州正處於本州數十年來最嚴重的火災季節之一。經過數月的異常炎熱,乾燥的天氣,大火至少導致了數千人的逃難與數億隻動物的死亡,並摧毀了2000多所房屋。毫無疑問,火災現場的照片震驚了世界,但是從太空拍攝到的衛星圖像則更能顯示澳大利亞人必須面對的艱巨問題。各國的媒體與衛星觀測機構每日都在更新著這場大火的最新信息。
  • Python中的運算符,如何通過算術運算符計算數據,實例操作演示
    什麼是Python的運算符在計算機系統中,變量就是存放數據的一個容器,簡單來說變量是用來存儲數據的,存儲數據最基本的作用就是為了運算,運算就會使用到運算符,那麼python中的運算符有哪些?例子中,1和 2被稱為操作數,"+" 稱為運算符。
  • Python 圖像處理 OpenCV (1):入門
    安裝OpenCV 在 Python 中有兩個類庫,一個是 opencv-python ,另一個是 opencv-contrib-python 。opencv-python 是只包含了主要模塊的包,而 opencv-contrib-python 包含了主要模塊以及一些擴展模塊,帶一些收費或者專利的算法,還有一些比較新的算法的高級版本。
  • 詳解計算機視覺五大技術:圖像分類、對象檢測、目標跟蹤、語義分割和實例分割
    智能汽車:計算機視覺仍然是檢測交通標誌、燈光和其他視覺特徵的主要信息來源。視覺識別是計算機視覺的關鍵組成部分,如圖像分類、定位和檢測。神經網絡和深度學習的最新進展極大地推動了這些最先進的視覺識別系統的發展。在本文中,我將分享 5 種主要的計算機視覺技術,並介紹幾種基於計算機視覺技術的深度學習模型與應用。
  • 「Python+cv2」Python安裝opencv及圖像的基本操作
    檢查python環境上面可以看出python版本是3.7。調用exit()函數可以退出python。3、安裝opencvpython環境下opencv的安裝:pip3 install opencv-python
  • Python系列之三——人臉檢測、人臉識別
    比詹小白還要白的童鞋可以查看往期文章進行了解噢1.人臉識別(一)——從零說起2.人臉識別(二)——訓練分類器3.人臉識別(二)——訓練分類器的補充說明4.人臉識別(三)——源碼放送一、人臉檢測      python版人臉檢測基本上可以參照C++版本的程序,根據語法不同進行改寫即可。