基於python3+opencv3遙感影像的湖泊邊界提取

參考:https://baijiahao.baidu.com/s?id=1607856881407380092&wfr=spider&for=pc

首先進行opencv安裝,先安裝Anaconda3,配置好環境,在Anaconda3的python3中安裝opencv-python。

1、選擇遙感影像,本例中選擇的遙感影像爲南京市玄武湖,影像如下:
在這裏插入圖片描述
(實際應用中湖泊數據可能不會這麼分明,需要更近一步研究)

2、導入cv2和numpy,讀取影像

import cv2
import numpy
image = cv2.imread("xwh.jpg")

3、獲取湖泊區域的BGR值,對應三個數值,可以利用軟件提取,軟件如:jcpicker.exe,本例中獲取的湖泊區域的BGR值分別爲90,98,67。提取在該值上下浮動20(可自行修改)區間的值,作爲影像二值化的依據。(補充:影像必須先進行灰度化,然後才進行二值化處理。)對於在湖泊BGR區間內的影像部分賦值爲白色(255),其餘部分賦值爲黑色(0).代碼如下:

BGR = numpy.array([90,98,67])
upper = BGR + 20
lower = BGR - 20
mask = cv2.inRange(image,lower,upper)
cv2.imshow("Mask",mask)

結果命名爲掩膜數據,結果如下圖:
在這裏插入圖片描述
4、OpenCV提供了cv2.findContours()函數提取二值化圖像的輪廓。對上面生成圖片上執行這個函數就可以返回該圖片的區域輪廓。由於執行該函數時會直接修改圖像,因此我們複製一份圖像之傳給cv2.findContours();同時,OpenCV提供了cv2.drawContour()函數繪可以把輪廓疊加到另一張圖片上。

使用cv2.findContours()函數對mask圖片提取輪廓,並調用cv2.drawContour()把輪廓疊加在原始圖像,代碼如下:

(_,contours,hicrarchy) = cv2.findContours(mask.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
print("number of contours:%d" %(len(contours)))
alllakesImage = image.copy()
cv2.drawContours(alllakesImage,contours,-1,(0,0,255),2)
cv2.imshow("Image of All Lake",alllakesImage)

結果如下圖所示:
在這裏插入圖片描述
5、在獲取的輪廓結果圖中我們可以看到,存在衆多的細小板塊,統計結果顯示number of contours:7067,其中contours.sort(key=len,reverse=True)可以對細小斑塊的面積進行排序,代碼如下:

theLargestLake = image.copy()
contours.sort(key=len,reverse=True)
cv2.drawContours(theLargestLake,[contours[0]],-1,(0,0,255),2)
cv2.imshow("Image of the Largest Lake",theLargestLake)

結果如下圖:
在這裏插入圖片描述
注意:由於openvc3中cv2.imshow()函數顯示的結果存在閃退的情況,在最後顯示圖的地方添加cv2.waitKey(),表示一直等待,如果其後存在代碼,不執行。

未完…….正在繼續………

由於上面步驟3中存在,手動賦予像素值的操作,因此考慮,是否可以通過統計直方圖,自動找出該值,即將R、G、B三色道直方圖中的峯值處對應的灰度值作爲輸入。
1、首先對影像進行三通道分離。代碼如下:

image = cv2.imread("xwh.jpg")
# 轉換爲浮點數進行計算
fsrc = np.array(image, dtype=np.float32) /255.0
band = cv2.split(fsrc)

其中band是一個數組,即band[b,g,r].

2、定義一個函數,分別對三色道的直方圖分別進行峯值處的灰度值提取的操作。

def histing(x):
    #求取最大值和最小值 
  (minVal, maxVal, minLoc, maxLoc) = cv2.minMaxLoc(band[x])
    #計算直方圖   
  hist = cv2.calcHist([band[x]], [0], None, [256], [minVal, maxVal])
  n = hist.tolist().index(max(hist)
  plt.plot(hist)
  plt.show()
  return n

結果如下:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
利用這三個值作爲輸入值,分割的結果如下圖,相比手動而言,效果還是差些。結果如下:
在這裏插入圖片描述
在遙感影像分類中,現階段計算機能做的結果還是不如人手動進行的效果好,雖然有些公司或者個人在鼓吹AI、人工智能進行分割效果很好之類,其研究範圍是個例,不具有廣泛的適用性。

遙感影像分割,在現在以及將來都是研究熱點,技術難題尚未解決,期待各位同志繼續努力….

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章