最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解OpenCV執(zhí)行連通分量標記的方法和分析

 更新時間:2022年08月05日 08:49:47   作者:求則得之,舍則失之  
在本教程中,您將學習如何使用?OpenCV?執(zhí)行連通分量標記和分析。具體來說,我們將重點介紹?OpenCV?最常用的連通分量標記函數(shù):cv2.connectedComponentsWithStats,感興趣的可以了解一下

在本教程中,您將學習如何使用 OpenCV 執(zhí)行連通分量標記和分析。具體來說,我們將重點介紹 OpenCV 最常用的連通分量標記函數(shù):cv2.connectedComponentsWithStats。

連通分量標記(也稱為連通分量分析、斑點提取或區(qū)域標記)是圖論的一種算法應用,用于確定二進制圖像中“斑點”狀區(qū)域的連通性。

我們經(jīng)常在與使用輪廓相同的情況下使用連通分量分析;然而,連通分量標記通常可以讓我們對二值圖像中的斑點進行更細粒度的過濾。在使用輪廓分析時,我們經(jīng)常受到輪廓層次結構的限制(即一個輪廓包含在另一個輪廓中)。通過連通分量分析,我們可以更輕松地分割和分析這些結構。

連通分量分析的一個很好的例子是計算二值(即閾值后的)車牌圖像的連通分量,并根據(jù)它們的屬性(例如寬度、高度、面積、solidity等)過濾斑點。這正是我們今天在這里要做的。

1.OpenCV 連通分量標記和分析

在本教程的第一部分,我們將回顧 OpenCV 提供的用于執(zhí)行連通分量標記和分析的四個函數(shù)。這些函數(shù)中最受歡迎的是cv2.connectedComponentsWithStats。

首先,我們將配置我們的開發(fā)環(huán)境并查看我們的項目目錄結構。

接下來,我們將實現(xiàn)兩種形式的連通分量分析:

一種方法將演示如何使用 OpenCV 的連通分量標記和分析函數(shù),計算每個連通分量的統(tǒng)計數(shù)據(jù),然后單獨提取/可視化每個連通分量。

第二種方法顯示了連接分量分析的實際示例。我們對車牌進行閾值化,然后使用連通分量分析僅提取車牌字符。

1.1 OpenCV 連通分量標記和分析函數(shù)

OpenCV 提供了四種連通分量分析函數(shù):

  • cv2.connectedComponents
  • cv2.connectedComponentsWithStats
  • cv2.connectedComponentsWithAlgorithm
  • cv2.connectedComponentsWithStatsWithAlgorithm

最流行的方法是 cv2.connectedComponentsWithStats,它返回以下信息:

  • 連通分量的邊界框
  • 連通分量的面積(以像素為單位)
  • 連通分量的質心/中心 (x, y) 坐標

第一種方法,cv2.connectedComponents,和第二種方法一樣,只是不返回上面的統(tǒng)計信息。在絕大多數(shù)情況下,您將需要統(tǒng)計信息,因此簡單地使用 cv2.connectedComponentsWithStats 即可。

第三種方法 cv2.connectedComponentsWithAlgorithm 實現(xiàn)了更快、更有效的連通分量分析算法。

如果您使用并行處理支持編譯 OpenCV,則 cv2.connectedComponentsWithAlgorithm 和 cv2.connectedComponentsWithStatsWithAlgorithm 將比前兩個運行得更快。

但一般來說,堅持使用 cv2.connectedComponentsWithStats 直到您熟悉連通分量標記。

1.2 項目結構

在我們使用 OpenCV 實現(xiàn)連通分量標記和分析之前,讓我們先來看看我們的項目目錄結構。

我們將應用連通分量分析來自動過濾車牌 (license_plate.png) 中的字符。

為了完成這項任務并了解有關連通分量分析的更多信息,我們將實現(xiàn)兩個 Python 腳本:

basic_connected_components.py:演示如何應用連通分量標記,提取每個組件及其統(tǒng)計數(shù)據(jù),并在我們的屏幕上可視化它們。

filtering_connected_components.py:應用連通分量標記,通過檢查每個連通分量的寬度、高度和面積(以像素為單位)過濾掉非牌照字符。

2.案例實現(xiàn)

2.1 使用 OpenCV 實現(xiàn)基本的連通分量標記

讓我們開始使用 OpenCV 實現(xiàn)連通分量分析。

打開項目文件夾中的 basic_connected_components.py 文件,讓我們開始工作:

# 導入相關包
# 導入必要的包
import argparse
import cv2

# 解析構建的參數(shù)解析器
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="path to input image")
ap.add_argument("-c", "--connectivity", type=int, default=4, help="connectivity for connected analysis")
args = vars(ap.parse_args())  # 將參數(shù)轉為字典格式

我們有兩個命令行參數(shù)

