1 引言
在二值影像f中,相互聯結的白色像素的集合成為一個前景目標白色區域,本章對二值影像f內每個區域進行標記操作,進而求得區域的數目,并計算每個區域的面積,

物體標識的一般程序如下:
- 從左到右,從上到下逐個像素掃描
- 若該點為前景物體,則以該點為種子進行區域增長并標記,(區域增長演算法可參考上節文章)
- 重復上述程序,直至所有像素都被訪問過為止,最后輸出標記后的影像,
2 物體標識代碼實作
2.1 讀入彩色影像執行灰度化和二值化
def get_binary_img(img):
# gray img to bin image
bin_img = np.zeros(shape=(img.shape), dtype=np.uint8)
h = img.shape[0]
w = img.shape[1]
for i in range(h):
for j in range(w):
bin_img[i][j] = 255 if img[i][j] < 255 else 0
return bin_img
# 呼叫
file_name = "./test.bmp"
img = cv2.imread(file_name)
# 灰度化
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化
bin_img = get_binary_img(gray_img)
結果如下:

上圖中左側為原圖,中間為灰度圖,右側為二值圖
2.2 目標標記
# 標記目標
def label_region(bin_img,width,height):
visited = np.zeros(shape=bin_img.shape,dtype=np.uint8)
label_img = np.zeros(shape=bin_img.shape, dtype=np.uint8)
label = 0
for i in range(height):
for j in range(width):
if bin_img[i][j] == 255 and visited[i][j]==0 : //找到種子點
# visit
visited[i][j] = 1
label += 1
label_img[i][j] = label
# label
label_from_seed(bin_img, visited, i, j, label, label_img)
return label_img
# 區域增長法進行標記
def label_from_seed(bin_img,visited,i,j,label,out_img):
directs = [(-1, -1), (0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0)]
seeds = [(i,j)]
height = bin_img.shape[0]
width = bin_img.shape[1]
while len(seeds):
seed = seeds.pop(0)
i = seed[0]
j = seed[1]
if visited[i][j] == 0:
visited[i][j] = 1
out_img[i][j] = label
# 以(i,j)為起點進行標記
for direct in directs:
cur_i = i + direct[0]
cur_j = j + direct[1]
# 非法
if cur_i < 0 or cur_j < 0 or cur_i >= height or cur_j >= width:
continue
# 沒有訪問過
if visited[cur_i][cur_j] == 0 and bin_img[cur_i][cur_j] == 255:
visited[cur_i][cur_j] = 1
out_img[cur_i][cur_j] = label
seeds.append((cur_i,cur_j))
得到結果如下:

上圖中左側為原圖,右側為物體標記圖,其中每一個物體的像素值就是該物體的標號,為計算面積打下基礎,
3 目標面積
對標記后的影像進行遍歷,統計每種編號出現的像素個數,即可求得不同區域的面積大小,
代碼如下:
def get_region_area(label_img,label):
count = { key: 0 for key in range(label + 1)}
start_pt = {key:(0,0) for key in range(label + 1)}
height = label_img.shape[0]
width = label_img.shape[1]
for i in range(height):
for j in range(width):
key = label_img[i][j]
count[key] += 1
if count[key] == 1:
start_pt[key] = (j,i)
return count,start_pt
畫圖函式如下:
def draw_area_reslult(img,count,start_pt):
draw = img.copy()
for key in count.keys():
if key > 0:
pt = start_pt[key]
x = pt[0]
y = pt[1]
area = count[key]
if y < 20:
y = 20
cv2.putText(draw, str(area),(x,y), cv2.FONT_HERSHEY_COMPLEX, 0.8, (128, 0, 128), 1)
return draw
結果如下:

通過上圖,可以知道我們共標記出4個目標,并且四個目標的面積依次為86,5680,6544和860,
4 總結
通過上述簡單步驟,我們實作了物體標識和面積測量,相應的處理效果如下:

上圖中左側為原圖,中間為目標標記圖,右側為我們面積測量圖,數值代表對于目標的面積,
您學肥了嘛?
關注公眾號《AI演算法之道》,獲取更多AI演算法資訊,

注:關注公眾號號,后臺回復 面積測量 ,即可獲得完整代碼,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/294324.html
標籤:其他
下一篇:rsync+inotify介紹
