我正在嘗試創建一個需要很長時間在這里解釋的程式,所以我會告訴你們我需要幫助的部分。
在這里,我需要檢測一個矩形(在我們的示例中將是一個車牌)。它幾乎完美地進行了識別,但我希望它更精確。這是我使用的示例影像。

如您所見,它在找到它方面做得相當不錯,但我也想考慮圓角。
這是源代碼
import numpy as np
import cv2
import imutils
def find_edges(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (3, 3), 0)
edged = cv2.Canny(image=gray, threshold1=100, threshold2=200)
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
if len(approx) == 4:
screenCnt = approx
break
return screenCnt
image = cv2.imread('img/plate.jpeg')
cnt = find_edges(image)
cv2.drawContours(image, [cnt], -1, (0, 255, 0), 2)
cv2.imshow('Outline', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
有什么方法可以實作這一點,如何實作,還是我在這方面努力太多了?

編輯:添加示例影像。很抱歉之前沒有包括在內,我的錯。
uj5u.com熱心網友回復:
首先,在你的find_edges功能,我取代了線screenCnt = approx帶screenCnt = c,以保持在所產生的檢測輪廓全部坐標:
def find_edges(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (3, 3), 0)
edged = cv2.Canny(image=gray, threshold1=100, threshold2=200)
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
if len(approx) == 4:
screenCnt = c
break
return screenCnt
然后,我定義了一個函式,get_opposites,它將接收一個輪廓,并從輪廓中回傳彼此相距最遠的兩個坐標:
def get_opposites(cnt):
current_max = 0
c = None
for a, b in combinations(cnt, 2):
current_distance = np.linalg.norm(a - b)
if current_distance > current_max:
current_max = current_distance
c = a, b
return c
接下來,我將從影像中檢測到的輪廓(使用find_edges您定義的函式 我的更改)分成兩部分;第一部分包含輪廓的左上角 右下角四分之一,第二部分包含輪廓的右上角 左下角四分之一:
image = cv2.imread('img/plate.jpeg')
cnt = find_edges(image)
xs = cnt[..., 0]
ys = cnt[..., 1]
x_mid = (np.amin(xs) np.amax(xs)) // 2
y_mid = (np.amin(ys) np.amax(ys)) // 2
tl_br = cnt[((ys < y_mid) & (xs < x_mid)) | ((ys > y_mid) & (xs > x_mid))]
tr_bl = cnt[((ys > y_mid) & (xs < x_mid)) | ((ys < y_mid) & (xs > x_mid))]
最后,我使用``函式從每個部分獲取兩個坐標,并將它們放入一個numpy陣列中以繪制到影像上:
p1, p3 = get_opposites(tl_br)
p2, p4 = get_opposites(tr_bl)
cv2.polylines(image, np.array([[p1, p2, p3, p4]], np.int32), True, (0, 255, 0), 2)
cv2.imshow('Outline', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
輸出:

全部一起:
import numpy as np
import cv2
import imutils
from itertools import combinations
def find_edges(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (3, 3), 0)
edged = cv2.Canny(image=gray, threshold1=100, threshold2=200)
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
if len(approx) == 4:
screenCnt = c
break
return screenCnt
def get_opposites(cnt):
current_max = 0
c = None
for a, b in combinations(cnt, 2):
current_distance = np.linalg.norm(a - b)
if current_distance > current_max:
current_max = current_distance
c = a, b
return c
image = cv2.imread('img/plate.jpeg')
cnt = find_edges(image)
xs = cnt[..., 0]
ys = cnt[..., 1]
x_mid = (np.amin(xs) np.amax(xs)) // 2
y_mid = (np.amin(ys) np.amax(ys)) // 2
tl_br = cnt[((ys < y_mid) & (xs < x_mid)) | ((ys > y_mid) & (xs > x_mid))]
tr_bl = cnt[((ys > y_mid) & (xs < x_mid)) | ((ys < y_mid) & (xs > x_mid))]
p1, p3 = get_opposites(tl_br)
p2, p4 = get_opposites(tr_bl)
cv2.polylines(image, np.array([[p1, p2, p3, p4]], np.int32), True, (0, 255, 0), 2)
cv2.imshow('Outline', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/388436.html
上一篇:【二叉樹】葉子相似的樹
