亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

OpenCV-Python如何實現輪廓擬合

發布時間:2021-06-08 13:59:30 來源:億速云 閱讀:379 作者:小新 欄目:開發技術

這篇文章主要介紹OpenCV-Python如何實現輪廓擬合,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

前言

什么是輪廓?

輪廓可以簡單認為成將連續的點(連著邊界)連在一起的曲線,具有相同 的顏色或者灰度。輪廓在形狀分析和物體的檢測和識別中很有用。

  • 為了更加準確,要使用二值化圖像。在尋找輪廓之前,要進行閾值化處理 或者 Canny 邊界檢測。

  • 查找輪廓的函數會修改原始圖像。如果你在找到輪廓之后還想使用原始圖 像的話,你應該將原始圖像存儲到其他變量中。

  • 在 OpenCV 中,查找輪廓就像在黑色背景中超白色物體。你應該記住, 要找的物體應該是白色而背景應該是黑色。

在計算輪廓時,可能并不需要實際的輪廓,而僅需要一個接近于輪廓的近似多邊形。比如矩形其實都是差不多的輪廓,都是長寬不相等且平行的四邊形,那么只要提供一個近似的輪廓,我們就可以區分形狀。

在OpenCV中,它給我們提供了cv2.boundingRect()函數來繪制輪廓的矩形邊界,其完整定義如下:

def boundingRect(array):

array:前面已經介紹過,array是一個灰度圖像,或者輪廓。

該函數返回3個值時,是矩形邊界的左上角頂點的坐標值以及矩形邊界的寬與高。返回4個值時,是矩形左上角頂點的x坐標,y坐標,以及寬高。

繪制橢圓的矩形邊界

現在,我們還是使用前面的一張橢圓圖形,如下圖所示:

OpenCV-Python如何實現輪廓擬合

得到圖形之后,我們使用上面的函數,計算該圖像輪廓的4值,代碼如下:

import cv2

img = cv2.imread("26_1.jpg")

# 轉換為灰度圖像
gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
x, y, w, h = cv2.boundingRect(contours[0])
print(x, y, w, h)

運行之后,控制臺輸出如下內容:

OpenCV-Python如何實現輪廓擬合

這里我們得到了橢圓的矩形左上角坐標為(53,120),其寬高分別為272與84。

既然我們已經得到了其矩形邊界的坐標以及寬高,那么我們可以開始繪制其矩形邊界。前面提取輪廓繪制用的是cv2.drawContours()函數,這里同樣也是。

代碼如下:

import cv2
import numpy as np

img = cv2.imread("26_1.jpg")
cv2.imshow("img1",img)
# 轉換為灰度圖像
gray= cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
x, y, w, h = cv2.boundingRect(contours[0])
rect=np.array([[[x,y],[x+w,y],[x+w,y+h],[x,y+h]]])#1
cv2.drawContours(img,[rect],-1,(255,255,255),2)#1

cv2.imshow("img2",img)

cv2.waitKey()
cv2.destroyAllWindows()

運行之后,其橢圓的矩形邊界就被我們標記出來了,效果如下:

OpenCV-Python如何實現輪廓擬合

當然,這里我們還可以使用另一個函數cv2.rectangle()來繪制矩形邊界,值需要更換上面代碼中注釋1的兩個代碼,具體如下所示:

cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255,255),2)

最小包圍矩形框

在OpenCV中,它還提供了cv2.minAreaRect()來繪制最小包圍矩形框,其完整定義如下:

def minAreaRect(points):

其中points參數是輪廓,返回值為矩形特征信息,包括矩形的中心(x,y),寬高,以及旋轉角度。

特別注意,minAreaRect函數的返回值并不能直接代入drawContours()函數中。因此,我們必須將其轉換為符合要求的結構才能接著操作。通過cv2.boxPoint()函數就可以轉換為符合drawContours()的結構參數。

還是上面那張圖,不過我們用旋轉后的橢圓原圖,代碼如下:

