Fat*_*aur 2 python opencv image-processing
我正在尝试创建一个程序,在这里需要很长时间来解释,所以我会告诉你们我需要帮助的部分。
这里我需要检测一个矩形(在我们的示例中它将是一个车牌)。它的识别几乎完美,但我希望它更精确。这是我使用的示例图像。
正如您所看到的,它在查找方面做得相当好,但我也想考虑圆角。
这是源代码
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()
Run Code Online (Sandbox Code Playgroud)
有什么方法可以实现这一目标以及如何实现这一目标,或者我是否在这方面付出了太多努力?
编辑:添加示例图像。抱歉之前没有包括在内,是我的错。
首先,在您的函数中,我用 替换了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
Run Code Online (Sandbox Code Playgroud)
然后,我定义了一个函数 ,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
Run Code Online (Sandbox Code Playgroud)
接下来,我将从图像中检测到的轮廓(使用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))]
Run Code Online (Sandbox Code Playgroud)
最后,我使用 `` 函数从每个部分获取两个坐标,并将它们放入 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()
Run Code Online (Sandbox Code Playgroud)
输出:
全部一起:
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()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1707 次 |
最近记录: |