生活随笔
收集整理的這篇文章主要介紹了
OpenCV与图像处理学习十——区域生长算法(含代码)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
OpenCV與圖像處理學(xué)習(xí)十——區(qū)域生長算法(含代碼)
- 一、區(qū)域生長算法概要
- 二、區(qū)域生長算法原理
- 三、代碼應(yīng)用
一、區(qū)域生長算法概要
區(qū)域生長是一種串行區(qū)域分割的圖像分割方法。區(qū)域生長是指從某個像素出發(fā),按照一定的準(zhǔn)則,逐步加入鄰近像素,當(dāng)滿足一定的條件時,區(qū)域生長終止。
區(qū)域生長的好壞決定于:
初始點(種子點)的選取。生長準(zhǔn)則。終止條件。
區(qū)域生長是從某個或者某些像素點出發(fā),最后得到整個區(qū)域,進而實現(xiàn)目標(biāo)的提取。
二、區(qū)域生長算法原理
基本思想:將具有相似性質(zhì)的像素集合起來構(gòu)成區(qū)域。
步驟:
對圖像順序掃描,找到第1個還沒有歸屬的像素, 設(shè)該像素為(x0, y0);以(x0, y0)為中心, 考慮(x0, y0)的4鄰域像素(x, y)如果(x0,y0)滿足生長準(zhǔn)則, 將(x, y)與(x0, y0)合并(在同一區(qū)域內(nèi)), 同時將(x, y)壓入堆棧(即滿足條件,被判定為和(x0, y0)屬于一個區(qū)域,后面需要再從這些點往外繼續(xù)生長,所以需要保存);從堆棧中取出一個像素, 把它當(dāng)作(x0, y0)返回到步驟2(繼續(xù)往外生長);當(dāng)堆棧為空時,返回到步驟1(有像素可能不屬于前面的區(qū)域);重復(fù)步驟1 - 4直到圖像中的每個點都有歸屬時;生長結(jié)束。
三、代碼應(yīng)用
這里為簡單起見,我們只設(shè)置了一個區(qū)域,即上述步驟中的第四步改為,當(dāng)堆棧為空時,生長結(jié)束。
我們需要分割的圖像如下所示:
我們將生長準(zhǔn)則設(shè)置為像素值之間的歐式距離小于某個閾值,也就是說相鄰像素值的差異較小時,歸類為一個區(qū)域,代碼如下所示:
import cv2
import numpy
as np
class Point(object):def __init__(self
, x
, y
):self
.x
= xself
.y
= y
def getX(self
):return self
.x
def getY(self
):return self
.y
connects
= [Point
(-1, -1), Point
(0, -1), Point
(1, -1), Point
(1, 0),Point
(1, 1), Point
(0, 1), Point
(-1, 1), Point
(-1, 0)]
def get_dist(seed_location1
, seed_location2
):l1
= im
[seed_location1
.x
, seed_location1
.y
]l2
= im
[seed_location2
.x
, seed_location2
.y
]count
= np
.sqrt
(np
.sum(np
.square
(l1
-l2
)))return count
im
= cv2
.imread
('./image/222.jpg')
cv2
.imshow
('src', im
)
cv2
.waitKey
(0)
cv2
.destroyAllWindows
()
im_shape
= im
.shape
height
= im_shape
[0]
width
= im_shape
[1]print('the shape of image :', im_shape
)
img_mark
= np
.zeros
([height
, width
])
cv2
.imshow
('img_mark', img_mark
)
cv2
.waitKey
(0)
cv2
.destroyAllWindows
()
img_re
= im
.copy
()
for i
in range(height
):for j
in range(width
):img_re
[i
, j
][0] = 0img_re
[i
, j
][1] = 0img_re
[i
, j
][2] = 0
cv2
.imshow
('img_re', img_re
)
cv2
.waitKey
(0)
cv2
.destroyAllWindows
()
seed_list
= []
seed_list
.append
(Point
(15, 15))
T
= 7
class_k
= 1
while (len(seed_list
) > 0):seed_tmp
= seed_list
[0]seed_list
.pop
(0)img_mark
[seed_tmp
.x
, seed_tmp
.y
] = class_k
for i
in range(8):tmpX
= seed_tmp
.x
+ connects
[i
].xtmpY
= seed_tmp
.y
+ connects
[i
].y
if (tmpX
< 0 or tmpY
< 0 or tmpX
>= height
or tmpY
>= width
):continuedist
= get_dist
(seed_tmp
, Point
(tmpX
, tmpY
))if (dist
< T
and img_mark
[tmpX
, tmpY
] == 0):img_re
[tmpX
, tmpY
][0] = im
[tmpX
, tmpY
][0]img_re
[tmpX
, tmpY
][1] = im
[tmpX
, tmpY
][1]img_re
[tmpX
, tmpY
][2] = im
[tmpX
, tmpY
][2]img_mark
[tmpX
, tmpY
] = class_kseed_list
.append
(Point
(tmpX
, tmpY
))
cv2
.imshow
('OUTIMAGE', img_re
)
cv2
.waitKey
(0)
cv2
.destroyAllWindows
()
分割得到的結(jié)果如下所示:
很顯然,天空的像素值較為接近,所以被生長為一片區(qū)域,而房屋的像素與天空的差異較大,當(dāng)天空的區(qū)域生長結(jié)束之后,因為這里只設(shè)置了分割一塊區(qū)域,所以下面的房屋部分沒有遍歷到。
總結(jié)
以上是生活随笔為你收集整理的OpenCV与图像处理学习十——区域生长算法(含代码)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。