import cv2
import numpy as np

img = cv2.imread("26_4.jpg")

cv2.imshow("img1",img)
# 轉換為灰度圖像
gray= cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
rect= cv2.minAreaRect(contours[0])
print(rect)
points=cv2.boxPoints(rect)
print(points)
points=np.int0(points)
print(points)
cv2.drawContours(img,[points],0,(255,255,255),2)

cv2.imshow("img2",img)

cv2.waitKey()
cv2.destroyAllWindows()

運行之后,圖像效果以及控制臺的輸出信息如下:

OpenCV-Python如何實現輪廓擬合

OpenCV-Python如何實現輪廓擬合

這里我們可以清楚的看到minAreaRect()函數返回值的轉換過程。先通過boxPoints()函數轉換為drawContours()函數能接受的參數格式,然后通過取整轉換為具體的像素坐標值。

最小包圍圓形框

既然有最小包圍矩形框,那么一定就有最小包圍圓形框。在OpenCV中,它給我們提供cv2.minEnclosingCircle()函數來繪制最小包圍圓形框。

函數的完整定義如下:

def minEnclosingCircle(points):

這里的參數與上面的points參數一致,但是其返回值并不相同,畢竟繪制圓形肯定與繪制矩形的參數肯定不一樣。

它有兩個返回值,一個是圓形的中心坐標(x,y),一個是圓形的半徑r。下面,我們直接來繪制上面橢圓的最小包圍圓形框。具體代碼如下所示:

import cv2
import numpy as np

img = cv2.imread("26_4.jpg")

cv2.imshow("img1", img)
# 轉換為灰度圖像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
(x, y), r = cv2.minEnclosingCircle(contours[0])
center = (int(x), int(y))
r = int(r)
cv2.circle(img, center, r, (255, 255, 255), 2)

cv2.imshow("img2", img)

cv2.waitKey()
cv2.destroyAllWindows()

運行之后,效果如下所示:

OpenCV-Python如何實現輪廓擬合

最優擬合橢圓

在OpenCV中,它給我們提供了cv2.fitEllipse()函數繪制最優擬合橢圓。其完整的定義如下:

def fitEllipse(points):

其中points參數與前文一致,而它的返回值是RotatedRect類型,這是因為該函數返回的是擬合橢圓的外接矩形,包括矩形的質心,寬高,旋轉角度等信息,這些信息正好與橢圓的中心點,軸長度,旋轉角度一致。

下面,我們來使用該函數繪制最優擬合橢圓,這里我們選取如上圖所示的一張矩形圖。具體代碼如下:

import cv2

img = cv2.imread("27.jpg")

cv2.imshow("img1", img)
# 轉換為灰度圖像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
ellipse = cv2.fitEllipse(contours[0])

cv2.ellipse(img, ellipse, (0, 0, 255), 3)

cv2.imshow("img2", img)

cv2.waitKey()
cv2.destroyAllWindows()

運行之后,效果如下所示:

OpenCV-Python如何實現輪廓擬合

最優擬合直線

在OpenCV中,它還提供了cv2.fitLine()函數繪制最優擬合直線,其完整定義如下:

def fitEllipse(points):

points:與前文一樣,是輪廓

distType:距離類型。擬合直線時,要使輸入點到擬合直線的距離之和最小。詳細參數定義參考開發文檔,這里不在贅述。

param:距離參數,與所選距離類型有關。當該參數為0時,自動選擇最優值。

reps:用于表示擬合直線所需要的徑向精度,通常該值被設定為0.01

aeps:用于表示擬合直線所需要的角度精度,通常該值被設定為0.01

對于二維直線,返回值line為4維,前兩維代表擬合出的直線的方向,后兩位代表直線上的一點。

下面,我們來直接使用代碼繪制最優擬合直線。

import cv2

img = cv2.imread("27.jpg")

cv2.imshow("img1", img)
# 轉換為灰度圖像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
ellipse = cv2.fitEllipse(contours[0])

