gpt4 book ai didi

python - 如何在Python和Opencv中检测八边形

转载 作者:行者123 更新时间:2023-12-02 16:07:17 25 4
gpt4 key购买 nike

我正在使用 python 中的 opencv 开发形状检测算法。
我正在使用库中的轮廓,并且成功检测出一些形状:圆形,矩形和三角形。
唯一的问题是,我只需要检测圆形的矩形和八边形。
此外,圈子还在运作,但不一致。
所以,这是我的代码:

import cv2
import numpy as np

def nothing(x):
# any operation
pass

cap = cv2.VideoCapture(1)

cv2.namedWindow("Trackbars")
cv2.createTrackbar("L-H", "Trackbars", 0, 180, nothing)
cv2.createTrackbar("L-S", "Trackbars", 66, 255, nothing)
cv2.createTrackbar("L-V", "Trackbars", 134, 255, nothing)
cv2.createTrackbar("U-H", "Trackbars", 180, 180, nothing)
cv2.createTrackbar("U-S", "Trackbars", 255, 255, nothing)
cv2.createTrackbar("U-V", "Trackbars", 243, 255, nothing)

font = cv2.FONT_HERSHEY_COMPLEX

while True:
_, frame = cap.read()
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

l_h = cv2.getTrackbarPos("L-H", "Trackbars")
l_s = cv2.getTrackbarPos("L-S", "Trackbars")
l_v = cv2.getTrackbarPos("L-V", "Trackbars")
u_h = cv2.getTrackbarPos("U-H", "Trackbars")
u_s = cv2.getTrackbarPos("U-S", "Trackbars")
u_v = cv2.getTrackbarPos("U-V", "Trackbars")

lower_yellow = np.array([l_h,l_s, l_v])
upper_yellow = np.array([u_h, u_s, u_v])

mask = cv2.inRange(hsv, lower_yellow, upper_yellow)
kernel = np.ones((5, 5), np.uint8)
mask = cv2.erode(mask, kernel)

# Contours detection
if int(cv2.__version__[0]) > 3:
# Opencv 4.x.x
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
else:
# Opencv 3.x.x
_, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:
area = cv2.contourArea(cnt)
approx = cv2.approxPolyDP(cnt, 0.02*cv2.arcLength(cnt, True), True)
x = approx.ravel()[0]
y = approx.ravel()[1]

if area > 400:
cv2.drawContours(frame, [approx], 0, (0, 0, 0), 5)

if len(approx) == 3:
cv2.putText(frame, "Triangle", (x, y), font, 1, (0, 0, 0))
elif len(approx) == 4:
cv2.putText(frame, "Rectangle", (x, y), font, 1, (0, 0, 0))
elif 10 < len(approx) < 20:
cv2.putText(frame, "Circle", (x, y), font, 1, (0, 0, 0))

cv2.imshow("Frame", frame)
cv2.imshow("Mask", mask)

key = cv2.waitKey(1)
if key == 27:
break

cap.release()
cv2.destroyAllWindows()

我想拥有的是更精确地检测八边形和圆。

最佳答案

要执行形状检测,我们可以使用轮廓逼近。假设对象是简单形状,这是一种使用阈值+轮廓近似的方法。等高线近似是基于这样的假设,即曲线可以由一系列短线段近似,这些短线段可用于确定轮廓的形状。例如,三角形具有三个顶点,正方形/矩形具有四个顶点,五边形具有五个顶点,依此类推。

  • 获取二进制图像。 我们加载图像,转换为灰度,然后
    Otsu's threshold
    获得二进制图像。
  • 检测形状。 使用轮廓近似过滤查找轮廓并识别每个轮廓的形状。可以使用 arcLength 计算轮廓的周长,并使用 approxPolyDP 获得实际的轮廓近似值。


  • 输入图像

    标记形状


    import cv2

    def detect_shape(c):
    # Compute perimeter of contour and perform contour approximation
    shape = ""
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.04 * peri, True)

    # Triangle
    if len(approx) == 3:
    shape = "triangle"

    # Square or rectangle
    elif len(approx) == 4:
    (x, y, w, h) = cv2.boundingRect(approx)
    ar = w / float(h)

    # A square will have an aspect ratio that is approximately
    # equal to one, otherwise, the shape is a rectangle
    shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle"

    # Pentagon
    elif len(approx) == 5:
    shape = "pentagon"

    # Hexagon
    elif len(approx) == 6:
    shape = "hexagon"

    # Octagon
    elif len(approx) == 8:
    shape = "octagon"

    # Star
    elif len(approx) == 10:
    shape = "star"

    # Otherwise assume as circle or oval
    else:
    shape = "circle"

    return shape

    # Load image, grayscale, Otsu's threshold
    image = cv2.imread('1.png')
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

    # Find contours and detect shape
    cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    for c in cnts:
    # Identify shape
    shape = detect_shape(c)

    # Find centroid and label shape name
    M = cv2.moments(c)
    cX = int(M["m10"] / M["m00"])
    cY = int(M["m01"] / M["m00"])
    cv2.putText(image, shape, (cX - 20, cY), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (36,255,12), 2)

    cv2.imshow('thresh', thresh)
    cv2.imshow('image', image)
    cv2.waitKey()

    关于python - 如何在Python和Opencv中检测八边形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60177653/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com