日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenCV与图像处理学习九——连通区域分析算法(含代码)

發(fā)布時間:2024/7/23 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV与图像处理学习九——连通区域分析算法(含代码) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

OpenCV與圖像處理學(xué)習(xí)九——連通區(qū)域分析算法(含代碼)

  • 一、連通區(qū)域概要
  • 二、Two-Pass算法
  • 三、代碼實現(xiàn)

一、連通區(qū)域概要

連通區(qū)域(Connected Component)一般是指圖像中具有相同像素值且位置相鄰的前景像素點組成的圖像區(qū)域,連通區(qū)域分析是指將圖像中的各個連通區(qū)域找出并標(biāo)記。連通區(qū)域分析是一種在CV和圖像分析處理的眾多應(yīng)用領(lǐng)域中較為常用和基本的方法。

例如: OCR識別中字符分割提取(車牌識別、文本識別、字幕識別等)、視覺跟蹤中的運動前景
目標(biāo)分割與提取(行人入侵檢測、遺留物體檢測、基于視覺的車輛檢測與跟蹤等)、醫(yī)學(xué)圖像處
理(感興趣目標(biāo)區(qū)域提取)等。

在需要將前景目標(biāo)提取出來以便后續(xù)進行處理的應(yīng)用場景中都能夠用到連通區(qū)域分析
方法,通常連通區(qū)域分析處理的對象是一張二值化后的圖像。

在圖像中,最小的單位是像素,每個像素周圍有鄰接像素,常見的鄰接關(guān)系有2種: 4鄰接與8鄰接,如下圖所示:

如果A與B連通, B與C連通,則A與C連通,在視覺上看來,彼此連通的點形成了一個區(qū)域,而不連通的點形成了不同的區(qū)域。這樣的一個所有的點彼此連通點構(gòu)成的集合,我們稱為一個連通區(qū)域。

我們來看一下下面這個二值化的圖:

對于每一個前景像素,只要它的鄰域中有像素也是前景,那么它們就屬于一個連通區(qū)域,在這張圖中,如果使用四鄰域的規(guī)則,那么將可以分成三個連通區(qū)域,而使用八鄰域的規(guī)則,則可以分成兩個連通區(qū)域

二、Two-Pass算法

基于上述概念,我們再來學(xué)習(xí)連通區(qū)域分析算法中常用的Two-Pass算法 (兩遍掃描法),正如其名,指的就是通過掃描兩遍圖像,將圖像中存在的所有連通域找出并標(biāo)記。

第一次掃描

  • 從左上角開始遍歷像素點,找到第一個像素為255(因為是二值圖,只有0和255)的點,令該像素的label=1;
  • 當(dāng)該像素的左鄰像素和上鄰像素為無效值時,給該像素置一個新的label值, label ++,記錄集合;
  • 當(dāng)該像素的左鄰像素或者上鄰像素有一個為有效值時,將有效值像素的label賦給該像素的label值;
  • 當(dāng)該像素的左鄰像素和上鄰像素都為有效值時,選取其中較小的label值賦給該像素的label值。
  • 若一張二值圖如下所示(藍點為前景點):

    則第一遍掃描之后記錄的label如下所示:

    通過領(lǐng)域像素得到label或成為領(lǐng)域像素得到label依據(jù)的像素點都將記錄為一個集合,只有毫無聯(lián)系的才會記錄為不同的集合,如上圖所示,前景點被分為了兩個集合(橙色標(biāo)記)。

    第二次掃描

  • 對每個點的label進行更新,更新為其對于其集合中最小的label

    則就可以得到兩個連通區(qū)域:
  • 三、代碼實現(xiàn)

    import cv2 import numpy as np# 4鄰域的連通域和 8鄰域的連通域 # [row, col] NEIGHBOR_HOODS_4 = True OFFSETS_4 = [[0, -1], [-1, 0], [0, 0], [1, 0], [0, 1]]NEIGHBOR_HOODS_8 = False OFFSETS_8 = [[-1, -1], [0, -1], [1, -1],[-1, 0], [0, 0], [1, 0],[-1, 1], [0, 1], [1, 1]] #第二遍掃描 def reorganize(binary_img: np.array):index_map = []points = []index = -1rows, cols = binary_img.shapefor row in range(rows):for col in range(cols):var = binary_img[row][col]if var < 0.5:continueif var in index_map:index = index_map.index(var)num = index + 1else:index = len(index_map)num = index + 1index_map.append(var)points.append([])binary_img[row][col] = numpoints[index].append([row, col])#print(binary_img)#print(points)return binary_img, points#四領(lǐng)域或八領(lǐng)域判斷 def neighbor_value(binary_img: np.array, offsets, reverse=False):rows, cols = binary_img.shapelabel_idx = 0rows_ = [0, rows, 1] if reverse == False else [rows-1, -1, -1]cols_ = [0, cols, 1] if reverse == False else [cols-1, -1, -1]for row in range(rows_[0], rows_[1], rows_[2]):for col in range(cols_[0], cols_[1], cols_[2]):label = 256if binary_img[row][col] < 0.5:continuefor offset in offsets:neighbor_row = min(max(0, row+offset[0]), rows-1)neighbor_col = min(max(0, col+offset[1]), cols-1)neighbor_val = binary_img[neighbor_row, neighbor_col]if neighbor_val < 0.5:continuelabel = neighbor_val if neighbor_val < label else labelif label == 255:label_idx += 1label = label_idxbinary_img[row][col] = labelprint('第一遍掃描:',binary_img)print('開始第二遍...')return binary_img# binary_img: bg-0, object-255; int #第一遍掃描 def Two_Pass(binary_img: np.array, neighbor_hoods):if neighbor_hoods == NEIGHBOR_HOODS_4:offsets = OFFSETS_4elif neighbor_hoods == NEIGHBOR_HOODS_8:offsets = OFFSETS_8else:raise ValueErrorbinary_img = neighbor_value(binary_img, offsets, False)return binary_imgif __name__ == "__main__":#創(chuàng)建四行七列的矩陣binary_img = np.zeros((4, 7), dtype=np.int16)#指定點設(shè)置為255index = [[0, 2], [0, 5],[1, 0], [1, 1], [1, 2], [1, 4], [1, 5], [1, 6],[2, 2], [2, 5],[3, 1], [3, 2], [3, 4],[3,5], [3, 6]]for i in index:binary_img[i[0], i[1]] = np.int16(255)print("原始二值圖像")print(binary_img)#print("Two_Pass")#調(diào)用Two Pass算法,計算第一遍掃面的結(jié)果binary_img = Two_Pass(binary_img, NEIGHBOR_HOODS_4)#print(binary_img)#計算第一遍掃面的結(jié)果binary_img, points = reorganize(binary_img)print(binary_img)#print(points)

    結(jié)果如下所示:

    原始二值圖像 [[ 0 0 255 0 0 255 0][255 255 255 0 255 255 255][ 0 0 255 0 0 255 0][ 0 255 255 0 255 255 255]] 第一遍掃描: [[0 0 1 0 0 2 0][3 3 1 0 4 2 2][0 0 1 0 0 2 0][0 5 1 0 6 2 2]] 開始第二遍... [[0 0 1 0 0 2 0][3 3 1 0 4 2 2][0 0 1 0 0 2 0][0 5 1 0 6 2 2]]

    總結(jié)

    以上是生活随笔為你收集整理的OpenCV与图像处理学习九——连通区域分析算法(含代码)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。