cv2.ellipse(img, ellipse, (0, 0, 255), 3)

cv2.imshow("img2", img)

cv2.waitKey()
cv2.destroyAllWindows()

運行之后,效果如下所示:

OpenCV-Python如何實現輪廓擬合

對于繪制直線來說,我們需要獲取繪制直線的起點以及終點,這里lefty為起點,righty為終點。

最小外包三角形

在OpenCV,它還提供了cv2.minEnclosingTriangle()函數來繪制最小外包三角形。其完整定義如下:

def minEnclosingTriangle(points, triangle=None):

其中points與前文類似,其返回值triangle為外包三角形的三個頂點集。

下面,我們直接構建最小外包三角形,具體代碼如下:

import cv2

img = cv2.imread("27.jpg")

cv2.imshow("img1", img)
# 轉換為灰度圖像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

area, trg1 = cv2.minEnclosingTriangle(contours[0])
print(area)
print(trg1)
for i in range(0, 3):
    cv2.line(img, tuple(trg1[i][0]), tuple(trg1[(i + 1) % 3][0]), (0, 255, 0), 2)

cv2.imshow("img2", img)

cv2.waitKey()
cv2.destroyAllWindows()

運行之后,效果如下:

OpenCV-Python如何實現輪廓擬合

需要注意的是,在cv2中沒有直接繪制三角形的函數,所以我們通過繪制三條直線,繪制三角形,minEnclosingTriangle()函數第一個返回值為三角形面積,第二返回值是三點坐標。

逼近多邊形

在OpenCV中,它還提供了cv2.approxPolyDP()函數構建指定邊數的逼近多邊形。其完整定義如下:

def approxPolyDP(curve, epsilon, closed, approxCurve=None):

curve:輪廓

epsilon:精度,原始輪廓的邊界點與逼近多邊形邊界之間的最大距離

closed:布爾類型。為True時,表示逼近多邊形是封閉的。為False時,biao表示畢竟多邊形是不封閉的。

approxCurve為該函數的返回值,是逼近多邊形的點集。。

下面,我們來實現各類逼近多邊形的繪制,代碼如下:

import cv2

img = cv2.imread("24.jpg")

list=[0.1,0.09,0.055,0.05,0.02]

cv2.imshow("img", img)
# 轉換為灰度圖像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

for i, val in enumerate(list):
    epsilon = val * cv2.arcLength(contours[0], True)
    approx = cv2.approxPolyDP(contours[0], epsilon, True)
    cv2.drawContours(img, [approx], 0, (0, 255, 0), 2)

    cv2.imshow("img"+str(i), img)

cv2.waitKey()
cv2.destroyAllWindows()

運行之后,效果如下:

OpenCV-Python如何實現輪廓擬合

cv2.approxPolyDP()函數采用的是Douglas-Peucker算法,該算法的原理是首先從輪廓中找到距離最遠的兩個點,并將兩個點相連。接下來,在輪廓上找到一個離當前直線最遠的點,并將該點與原有直線連成一個封閉的多邊形,此時得到一個三角形。以此類推四邊形,五邊形,六邊形等。當前多邊形的距離都小于函數cv2.approxPolyDP()的參數epsilon的值時,就停止迭代。

以上是“OpenCV-Python如何實現輪廓擬合”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

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

AI

乌鲁木齐市| 石狮市| 南开区| 秭归县| 永福县| 平潭县| 缙云县| 屏东县| 简阳市| 黎川县| 东乌| 名山县| 绥化市| 彭阳县| 绍兴县| 潼南县| 吉木萨尔县| 桑植县| 伽师县| 珲春市| 昭平县| 乐至县| 田阳县| 甘孜县| 余江县| 昔阳县| 报价| 景泰县| 墨玉县| 远安县| 舒兰市| 墨江| 连平县| 仁寿县| 南汇区| 白城市| 安吉县| 广东省| 桐乡市| 托克逊县| 酒泉市|