OpenCV与图像处理学习十一——分水岭算法(含代码)
生活随笔
收集整理的這篇文章主要介紹了
OpenCV与图像处理学习十一——分水岭算法(含代码)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
OpenCV與圖像處理學(xué)習(xí)十一——分水嶺算法(含代碼)
- 一、分水嶺算法概要
- 二、分水嶺算法步驟
- 三、代碼應(yīng)用
一、分水嶺算法概要
任意的灰度圖像可以被看做是地質(zhì)學(xué)表面,高亮度的地方是山峰,低亮度的地方是山谷。
給每個(gè)孤立的山谷(局部最小值)不同顏色的水(標(biāo)簽),當(dāng)水漲起來(lái),根據(jù)周?chē)纳椒?#xff08;梯度),不同的山谷也就是不同的顏色會(huì)開(kāi)始合并,要避免山谷合并,需要在水要合并的地方建立分水嶺,直到所有山峰都被淹沒(méi),所創(chuàng)建的分水嶺就是分割邊界線(xiàn),這個(gè)就是分水嶺的原理。
二、分水嶺算法步驟
三、代碼應(yīng)用
""" 完成分水嶺算法步驟: 1、加載原始圖像 2、閾值分割,將圖像分割為黑白兩個(gè)部分 3、對(duì)圖像進(jìn)行開(kāi)運(yùn)算,即先腐蝕在膨脹 4、對(duì)開(kāi)運(yùn)算的結(jié)果再進(jìn)行 膨脹,得到大部分是背景的區(qū)域 5、通過(guò)距離變換 Distance Transform 獲取前景區(qū)域 6、背景區(qū)域sure_bg 和前景區(qū)域sure_fg相減,得到即有前景又有背景的重合區(qū)域 7、連通區(qū)域處理 8、最后使用分水嶺算法 """import cv2 import numpy as np# Step1. 加載圖像 img = cv2.imread('image/yezi.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Step2.閾值分割,將圖像分為黑白兩部分 ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) cv2.imshow("thresh", thresh)# Step3. 對(duì)圖像進(jìn)行“開(kāi)運(yùn)算”,先腐蝕再膨脹 kernel = np.ones((3, 3), np.uint8) opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2) cv2.imshow("opening", opening)# Step4. 對(duì)“開(kāi)運(yùn)算”的結(jié)果進(jìn)行膨脹,得到大部分都是背景的區(qū)域 sure_bg = cv2.dilate(opening, kernel, iterations=3) cv2.imshow("sure_bg", sure_bg)# Step5.通過(guò)distanceTransform獲取前景區(qū)域 dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5) # DIST_L1 DIST_C只能 對(duì)應(yīng)掩膜為3 DIST_L2 可以為3或者5 ret, sure_fg = cv2.threshold(dist_transform, 0.1 * dist_transform.max(), 255, 0)cv2.imshow("sure_fg", sure_fg)# Step6. sure_bg與sure_fg相減,得到既有前景又有背景的重合區(qū)域 #此區(qū)域和輪廓區(qū)域的關(guān)系未知 sure_fg = np.uint8(sure_fg) unknow = cv2.subtract(sure_bg, sure_fg) cv2.imshow("unknow", unknow)# Step7. 連通區(qū)域處理 ret, markers = cv2.connectedComponents(sure_fg, connectivity=8) # 對(duì)連通區(qū)域進(jìn)行標(biāo)號(hào) 序號(hào)為 0 - N-1 markers = markers + 1 # OpenCV 分水嶺算法對(duì)物體做的標(biāo)注必須都 大于1 ,背景為標(biāo)號(hào) 為0 因此對(duì)所有markers 加1 變成了 1 - N # 去掉屬于背景區(qū)域的部分(即讓其變?yōu)?,成為背景) # 此語(yǔ)句的Python語(yǔ)法 類(lèi)似于if ,“unknow==255” 返回的是圖像矩陣的真值表。 markers[unknow==255] = 0# Step8.分水嶺算法 markers = cv2.watershed(img, markers) # 分水嶺算法后,所有輪廓的像素點(diǎn)被標(biāo)注為 -1 print(markers)img[markers == -1] = [0, 0, 255] # 標(biāo)注為-1 的像素點(diǎn)標(biāo) 紅 cv2.imshow("dst", img) cv2.waitKey(0) cv2.destroyAllWindows()原圖為:
使用大津閾值法二值化后的結(jié)果:
開(kāi)運(yùn)算消除一些噪聲(本例不明顯):
做膨脹操作,那么得到的背景區(qū)域一定是背景區(qū)域:
做距離變換操作(或腐蝕),那么得到的前景一定為真正的前景:
中間是既有前景又有背景的重合區(qū)域,此區(qū)域和輪廓區(qū)域的關(guān)系未知:
分水嶺算法之后的效果為:
總結(jié)
以上是生活随笔為你收集整理的OpenCV与图像处理学习十一——分水岭算法(含代码)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: visual assist安装方法
- 下一篇: 从‘一边拉琴,一边哭’,看什么是真正的兴