91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

OpenCV形狀檢測功能怎么實現

發布時間:2022-08-01 14:27:17 來源:億速云 閱讀:194 作者:iii 欄目:開發技術

本篇內容介紹了“OpenCV形狀檢測功能怎么實現”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

1.基于OpenCV的形狀檢測Python版本

目錄結構

OpenCV形狀檢測功能怎么實現

1.1.定義我們的形狀檢測器類ShapeDetector

開始定義我們的 ShapeDetector 類。我們將跳過這里的 init 構造函數,因為不需要初始化任何東西。

# 導入必要的包
import cv2


class ShapeDetector:
    def __init__(self):
        pass

    def detect(self, c):
        # 初始化形狀名稱并近似輪廓
        shape = "unidentified"
        peri = cv2.arcLength(c, True)
        approx = cv2.approxPolyDP(c, 0.04 * peri, True)

我們的檢測方法,它只需要一個參數 c,即我們試圖識別的形狀的輪廓。為了進行形狀檢測,我們將使用輪廓逼近。

顧名思義,輪廓近似是一種算法,用于減少曲線中點的數量,并減少點集——因此稱為近似。

輪廓近似是基于曲線可以由一系列短線段近似的假設。這導致生成的近似曲線由原始曲線定義的點的子集組成。

輪廓近似實際上已經在 OpenCV 中通過 cv2.approxPolyDP 方法實現。

為了進行輪廓逼近,我們首先計算輪廓的周長,然后構建實際的輪廓逼近。 cv2.approxPolyDP 的第二個參數的常用值通常在原始輪廓周長的 1%-5% 范圍內。

給定我們的近似輪廓,我們可以繼續執行形狀檢測:

        # 如果形狀是一個三角形,它將有3個頂點
        if len(approx) == 3:
            shape = "triangle"
        # 如果形狀有4個頂點,它要么是正方形,要么是矩形
        elif len(approx) == 4:
            # 計算輪廓的包圍框,并使用包圍框計算高寬比
            (x, y, w, h) = cv2.boundingRect(approx)
            ar = w / float(h)
            # 正方形的長寬比大約等于1,否則,形狀就是矩形
            shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle"
        # 如果形狀是一個五邊形,它將有5個頂點
        elif len(approx) == 5:
            shape = "pentagon"
        # 否則,我們假設形狀是一個圓
        else:
            shape = "circle"
        # 返回形狀的名稱
        return shape

重要的是要了解輪廓由頂點列表組成。我們可以檢查此列表中的數目以確定對象的形狀。例如,如果近似輪廓有三個頂點

那么它一定是一個三角形。如果一條輪廓有四個頂點,那么它一定是正方形或矩形。為了確定這一點,我們計算形狀的長寬比

也就是輪廓邊界框的寬度除以高度。如果長寬比是~1.0,那么我們正在檢查一個正方形(因為所有的邊都有大約相等的長度)。否則,形狀就是矩形。如果一條等高線有五個頂點,我們可以將其標記為五邊形。否則,我們可以假設我們正在檢查的形狀是一個圓。

最后,將標識好的形狀返回給調用方法。

我們已經定義了一個utils模塊。在這個模塊中,我們有shapedetector .py,它將存儲ShapeDetector類的實現。

最后,我們有detect_shapes.py腳本,我們將使用它從磁盤加載圖像,分析它的形狀,然后通過ShapeDetector類執行形狀檢測和識別。

1.2.基于OpenCV的形狀檢測器

現在我們的 ShapeDetector 類已經定義好了,讓我們創建 detect_shapes.py 腳本:

# 導入必要的庫
from utils.shapedetector import ShapeDetector
import argparse
import imutils
import cv2

# 構造參數解析并解析參數
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", default="inpaint.jpg", help="path to the input image")
args = vars(ap.parse_args())

首先導入我們已經實現的ShapeDetector類,然后解析參數,下一步,我們開始預處理我們的圖像

# 加載圖像并將其調整圖像大小,以便更好地近似形狀
image = cv2.imread(args["image"])
resized = imutils.resize(image, width=300)
ratio = image.shape[0] / float(resized.shape[0])
# 將調整后的圖像轉換為灰度,稍微模糊它,并閾值化
gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
# 在閾值化圖像中找到輪廓并初始化形狀檢測器
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
                        cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
sd = ShapeDetector()

首先,我們從磁盤加載圖像,并調整其大小。然后,我們跟蹤舊高度與調整后的新高度的比率&mdash;&mdash;我們將在本教程的后面部分找到這樣做的確切原因。