–image:輸入圖像路徑

–connectivity:4連通或者8連通

接下來,進行圖像預處理操作

# 加載輸入圖像,將其轉換為灰度,并對其進行閾值處理
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

閾值處理以后,將得到如下圖像:

請注意車牌字符在黑色背景上顯示為白色。但是,輸入圖像中也有一堆噪聲也顯示為前景(白色)。我們的目標是應用連通分量分析來過濾掉這些噪聲區(qū)域,只留下車牌字符。

但在我們開始之前,讓我們先學習如何使用 cv2.connectedComponentsWithStats 函數(shù):

output = cv2.connectedComponentsWithStats(thresh, args["connectivity"], cv2.CV_32S)
(numLabels, labels, stats, centroids) = output

使用OpenCV的cv2.connectedComponentsWithStats 執(zhí)行連通分量分析。我們在這里傳入三個參數(shù):

  • 閾值化后的圖像
  • 4連通還是8連通
  • 數(shù)據(jù)類型(應該使用cv2.CV_32S)

然后 cv2.connectedComponentsWithStats 返回一個 4 元組:

  • 檢測到的唯一標簽總數(shù)(即總連通分量數(shù))
  • 一個名為labels的掩碼, 掩碼與我們的輸入閾值圖像具有相同的空間維度。對于labels中的每個位置,我們都有一個整數(shù) ID 值,該值對應于像素所屬的連通分量。您將在本節(jié)后面學習如何過濾labels矩陣。
  • stats:每個連通分量的統(tǒng)計信息,包括邊界框坐標和面積(以像素為單位)。
  • 每個連通分量的質心(即中心)(x,y)坐標。

讓我們開始解析這些數(shù)值:

# 遍歷每個連通分量
for i in range(0, numLabels):
    # 0表示的是背景連通分量,忽略
    if i == 0:
        text = "examining component {}/{} (background)".format(
            i + 1, numLabels)
    # otherwise, we are examining an actual connected component
    else:
        text = "examining component {}/{}".format(i + 1, numLabels)
    # 打印當前的狀態(tài)信息
    print("[INFO] {}".format(text))
    # 提取當前標簽的連通分量統(tǒng)計信息和質心
    x = stats[i, cv2.CC_STAT_LEFT]
    y = stats[i, cv2.CC_STAT_TOP]
    w = stats[i, cv2.CC_STAT_WIDTH]
    h = stats[i, cv2.CC_STAT_HEIGHT]
    area = stats[i, cv2.CC_STAT_AREA]
    (cX, cY) = centroids[i]

if/else語句說明:

  • 第一個連通分量,即ID 為 0,始終是背景。我們通常會忽略背景,但如果您需要它,請記住 ID=0 包含它。
  • 否則,如果 i > 0,那么我們知道該連通分量值得進一步探索。

解析我們的統(tǒng)計數(shù)據(jù)和質心列表:

  • 連通分量的起始x坐標
  • 連通分量的起始y坐標
  • 連通分量的寬(w)
  • 連通分量的高(h)
  • 連通分量的質心坐標(x,y)
    # 可視化邊界框和當前連通分量的質心
    # clone原始圖,在圖上畫當前連通分量的邊界框以及質心
    output = image.copy()
    cv2.rectangle(output, (x, y), (x + w, y + h), (0, 255, 0), 3)
    cv2.circle(output, (int(cX), int(cY)), 4, (0, 0, 255), -1)

創(chuàng)建一個我們可以繪制的輸出圖像。然后我們將當前的連通分量的邊界框繪制為綠色矩形,將質心繪制為紅色圓圈。

我們的最終代碼塊演示了如何為當前連通分量創(chuàng)建掩碼:

    # 創(chuàng)建掩碼
    componentMask = (labels == i).astype("uint8") * 255
    # 顯示輸出圖像和掩碼
    cv2.imshow("Output", output)
    cv2.imshow("Connected Component", componentMask)
    cv2.waitKey(0)

首先在labels中找到與當前組件 ID 相等的所有位置。然后我們將結果轉換為一個無符號的 8 位整數(shù),其中背景值為 0,前景值為 255。最后顯示原始圖以及掩碼圖。

第一個連通分量實際上是我們的背景。我們通常會跳過,因為通常不需要背景。 然后顯示其余連通分量。對于每個連通分量,我們繪制邊界框(綠色矩形)和質心/中心(紅色圓圈)。 您可能已經(jīng)注意到,其中一些連接的組件是車牌字符,而另一些則只是“噪音”。我們將在下一部分解決這個問題。

2.2 完整代碼

# 導入必要的包
import argparse
import cv2

# 解析構建的參數(shù)解析器
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", default="plate.jpg", help="path to input image")
ap.add_argument("-c", "--connectivity", type=int, default=4, help="connectivity for connected analysis")
args = vars(ap.parse_args())  # 將參數(shù)轉為字典格式

