
今天給大家推薦一篇高大上的文章:基于OpenCV實現(xiàn)海岸線變化檢測。OpenCV大家都知道,一款開源的計算機(jī)視覺庫,平常大家看到的都是OpenCV人臉識別,圖像處理之類的,今天跟小編一起來看他如何實現(xiàn)海岸線變化檢測的吧。
文章來源: 小白學(xué)視覺
作者:努比
介紹
海岸是一個動態(tài)系統(tǒng),其中因侵蝕現(xiàn)象導(dǎo)致的海岸線后退、或是由眾多因素如氣象,地質(zhì),生物和人類活動所導(dǎo)致線前進(jìn)的是常見現(xiàn)象。
在海洋磨損作用大于沉積物的情況下,有明顯的海岸侵蝕,我們稱之為地球表面的崩解和破壞。
資料來源:弗林德斯大學(xué)(CC0)
本文的目標(biāo)
在本文中,我們將對Landsat 8平臺上的OLI(陸地成像儀)傳感器獲取的衛(wèi)星圖像使用Canny Edge Detection算法。
通過這種方法,我們將能夠可視化的估計特定歐洲地區(qū)遭受強(qiáng)腐蝕作用的海岸線隨時間的推移:霍德內(nèi)斯海岸。
一下是處理流程:
處理流程
在開始之前讓我們先介紹一下OLI數(shù)據(jù)...
0.關(guān)于Landsat OLI數(shù)據(jù)的簡要介紹
Landsat 8是一個軌道平臺,安裝在稱為OLI(陸地成像儀)的11波段多光譜傳感器上。
具體來說,在本文中,我們將僅使用分辨率為30米(即前7個)的波段。
美國地質(zhì)調(diào)查局陸地衛(wèi)星8號
該數(shù)據(jù)可以免費下載,注冊后,獲得USGS:https://earthexplorer.usgs.gov/。
而且,通常我摸并不使用入射太陽光作為原始數(shù)據(jù),而是使用反射率,即從地球表面反射的太陽光量[0-1]。
1.包導(dǎo)入
在各種常見的包,我們將使用rasterio處理圖像,利用OpenCV中的Canny 算法和Scikit-Learn分割圖像。
from glob import glob import numpy as np import rasterio import json, re, itertools, os import matplotlib.pyplot as plt import cv2 as cv from sklearn import preprocessing from sklearn.cluster import KMeans
2.數(shù)據(jù)導(dǎo)入
讓我們定義一個變量,該變量告訴我們要保留的波段數(shù)以及在JSON中輸入的輔助數(shù)據(jù):
N_OPTICS_BANDS = 7 with open("bands.json","r") as bandsJson: bandsCharacteristics = json.load(bandsJson)
這個Json是Landsat OLI成像儀的信息集合。類似于一種說明手冊:
# bands.json [{'id': '1', 'name': 'Coastal aerosol', 'span': '0.43-0.45', 'resolution': '30'}, {'id': '2', 'name': 'Blue', 'span': '0.45-0.51', 'resolution': '30'}, {'id': '3', 'name': 'Green', 'span': '0.53-0.59', 'resolution': '30'}, {'id': '4', 'name': 'Red', 'span': '0.64-0.67', 'resolution': '30'}, {'id': '5', 'name': 'NIR', 'span': '0.85-0.88', 'resolution': '30'}, {'id': '6', 'name': 'SWIR 1', 'span': '1.57-1.65', 'resolution': '30'}, {'id': '7', 'name': 'SWIR 2', 'span': '2.11-2.29', 'resolution': '30'}, {'id': '8', 'name': 'Panchromatic', 'span': '0.50-0.68', 'resolution': '15'}, {'id': '9', 'name': 'Cirrus', 'span': '1-36-1.38', 'resolution': '30'}, {'id': '10', 'name': 'TIRS 1', 'span': '10.6-11.9', 'resolution': '100'}, {'id': '11', 'name': 'TIRS 2', 'span': '11.50-12.51', 'resolution': '100'}]
bands.json文件包含有關(guān)我們將要使用的頻段的所有有用信息。
注意,我們將僅使用分辨率為30 m的頻段,因此僅使用前7個頻段。如果您愿意使用較低的分辨率(100m),則也可以嵌入TIRS 1和TIRS 2頻段。
正如上面幾行已經(jīng)提到的那樣,我們將使用從Landsat-8 OLI上獲取兩組不同的數(shù)據(jù):
? 2014/02/01
? 2019/07/25
為了簡化兩次采集的所需操作,我們將定義一個Acquisition()類,其中將封裝所有必要的函數(shù)。
在執(zhí)行代碼期間,我們能夠執(zhí)行一些基礎(chǔ)支持性的功能,例如:
? 在指定路徑中搜索GeoTIFF;
? 加載采購;
? 購置登記 (調(diào)整);
? 收購子集
class Acquisition: def __init__(self, path, ext, nOpticsBands): self.nOpticsBands = nOpticsBands self._getGeoTIFFs(path, ext) self.images = self._loadAcquisition() def _getGeoTIFFs(self, path, ext): # It searches for GeoTIFF files within the folder. print("Searching for '%s' files in %s" % (ext, path)) self.fileList = glob(os.path.join(path,"*."+ext)) self.opticsFileList = [ [list(filter(re.compile(r"band%s\."%a).search, self.fileList))[0] for a in range(1,self.nOpticsBands+1)] print("Found %d 'tif' files" % len(self.opticsFileList)) def _loadAcquisition(self): # It finally reads and loads selected images into arrays. print("Loading images") self.loads = [rasterio.open(bandPath) for bandPath in self.opticsFileList] images = [load.read()[0] for load in self.loads] print("Done") return images def subsetImages(self, w1, w2, h1, h2, leftBound): # This function subsets images according the defined sizes. print("Subsetting images (%s:%s, %s:%s)" % (w1, w2, h1, h2)) cols = (self.loads[0].bounds.left - leftBound)/30 registered = [np.insert(band,np.repeat(0,cols),0,axis=1) for band in self.images] subset = [band[w1:w2,h1:h2] for band in registered] print("Done") return subset
好的,讓我們現(xiàn)在開始啟動整個代碼:
DATES = ["2014-02-01", "2019-07-25"] acquisitionsObjects = [] for date in DATES: singleAcquisitionObject = Acquisition("Data/"+date, "tif", N_OPTICS_BANDS) acquisitionsObjects.append( singleAcquisitionObject )
運行結(jié)果如下:
Searching for 'tif' files in Data/2014-02-01
Found 7 'tif' files
Loading images
Done
Searching for 'tif' files in Data/2019-07-25
Found 7 'tif' files
Loading images
Done
現(xiàn)在我們已加載了14張OLI圖像(在7個波段中各采集2個)。
2.1 子集多光譜立方體
在這個階段中,先對兩個多光譜立方體進(jìn)行“對齊”(或正式注冊),再切出不感興趣的部分。
我們可以使用ImageImages()函數(shù)“剪切”不需要的數(shù)據(jù)。
因此,我們定義AOI(感興趣的區(qū)域),并使用Acquisition()類中的subsetImages()函數(shù)進(jìn)行設(shè)置:
W1, W2 = 950, 2300 H1, H2 = 4500, 5300 subAcquisitions = [acquisition.subsetImages(W1, W2, H1, H2, 552285.0) for acquisition in acquisitionsObjects].
完成!
3.數(shù)據(jù)探索
3.1可視化多光譜立方體
讓我們嘗試查看2019/07/25收購的所有范圍。出于純粹的美學(xué)原因,在繪制圖像之前,讓我們使用
StandardScaler()對圖像進(jìn)行標(biāo)準(zhǔn)化。
axs = range(N_OPTICS_BANDS) fig, axs = plt.subplots(2, 4, figsize=(15,12)) axs = list(itertools.chain.from_iterable(axs)) for b in range(N_OPTICS_BANDS): id_ = bandsCharacteristics[b]["id"] name_ = bandsCharacteristics[b]["name"] span_ = bandsCharacteristics[b]["span"] resolution_ = bandsCharacteristics[b]["resolution"] title = "%s - %s\n%s (%s m)" % (id_, name_, span_, resolution_) axs[b].imshow(preprocessing.StandardScaler().fit_transform(subAcquisitions[1][b]), cmap="Greys_r") axs[b].set_title(title); axs[b].set_xticklabels([]); axs[b].set_yticklabels([]) plt.axis("off"); plt.tight_layout(w_pad=-10); plt.show()
以下是運行結(jié)果。
這些圖中,有些波段比其他波段更亮。這很正常。
3.2可視化復(fù)合RGB中的多光譜立方體
現(xiàn)在,讓我們嘗試可視化使用波段4(紅色),3(綠色)和2(藍(lán)色)獲得的RGB復(fù)合圖像中的兩次采集。
定義BIAS和GAIN 僅是為了獲得更好的效果。
BIAS = 1.5 GAIN = [2.3,2.4,1.4] r1 = (subAcquisitions[0][3] - subAcquisitions[0][3].min()) / (subAcquisitions[0][3].max()-subAcquisitions[0][3].min()) * GAIN[0] * BIAS g1 = (subAcquisitions[0][2] - subAcquisitions[0][2].min()) / (subAcquisitions[0][2].max()-subAcquisitions[0][2].min()) * GAIN[1] * BIAS b1 = (subAcquisitions[0][1] - subAcquisitions[0][1].min()) / (subAcquisitions[0][1].max()-subAcquisitions[0][1].min()) * GAIN[2] * BIAS r2 = (subAcquisitions[1][3] - subAcquisitions[1][3].min()) / (subAcquisitions[1][3].max()-subAcquisitions[1][3].min()) * GAIN[0] * BIAS g2 = (subAcquisitions[1][2] - subAcquisitions[1][2].min()) / (subAcquisitions[1][2].max()-subAcquisitions[1][2].min()) * GAIN[1] * BIAS b2 = (subAcquisitions[1][1] - subAcquisitions[1][1].min()) / (subAcquisitions[1][1].max()-subAcquisitions[1][1].min()) * GAIN[2] * BIAS rgbImage1, rgbImage2 = np.zeros((W2-W1,H2-H1,3)), np.zeros((W2-W1,H2-H1,3)) rgbImage1[:,:,0], rgbImage2[:,:,0] = r1, r2 rgbImage1[:,:,1], rgbImage2[:,:,1] = g1, g2 rgbImage1[:,:,2], rgbImage2[:,:,2] = b1, b2 fig, (ax1,ax2) = plt.subplots(1,2,figsize=(16,12)) ax1.imshow(rgbImage1); ax2.imshow(rgbImage2) ax1.set_title("RGB\n(Bands 4-3-2)\n2014-02-01"); ax2.set_title("RGB\n(Bands 4-3-2)\n2019-07-25") plt.show()
結(jié)果如下圖所示!有趣的是,這兩次獲取的反射率完全的不同。
好的,繼續(xù)進(jìn)行海岸線檢測。
4.自動化海岸線檢測
在本段中,我們將使用Canny的算法執(zhí)行邊緣檢測。
在進(jìn)行實際檢測之前,有必要準(zhǔn)備數(shù)據(jù)集,嘗試通過聚類算法對數(shù)據(jù)集進(jìn)行分割以區(qū)分海洋和陸地。
4.1數(shù)據(jù)準(zhǔn)備
在此階段,我們將重塑兩個多光譜立方體以進(jìn)行聚類操作。
4.2用K均值進(jìn)行圖像分割
我們通過k均值對這兩次采集進(jìn)行細(xì)分(使用自己喜歡的模型即可)。
4.3細(xì)分結(jié)果
這是確定的代表新興土地和水體的兩個集群。
4.4Canny邊緣檢測算法
Canny的傳統(tǒng)鍵技術(shù)分為以下幾個階段:
1. 高斯濾波器通過卷積降低噪聲;
2. 四個方向(水平,垂直和2個傾斜)的圖像梯度計算;
3. 梯度局部最大值的提取;
4. 帶有滯后的閾值,用于邊緣提取。
讓我們開始,將聚類結(jié)果轉(zhuǎn)換為圖像,然后通過具有15x15內(nèi)核的高斯濾波器降低噪聲:
clusteredImages = [clusterLabels.reshape(subAcquisitions[0][0].shape).astype("uint8") for clusterLabels in clusters] blurredImages = [cv.GaussianBlur(clusteredImage, (15,15), 0) for clusteredImage in clusteredImages] fig, (ax1, ax2) = plt.subplots(1,2,figsize=(16,13)) ax1.imshow(blurredImages[0]) ax1.set_title("2014-02-01\nGaussian Blurred Image") ax2.imshow(blurredImages[1]) ax2.set_title("2019-07-25\nGaussian Blurred Image") plt.show()
在圖像稍微模糊之后,我們可以使用OpenCV Canny()模塊:
rawEdges = [cv.Canny(blurredImage, 2, 5).astype("float").reshape(clusteredImages[0].shape) for blurredImage in blurredImages] edges = [] for edge in rawEdges: edge[edge == 0] = np.nan edges.append(edge)
在單行代碼中,我們獲得了梯度,提取了局部最大值,然后對每次采集都應(yīng)用了帶有滯后的閾值。
注意:我們可以使用不同參數(shù)Canny()來探索處理結(jié)果。
4.5結(jié)果
plt.figure(figsize=(16,30)) plt.imshow(rgbImage2) plt.imshow(edges[0], cmap = 'Set3_r') plt.imshow(edges[1], cmap = 'Set1') plt.title('CoastLine') plt.show()
以下是一些詳細(xì)信息:
5結(jié)論
從結(jié)果中可以看到,Canny的算法在其原始管道中運行良好,但其性能通常取決于所涉及的數(shù)據(jù)。
實際上,所使用的聚類算法使我們能夠?qū)Χ喙庾V立方體進(jìn)行細(xì)分。并行使用多個聚類模型可以總體上改善結(jié)果。
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
LSTM 模型輸入長度選擇技巧:提升序列建模效能的關(guān)鍵? 在循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)家族中,長短期記憶網(wǎng)絡(luò)(LSTM)憑借其解決長序列 ...
2025-07-11CDA 數(shù)據(jù)分析師報考條件詳解與準(zhǔn)備指南? ? 在數(shù)據(jù)驅(qū)動決策的時代浪潮下,CDA 數(shù)據(jù)分析師認(rèn)證愈發(fā)受到矚目,成為眾多有志投身數(shù) ...
2025-07-11數(shù)據(jù)透視表中兩列相乘合計的實用指南? 在數(shù)據(jù)分析的日常工作中,數(shù)據(jù)透視表憑借其強(qiáng)大的數(shù)據(jù)匯總和分析功能,成為了 Excel 用戶 ...
2025-07-11尊敬的考生: 您好! 我們誠摯通知您,CDA Level I和 Level II考試大綱將于 2025年7月25日 實施重大更新。 此次更新旨在確保認(rèn) ...
2025-07-10BI 大數(shù)據(jù)分析師:連接數(shù)據(jù)與業(yè)務(wù)的價值轉(zhuǎn)化者? ? 在大數(shù)據(jù)與商業(yè)智能(Business Intelligence,簡稱 BI)深度融合的時代,BI ...
2025-07-10SQL 在預(yù)測分析中的應(yīng)用:從數(shù)據(jù)查詢到趨勢預(yù)判? ? 在數(shù)據(jù)驅(qū)動決策的時代,預(yù)測分析作為挖掘數(shù)據(jù)潛在價值的核心手段,正被廣泛 ...
2025-07-10數(shù)據(jù)查詢結(jié)束后:分析師的收尾工作與價值深化? ? 在數(shù)據(jù)分析的全流程中,“query end”(查詢結(jié)束)并非工作的終點,而是將數(shù) ...
2025-07-10CDA 數(shù)據(jù)分析師考試:從報考到取證的全攻略? 在數(shù)字經(jīng)濟(jì)蓬勃發(fā)展的今天,數(shù)據(jù)分析師已成為各行業(yè)爭搶的核心人才,而 CDA(Certi ...
2025-07-09【CDA干貨】單樣本趨勢性檢驗:捕捉數(shù)據(jù)背后的時間軌跡? 在數(shù)據(jù)分析的版圖中,單樣本趨勢性檢驗如同一位耐心的偵探,專注于從單 ...
2025-07-09year_month數(shù)據(jù)類型:時間維度的精準(zhǔn)切片? ? 在數(shù)據(jù)的世界里,時間是最不可或缺的維度之一,而year_month數(shù)據(jù)類型就像一把精準(zhǔn) ...
2025-07-09CDA 備考干貨:Python 在數(shù)據(jù)分析中的核心應(yīng)用與實戰(zhàn)技巧? ? 在 CDA 數(shù)據(jù)分析師認(rèn)證考試中,Python 作為數(shù)據(jù)處理與分析的核心 ...
2025-07-08SPSS 中的 Mann-Kendall 檢驗:數(shù)據(jù)趨勢與突變分析的有力工具? ? ? 在數(shù)據(jù)分析的廣袤領(lǐng)域中,準(zhǔn)確捕捉數(shù)據(jù)的趨勢變化以及識別 ...
2025-07-08備戰(zhàn) CDA 數(shù)據(jù)分析師考試:需要多久?如何規(guī)劃? CDA(Certified Data Analyst)數(shù)據(jù)分析師認(rèn)證作為國內(nèi)權(quán)威的數(shù)據(jù)分析能力認(rèn)證 ...
2025-07-08LSTM 輸出不確定的成因、影響與應(yīng)對策略? 長短期記憶網(wǎng)絡(luò)(LSTM)作為循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)的一種變體,憑借獨特的門控機(jī)制,在 ...
2025-07-07統(tǒng)計學(xué)方法在市場調(diào)研數(shù)據(jù)中的深度應(yīng)用? 市場調(diào)研是企業(yè)洞察市場動態(tài)、了解消費者需求的重要途徑,而統(tǒng)計學(xué)方法則是市場調(diào)研數(shù) ...
2025-07-07CDA數(shù)據(jù)分析師證書考試全攻略? 在數(shù)字化浪潮席卷全球的當(dāng)下,數(shù)據(jù)已成為企業(yè)決策、行業(yè)發(fā)展的核心驅(qū)動力,數(shù)據(jù)分析師也因此成為 ...
2025-07-07剖析 CDA 數(shù)據(jù)分析師考試題型:解鎖高效備考與答題策略? CDA(Certified Data Analyst)數(shù)據(jù)分析師考試作為衡量數(shù)據(jù)專業(yè)能力的 ...
2025-07-04SQL Server 字符串截取轉(zhuǎn)日期:解鎖數(shù)據(jù)處理的關(guān)鍵技能? 在數(shù)據(jù)處理與分析工作中,數(shù)據(jù)格式的規(guī)范性是保證后續(xù)分析準(zhǔn)確性的基礎(chǔ) ...
2025-07-04CDA 數(shù)據(jù)分析師視角:從數(shù)據(jù)迷霧中探尋商業(yè)真相? 在數(shù)字化浪潮席卷全球的今天,數(shù)據(jù)已成為企業(yè)決策的核心驅(qū)動力,CDA(Certifie ...
2025-07-04CDA 數(shù)據(jù)分析師:開啟數(shù)據(jù)職業(yè)發(fā)展新征程? ? 在數(shù)據(jù)成為核心生產(chǎn)要素的今天,數(shù)據(jù)分析師的職業(yè)價值愈發(fā)凸顯。CDA(Certified D ...
2025-07-03