將調整大小后的圖像轉換為灰度,平滑它以減少高頻噪聲,最后閾值化它以顯示圖像中的形狀。

閾值之后,我們的圖像應該是這樣的:

OpenCV形狀檢測功能怎么實現

請注意我們的圖像是如何被二值化的&mdash;&mdash;形狀顯示為黑色背景下的白色前景。

最后,在二值圖像中找到輪廓,基于OpenCV版本的cv2.findContours獲取正確的元組值,并最終初始化我們的ShapeDetector。

最后一步是識別每個輪廓:

# 遍歷所有輪廓
for c in cnts:
    # 計算輪廓的中心,然后僅使用輪廓檢測形狀的名稱
    M = cv2.moments(c)
    cX = int((M["m10"] / M["m00"]) * ratio)
    cY = int((M["m01"] / M["m00"]) * ratio)
    shape = sd.detect(c)
    # 將輪廓(x, y)坐標乘以調整比例,然后在圖像上繪制輪廓和形狀的名稱
    c = c.astype("float")
    c *= ratio
    c = c.astype("int")
    cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
    cv2.putText(image, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,
                0.5, (255, 255, 255), 2)
    # 顯示輸出圖像
    cv2.imshow("Image", image)
    cv2.waitKey(0)

我們開始在每個單獨的輪廓上循環。對于每一個,我們計算輪廓的中心,然后執行形狀檢測和識別。

由于我們正在處理從調整大小后的圖像中提取的輪廓(而不是原始圖像),我們需要將輪廓和中心(x, y)坐標乘以調整比率。

這將為我們提供原始圖像的輪廓和質心的正確(x, y)坐標。

最后,我們在圖像上繪制輪廓和識別的形狀,然后顯示我們的結果。

OpenCV形狀檢測功能怎么實現

2.基于OpenCV的形狀檢測C++版本

在本教程中,讓我們看看如何使用 OpenCV 的輪廓來識別對象的形狀和位置。

使用OpenCV的輪廓,你可以得到每個白斑的頂點的點序列(白斑被認為是多邊形)。例如,對于三角形你會得到3個點(頂點),

對于四邊形你會得到4個點。你可以通過多邊形的頂點數來識別任何多邊形。

你甚至可以通過計算和比較頂點之間的距離來識別多邊形的特征,如凸性、凹性、等邊等。

我們看看如何使用 OpenCV 來完成。您所需要的只是一個二進制圖像,其中您的對象應該是白色的,背景應該是黑色的。

現在我將使用OpenCV C++應用程序來識別上圖中的三角形、四邊形和七邊形。我將沿著每個確定的多邊形的周長畫一條線,

三角形顏色為藍色,四邊形顏色為綠色,七邊形顏色為紅色。

2.1代碼實現

#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()
{

    Mat img = imread("FindingContours.png");

    //show the original image
    namedWindow("Raw");
    imshow("Raw", img);

    //converting the original image into grayscale
    Mat imgGrayScale = Mat(img.size(), CV_8UC1);
    cvtColor(img, imgGrayScale, COLOR_BGR2GRAY);

    //thresholding the grayscale image to get better results
    threshold(imgGrayScale, imgGrayScale, 128, 255, THRESH_BINARY);

    //finding all contours in the image
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(imgGrayScale, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);


    //iterating through each contour
    for (size_t i = 0; i < contours.size(); i++)
    {
        vector<Point> approx;
        //obtain a sequence of points of contour, pointed by the variable 'contour'
        approxPolyDP(contours[i], approx, arcLength(contours[i], true) * 0.02, true);

        //if there are 3  vertices  in the contour(It should be a triangle)
        if (approx.size() == 3)
        {
            //drawing lines around the triangle
            for (int i = 0; i < 3; i++) {
                line(img, approx[i], approx[(i+1)%3], Scalar(255, 0, 0), 4);
            }
        }
        //if there are 4 vertices in the contour(It should be a quadrilateral)
        else if (approx.size() == 4)
        {
            //drawing lines around the quadrilateral
            for (int i = 0; i < 4; i++) {
                line(img, approx[i], approx[(i + 1) % 4], Scalar(0, 255, 0), 4);
            }
        }

        //if there are 7  vertices  in the contour(It should be a heptagon)
        else if (approx.size() == 7)
        {
            //drawing lines around the heptagon
            for (int i = 0; i < 7; i++) {
                line(img, approx[i], approx[(i + 1) % 7], Scalar(0, 0, 255), 4);
            } 
        }
    }

    //show the image in which identified shapes are marked   
    namedWindow("Tracked");
    imshow("Tracked", img);

    waitKey(0); //wait for a key press

    //cleaning up
    destroyAllWindows();

    return 0;
}