# 加載輸入圖像,將其轉換為灰度,并對其進行閾值處理
image = cv2.imread(args["image"])
cv2.imshow("src", image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv2.imshow("threshold", thresh)

# 對閾值化后的圖像應用連通分量分析
output = cv2.connectedComponentsWithStats(thresh, args["connectivity"], cv2.CV_32S)
(numLabels, labels, stats, centroids) = output

# 遍歷每個連通分量
for i in range(0, numLabels):
    # 0表示的是背景連通分量,忽略
    if i == 0:
        text = "examining component {}/{} (background)".format(
            i + 1, numLabels)
    # otherwise, we are examining an actual connected component
    else:
        text = "examining component {}/{}".format(i + 1, numLabels)
    # 打印當前的狀態(tài)信息
    print("[INFO] {}".format(text))
    # 提取當前標簽的連通分量統(tǒng)計信息和質心
    x = stats[i, cv2.CC_STAT_LEFT]
    y = stats[i, cv2.CC_STAT_TOP]
    w = stats[i, cv2.CC_STAT_WIDTH]
    h = stats[i, cv2.CC_STAT_HEIGHT]
    area = stats[i, cv2.CC_STAT_AREA]
    (cX, cY) = centroids[i]

    # 可視化邊界框和當前連通分量的質心
    # clone原始圖,在圖上畫當前連通分量的邊界框以及質心
    output = image.copy()
    cv2.rectangle(output, (x, y), (x + w, y + h), (0, 255, 0), 3)
    cv2.circle(output, (int(cX), int(cY)), 4, (0, 0, 255), -1)

    # 創(chuàng)建掩碼
    componentMask = (labels == i).astype("uint8") * 255
    # 顯示輸出圖像和掩碼
    cv2.imshow("Output", output)
    cv2.imshow("Connected Component", componentMask)
    cv2.waitKey(0)

2.3 過濾連通分量

我們之前的代碼示例演示了如何使用 OpenCV 提取連接的組件,但沒有演示如何過濾它們。

import numpy as np
import argparse
import cv2

ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", default="plate.jpg", help="path to image")
ap.add_argument("-c", "--connectivity", type=int, default=4, help="connectivity for connected component analysis")

args = vars(ap.parse_args())

# 加載圖像,轉為灰度,二值化
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY)

# 應用連通分量分析
output = cv2.connectedComponentsWithStats(thresh, connectivity=args["connectivity"], ltype=cv2.CV_32S)
(numLabels, labels, stats, centriods) = output

mask = np.zeros(gray.shape, dtype="uint8")

for i in range(1, numLabels):  # 忽略背景
    x = stats[i, cv2.CC_STAT_LEFT]  # [i, 0]
    y = stats[i, cv2.CC_STAT_TOP]  # [i, 1]
    w = stats[i, cv2.CC_STAT_WIDTH]  # [i, 2]
    h = stats[i, cv2.CC_STAT_HEIGHT]  # [i, 3]
    area = stats[i, cv2.CC_STAT_AREA]  # [i, 4]
    # 確保寬高以及面積既不太大也不太小
    keepWidth = w > 50 and w < 500
    keepHeight = h > 150 and h < 650
    keepArea = area > 500 and area < 25000
    # 我使用print語句顯示每個連接組件的寬度、高度和面積,
    # 同時將它們單獨顯示在屏幕上。我記錄了車牌字符的寬度、高度和面積,并找到了它們的最小/最大值,
    # 對于您自己的應用程序也應該這樣做。

    if all((keepWidth, keepHeight, keepArea)):
        print("[INFO] keep connected component '{}'".format(i))
        componentMask = (labels == i).astype("uint8") * 255
        mask = cv2.bitwise_or(mask, componentMask)

cv2.imshow("Image", image)
cv2.imshow("Chracters", mask)
cv2.waitKey(0)

如果我們正在構建一個自動牌照/車牌識別(ALPR/ANPR)系統(tǒng),我們將獲取這些字符,然后將它們傳遞給光學字符識別(OCR)算法進行識別。但這一切都取決于我們是否能夠將字符二值化并提取它們,連通分量分析使我們能夠做到這一點!

2.4 C++代碼案例

