欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

OpenCV圖像分割之分水嶺算法與圖像金字塔算法詳解

 更新時(shí)間:2021年12月28日 14:47:20   作者:機(jī)器視覺(jué)小學(xué)徒  
本文主要介紹了OpenCV中的分水嶺算法、圖像金字塔對(duì)圖像進(jìn)行分割的方法。文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)OpenCV有一定的幫助,需要的可以參考一下

前言

主要介紹OpenCV中的分水嶺算法、圖像金字塔對(duì)圖像進(jìn)行分割的方法。

一、使用分水嶺算法分割圖像

分水嶺算法的基本原理為:將任意的灰度圖像視為地形圖表面,其中灰度值高的部分表示山峰和丘陵,而灰度值低的地方表示山谷。用不同顏色的水(標(biāo)簽)填充每個(gè)獨(dú)立的山谷(局部最小值);隨著水平面的上升,來(lái)自不同山谷(具有不同顏色)的水將開(kāi)始合并。為了避免出現(xiàn)這種情況,需要在水匯合的位置建造水壩;持續(xù)填充水和建造水壩,直到所有的山峰和丘陵都在水下。整個(gè)過(guò)程中建造的水壩將作為圖像分割的依據(jù)。

使用分水嶺算法執(zhí)行圖像分割操作時(shí)通常包含下列步驟:

(1) 將原圖轉(zhuǎn)換為灰度圖像

(2) 應(yīng)用形態(tài)變換中的開(kāi)運(yùn)算和膨脹操作,去除圖像噪聲,獲得圖像邊緣信息,確定圖像背景

(3) 進(jìn)行距離轉(zhuǎn)換,再進(jìn)行閾值處理,確定圖像前景

(4) 確定圖像的未知區(qū)域(用圖像的背景減去前景剩余的部分)

(5) 標(biāo)記背景圖像

(6) 執(zhí)行分水嶺算法分割圖像

1、cv2.distanceTransform()函數(shù)

OpenCV中的cv2.distanceTransform()函數(shù)用于計(jì)算非0值像素點(diǎn)到0值(背景)像素點(diǎn)的距離,其基本格式如下:

dst = cv2.distanceTransform(src, distanceType, maskSize[, dstType])

dst為返回的距離轉(zhuǎn)換結(jié)果圖像

src為原圖像, 必須是8為單通道二值圖像

distanceType為距離類(lèi)型

maskSize為掩膜的大小, 可設(shè)置為0, 3或5

dstType為返回的圖像類(lèi)型, 默認(rèn)值為CV_32F(32位浮點(diǎn)數(shù))

import cv2
import numpy as np
import matplotlib.pyplot as plt

# cv2.distanceTransform()函數(shù),計(jì)算非0值像素點(diǎn)到0值(背景)像素點(diǎn)的距離
img = cv2.imread('home.jpg')
cv2.imshow('original', img)

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 										# 灰度操作
cv2.imshow('gray', img_gray)

ret, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) 	# 閾值操作
cv2.imshow('thresh', thresh)

kernel = np.ones((3, 3), np.uint8)
img_open = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2) 				# 形態(tài)學(xué)操作
cv2.imshow('open', img_open)

img_dilate = cv2.dilate(img_open, kernel, iterations=2)    								# 膨脹操作,確定背景
cv2.imshow('img_dilate', img_dilate)

img_dist = cv2.distanceTransform(img_dilate , cv2.DIST_L2, 5) 							# 距離轉(zhuǎn)換
cv2.imshow('img_dist', img_dist)

cv2.waitKey(0)
cv2.destroyAllWindows()

2、cv2.connectedComponents()函數(shù)

OpenCV中的cv2.connectedComponents()函數(shù)用于將圖像中的背景標(biāo)記為0,將其他圖像標(biāo)記為從1開(kāi)始的整數(shù),其基本格式如下:

ret, labels = cv2.connectedComponents(image[, connectivity[, ltype]])

labels為返回的標(biāo)記結(jié)果圖像, 和image大小一樣

image為要標(biāo)記的8位單通道圖像

connectivity為4或8(默認(rèn)值), 表示連接性

ltype為返回的標(biāo)記結(jié)果圖像的類(lèi)型

# cv2.connectedComponents()函數(shù),將圖像中的背景標(biāo)記為0,將其他圖像標(biāo)記為從1開(kāi)始的整數(shù)
ret, imgfg = cv2.threshold(img_dist, 0.7*img_dist.max(), 255, cv2.THRESH_TRUNC)

imgfg = np.uint8(imgfg)

ret, markers = cv2.connectedComponents(imgfg)

plt.imshow(imgfg,cmap='gray')
plt.title('imgfg') 
plt.axis('off')
plt.show()

plt.imshow(markers,cmap='gray')
plt.title('markers') 
plt.axis('off')
plt.show()

3、cv2.watershed()函數(shù)

OpenCV中的cv2.watershed()函數(shù)用于執(zhí)行分水嶺算法分割圖像,其基本格式如下:

ret = cv2.watershed(image, markers)

ret為返回的8位或32位單通道圖像

image為輸入的8位或32位單通道圖像

markers為輸入的32位單通道圖像

# cv2.watershed()函數(shù),執(zhí)行分水嶺算法分割圖像
img = cv2.imread('qizi.jpg')

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度操作

ret, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) 	# 閾值操作

kernel = np.ones((3, 3), np.uint8)
img_open = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2) 				# 形態(tài)學(xué)操作

img_dilate = cv2.dilate(img_open, kernel, iterations=3)               					# 膨脹操作(確定背景)

img_dist = cv2.distanceTransform(img_open, cv2.DIST_L2, 0)          

ret, img_fg = cv2.threshold(img_dist, 0.7*img_dist.max(), 255, 2)      					# 距離操作(確定前景)

img_fg = np.uint8(img_fg)

ret, markers = cv2.connectedComponents(img_fg)

unknown = cv2.subtract(img_dilate, img_fg)												# 確定位置未知區(qū)域

markers = markers + 1																	# 加1使背景不為0

markers[unknown == 255] = 0																# 將未知區(qū)域設(shè)置為0

img_water = cv2.watershed(img, markers)													# 執(zhí)行分水嶺算法

plt.imshow(img_water, cmap='gray')
plt.title('watershed')
plt.axis('off')
plt.show()

img[img_water == -1] = [0, 255, 0]														# 將原圖中的被標(biāo)記點(diǎn)設(shè)置為綠色
cv2.namedWindow('watershed', cv2.WINDOW_NORMAL)
cv2.imshow('watershed', img)

cv2.waitKey(0)
cv2.destroyAllWindows()

二、圖像金字塔

圖像金字塔從分辨率的角度分析處理圖像。圖像金字塔的底部為原始圖,對(duì)原始圖像進(jìn)行梯次向下采樣,得到金字塔的其他各層圖像。層次越高,分辨率越低,圖像越小。通常,每向上一層,圖像的寬度和高度就為下一層的一半。常見(jiàn)的圖像金字塔可分為高斯金字塔和拉普拉斯金字塔。

高斯金字塔有向上和向下兩種采樣方式。向下采樣時(shí),原始圖像為第0層,第1次向下采樣的結(jié)果為第1層,第2次向下采樣的結(jié)果為第2層,以此類(lèi)推。每次采樣圖像的寬度和高度都減小為原來(lái)的一半,所有的圖層構(gòu)成高斯金字塔。向上采樣的過(guò)程和向下采樣的過(guò)程相反,每次采樣圖像的寬度和高度都擴(kuò)大為原來(lái)的二倍。

1、高斯金字塔向下采樣

OpenCV中的cv2.pyrDown()函數(shù)用于執(zhí)行高斯金字塔構(gòu)造的向下采樣步驟,其基本格式如下:

ret = cv2.pyrDown(image[, dstsize[, borderType]])

ret為返回的結(jié)果圖像, 類(lèi)型和輸入圖像相同

image為輸入圖像

dstsize為結(jié)果圖像大小

borderType為邊界類(lèi)型

# 高斯金字塔向下采樣
img = cv2.imread('qizi.jpg')
img1 = cv2.pyrDown(img)
img2 = cv2.pyrDown(img1)

cv2.imshow('img', img)
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)

print('0層的形狀:', img.shape)
print('1層的形狀:', img1.shape)
print('2層的形狀:', img2.shape)

cv2.waitKey(0)
cv2.destroyAllWindows()

2、高斯金字塔向上采樣

OpenCV中的cv2.pyrUp()函數(shù)用于執(zhí)行高斯金字塔構(gòu)造的向下采樣步驟,其基本格式如下:

ret = cv2.pyrUp(image[, dstsize[, borderType]])

ret為返回的結(jié)果圖像, 類(lèi)型和輸入圖像相同

image為輸入圖像

dstsize為結(jié)果圖像大小

borderType為邊界類(lèi)型

3、拉普拉斯金字塔

拉普拉斯金字塔的第n層是該層高斯金字塔圖像減去n+1層向上采樣的結(jié)果獲得的圖像。

# 拉普拉斯金字塔
img = cv2.imread('qizi.jpg')
img1 = cv2.pyrDown(img)
img2 = cv2.pyrDown(img1)
img3 = cv2.pyrDown(img2)

imgL0 = cv2.subtract(img, cv2.pyrUp(img1))
imgL1 = cv2.subtract(img1, cv2.pyrUp(img2))
imgL2 = cv2.subtract(img2, cv2.pyrUp(img3))

cv2.imshow('imgL0', imgL0)
cv2.imshow('imgL1', imgL1)
cv2.imshow('imgL2', imgL2)

cv2.waitKey(0)
cv2.destroyAllWindows()

4、應(yīng)用圖像金字塔實(shí)現(xiàn)圖像的分割和融合

# 應(yīng)用圖像金字塔實(shí)現(xiàn)圖像融合
img1 = cv2.imread('jiang1.jpg')
img2 = cv2.imread('jiang2.jpg')

#生成圖像1的高斯金字塔,向下采樣6次
img = img1.copy()
img1Gaus = [img]
for i in range(6):
    img = cv2.pyrDown(img)
    img1Gaus.append(img)

#生成圖像2的高斯金字塔,向下采樣6次
img = img2.copy()
img2Gaus = [img]
for i in range(6):
    img = cv2.pyrDown(img)
    img2Gaus.append(img)

#生成圖像1的拉普拉斯金字塔,6層
img1Laps = [img1Gaus[5]]
for i in range(5,0,-1):
    img = cv2.pyrUp(img1Gaus[i])
    lap = cv2.subtract(img1Gaus[i-1],img)    #兩個(gè)圖像大小不同時(shí),做減法會(huì)出錯(cuò)
    img1Laps.append(lap)

#生成圖像2的拉普拉斯金字塔,6層
img2Laps = [img2Gaus[5]]
for i in range(5,0,-1):
    img = cv2.pyrUp(img2Gaus[i])
    lap = cv2.subtract(img2Gaus[i-1],img)
    img2Laps.append(lap)

#拉普拉斯金字塔拼接:圖像1每層左半部分與和圖像2每層右半部分拼接
imgLaps = []
for la,lb in zip(img1Laps,img2Laps):
    rows,cols,dpt = la.shape
    ls=la.copy()
    ls[:,int(cols/2):]=lb[:,int(cols/2):]
    imgLaps.append(ls)

#從拉普拉斯金字塔恢復(fù)圖像
img = imgLaps[0]
for i in range(1,6):
    img = cv2.pyrUp(img)
    img = cv2.add(img, imgLaps[i])