如您所見,三角形用藍色標記, 四邊形用綠色標記,七邊形用紅色標記。所以,現在很明顯,這種方法能夠識別形狀。 首先將原始圖像轉換為灰度。

這是因為這種方法只適用于單通道的灰度圖像。為了獲得更好的結果,我使用“threshold”函數對灰度圖像進行閾值處理。

您可以使用自己的方式對圖像進行閾值處理。然后我找到閾值圖像中的所有輪廓,并識別和跟蹤所有三角形、四邊形和七邊形。

2.2主要函數解析

讓我們討論一下這個應用程序中的OpenCV 函數。

double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type);

src:源圖像(8位單通道)

dst:與src具有相同大小相同類型的目標圖像

thresh:閾值

maxval:滿足條件的像素替換為這個值

type:閾值化方法,

THRESH_BINARY

  • dst(x,y)=max, if src(x,y) > ThreshVal

  • dst(x,y)=0, if src(x,y) < ThreshVal

THRESH_BINARY_INV

  • dst(x,y)=0,如果 src(x,y) > ThreshVal

  • dst(x,y)=max,如果 src(x,y) < ThreshVal

THRESH_TOZERO

  • dst(x,y)=src(x,y), 如果 src(x,y) > ThreshVal

  • dst(x,y)=0, 如果 src(x,y) < ThreshVal

THRESH_TOZERO_INV

  • dst(x,y)=0,如果 src(x,y) > ThreshVal

  • dst(x,y)=src(x,y),如果 src(x,y) < ThreshVal

THRESH_TRUNC

  • dst(x,y)=threshVal,如果 src(x,y) > ThreshVal

  • dst(x,y)=src(x,y), if src(x,y) < ThreshVal

在上面的應用程序中,我使用了“ THRESH_BINARY”,因為我想在對象所在的位置分配 255(白色其他是0(黑色)。

findContours( InputArray image, OutputArrayOfArrays contours, OutputArray hierarchy, int mode, int method, Point offset = Point());

image: 8位單通道圖像。非零像素被視為1。零像素保持為0,因此圖像被視為二值。你可以使用#compare #inRange #threshold,#adaptiveThreshold,

#Canny,以及其他參數來創建灰度或彩色圖像的二值圖像。

contours: 發現的所有輪廓

hierarchy:輪廓之間的層次結構

int mode - 從圖像中檢索輪廓的模式,您必須選擇以下之一

  • RETR_LIST - 檢索所有輪廓并將它們放入列表中

  • RETR_EXTERNAL - 僅檢索外輪廓

  • RETR_CCOMP - 檢索所有輪廓并將它們組織成兩級層次結構:

  • RETR_TREE - 檢索所有輪廓并重建嵌套輪廓的完整層次結構

int method - 近似方法,您必須選擇以下之一

  • CHAIN_APPROX_NONE - 將鏈碼中的所有點轉換為點

  • CHAIN_APPROX_SIMPLE - 壓縮水平、垂直和對角線段,只留下它們的端點

  • CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS - 應用 Teh-Chin 鏈近似算法的一種風格。

Point offset:每個輪廓點應移動的偏移量。當我們在圖像中設置 ROI(感興趣區域)時,這很有用。通常我們將偏移量設置為 &lsquo;Point(0,0)&rsquo;

void approxPolyDP( InputArray curve, OutputArray approxCurve, double epsilon, bool closed );

  • curve: 存儲2D點的std::vector或Mat

  • approxCurve: 多邊形近似的結果。類型應該與輸入類型相匹配。

  • epsilon: 指定近似精度的參數。這是原始輪廓與其近似值之間的最大距離。

  • closed: 如果為真,逼近曲線是閉合的(它的第一個和最后一個頂點是連接的)。否則不閉合。

2.3結果展示

OpenCV形狀檢測功能怎么實現

“OpenCV形狀檢測功能怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

来凤县| 宜兴市| 阿勒泰市| 调兵山市| 屏东县| 阳山县| 清徐县| 彭州市| 庆元县| 彝良县| 竹北市| 盱眙县| 宜章县| 贺兰县| 仙游县| 九龙坡区| 桃园县| 怀远县| 许昌县| 镇康县| 民丰县| 南木林县| 榆林市| 佛坪县| 大足县| 洛阳市| 西乌珠穆沁旗| 三原县| 临安市| 新余市| 大连市| 福泉市| 宜章县| 涞源县| 鱼台县| 长汀县| 洪雅县| 西青区| 屏南县| 博兴县| 邵阳县|