#include <opencv2/core/utility.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
Mat img;
int threshval = 100;
static void on_trackbar(int, void*)
{
    Mat bw = threshval < 128 ? (img < threshval) : (img > threshval);
    Mat labelImage(img.size(), CV_32S);
    int nLabels = connectedComponents(bw, labelImage, 8);
    std::vector<Vec3b> colors(nLabels);
    colors[0] = Vec3b(0, 0, 0);//background
    for(int label = 1; label < nLabels; ++label){
        colors[label] = Vec3b( (rand()&255), (rand()&255), (rand()&255) );
    }
    Mat dst(img.size(), CV_8UC3);
    for(int r = 0; r < dst.rows; ++r){
        for(int c = 0; c < dst.cols; ++c){
            int label = labelImage.at<int>(r, c);
            Vec3b &pixel = dst.at<Vec3b>(r, c);
            pixel = colors[label];
         }
     }
    imshow( "Connected Components", dst );
}
int main( int argc, const char** argv )
{
    CommandLineParser parser(argc, argv, "{@image|stuff.jpg|image for converting to a grayscale}");
    parser.about("\nThis program demonstrates connected components and use of the trackbar\n");
    parser.printMessage();
    cout << "\nThe image is converted to grayscale and displayed, another image has a trackbar\n"
            "that controls thresholding and thereby the extracted contours which are drawn in color\n";
    String inputImage = parser.get<string>(0);
    img = imread(samples::findFile(inputImage), IMREAD_GRAYSCALE);
    if(img.empty())
    {
        cout << "Could not read input image file: " << inputImage << endl;
        return EXIT_FAILURE;
    }
    imshow( "Image", img );
    namedWindow( "Connected Components", WINDOW_AUTOSIZE);
    createTrackbar( "Threshold", "Connected Components", &threshval, 255, on_trackbar );
    on_trackbar(threshval, 0);
    waitKey(0);
    return EXIT_SUCCESS;
}

到此這篇關于詳解OpenCV執(zhí)行連通分量標記的方法和分析的文章就介紹到這了,更多相關OpenCV連通分量標記內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Python實現(xiàn)列表拼接和去重的三種方式

    Python實現(xiàn)列表拼接和去重的三種方式

    本文主要介紹了Python實現(xiàn)列表拼接和去重,詳細的介紹了列表拼接和列表去重三種方式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • python 從csv讀數(shù)據(jù)到mysql的實例

    python 從csv讀數(shù)據(jù)到mysql的實例

    今天小編就為大家分享一篇python 從csv讀數(shù)據(jù)到mysql的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • Django實現(xiàn)文件上傳和下載功能

    Django實現(xiàn)文件上傳和下載功能

    這篇文章主要為大家詳細介紹了Django下完成文件上傳和下載功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • Python徹底刪除文件夾及其子文件方式

    Python徹底刪除文件夾及其子文件方式

    今天小編就為大家分享一篇Python徹底刪除文件夾及其子文件方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • python等間距取值方式

    python等間距取值方式

    這篇文章主要介紹了python等間距取值方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Python實現(xiàn)KNN(K-近鄰)算法的示例代碼

    Python實現(xiàn)KNN(K-近鄰)算法的示例代碼

    這篇文章主要介紹了Python實現(xiàn)KNN(K-近鄰)算法的示例代碼,它主要用于對事物進行分類。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • Python3 類型標注支持操作

    Python3 類型標注支持操作

    這篇文章主要介紹了Python3 類型標注支持操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Python實現(xiàn)對桌面進行實時捕捉畫面的方法詳解

    Python實現(xiàn)對桌面進行實時捕捉畫面的方法詳解

    最近在研究目標檢測方面的小東西,需要到對桌面進行實時捕捉畫面。所以本文來用Python實現(xiàn)簡單的對桌面進行實時捕捉畫面,感興趣的可以了解一下
    2023-01-01
  • pytorch簡單實現(xiàn)神經(jīng)網(wǎng)絡功能

    pytorch簡單實現(xiàn)神經(jīng)網(wǎng)絡功能

    這篇文章主要介紹了pytorch簡單實現(xiàn)神經(jīng)網(wǎng)絡,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • Python udp網(wǎng)絡程序實現(xiàn)發(fā)送、接收數(shù)據(jù)功能示例

    Python udp網(wǎng)絡程序實現(xiàn)發(fā)送、接收數(shù)據(jù)功能示例

    這篇文章主要介紹了Python udp網(wǎng)絡程序實現(xiàn)發(fā)送、接收數(shù)據(jù)功能,結合實例形式分析了Python使用socket模塊進行udp套接字創(chuàng)建、數(shù)據(jù)收發(fā)等相關操作技巧,需要的朋友可以參考下
    2019-12-12

最新評論

阳西县| 特克斯县| 贡觉县| 怀来县| 千阳县| 商河县| 四子王旗| 山东省| 壤塘县| 怀柔区| 永福县| 抚宁县| 龙井市| 邳州市| 广饶县| 芜湖县| 房产| 体育| 汕头市| 安阳市| 丹江口市| 札达县| 牙克石市| 开封县| 台东县| 灯塔市| 凤庆县| 昌邑市| 南涧| 东至县| 广昌县| 新河县| 崇文区| 常熟市| 泉州市| 金塔县| 岢岚县| 集贤县| 清镇市| 同德县| 吉林市|