#圖像1原圖像的半部分與和圖像2原圖像的右左半部分直接拼接
direct = img1.copy()
direct[:,int(cols/2):]=img2[:,int(cols/2):]
cv2.imshow('Direct',direct)             #顯示直接拼接結(jié)果
cv2.imshow('Pyramid',img)               #顯示圖像金字塔拼接結(jié)果
cv2.waitKey(0)
cv2.destroyAllWindows()

到此這篇關(guān)于OpenCV圖像分割之分水嶺算法與圖像金字塔算法詳解的文章就介紹到這了,更多相關(guān)OpenCV圖像分割內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳細(xì)解讀Python中解析XML數(shù)據(jù)的方法

    詳細(xì)解讀Python中解析XML數(shù)據(jù)的方法

    這篇文章主要介紹了Python中解析XML數(shù)據(jù)的方法,是Python入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-10-10
  • Django零基礎(chǔ)入門(mén)之常用過(guò)濾器詳解

    Django零基礎(chǔ)入門(mén)之常用過(guò)濾器詳解

    這篇文章主要介紹了Django零基礎(chǔ)入門(mén)之常用過(guò)濾器的使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Python實(shí)現(xiàn)批量獲取當(dāng)前文件夾下的文件名

    Python實(shí)現(xiàn)批量獲取當(dāng)前文件夾下的文件名

    這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)批量獲取當(dāng)前文件夾下的文件名,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • Python編程快速上手——正則表達(dá)式查找功能案例分析

    Python編程快速上手——正則表達(dá)式查找功能案例分析

    這篇文章主要介紹了Python正則表達(dá)式查找功能,結(jié)合具體實(shí)例形式分析了Python基于正則表達(dá)式遍歷查找指定格式文件的相關(guān)操作技巧,需要的朋友可以參考下
    2020-02-02
  • Python批量對(duì)word文檔進(jìn)行操作步驟

    Python批量對(duì)word文檔進(jìn)行操作步驟

    這篇文章主要介紹了Python批量對(duì)word文檔進(jìn)行操作,一步步逐步完成創(chuàng)建文檔,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • 判斷python字典中key是否存在的兩種方法

    判斷python字典中key是否存在的兩種方法

    這篇文章主要介紹了判斷python字典中key是否存在的兩種方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Django項(xiàng)目中使用JWT的實(shí)現(xiàn)代碼

    Django項(xiàng)目中使用JWT的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Django項(xiàng)目中使用JWT的實(shí)現(xiàn)代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • Python多線程 Queue 模塊常見(jiàn)用法

    Python多線程 Queue 模塊常見(jiàn)用法

    Python的Queue模塊提供一種適用于多線程編程的FIFO實(shí)現(xiàn)。它可用于在生產(chǎn)者(producer)和消費(fèi)者(consumer)之間線程安全(thread-safe)地傳遞消息或其它數(shù)據(jù),因此多個(gè)線程可以共用同一個(gè)Queue實(shí)例。Queue的大?。ㄔ氐膫€(gè)數(shù))可用來(lái)限制內(nèi)存的使用
    2021-07-07
  • pyqt5 QScrollArea設(shè)置在自定義側(cè)(任何位置)

    pyqt5 QScrollArea設(shè)置在自定義側(cè)(任何位置)

    這篇文章主要介紹了pyqt5 QScrollArea設(shè)置在自定義側(cè)(任何位置),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 詳解PyTorch批訓(xùn)練及優(yōu)化器比較

    詳解PyTorch批訓(xùn)練及優(yōu)化器比較

    本篇文章主要介紹了詳解PyTorch批訓(xùn)練及優(yōu)化器比較,詳細(xì)的介紹了什么是PyTorch批訓(xùn)練和PyTorch的Optimizer優(yōu)化器,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2018-04-04

最新評(píng)論