具有轮廓的纸牌的4个角

问题描述 投票:0回答:1

我正在尝试查找纸牌的4个角的坐标,因此我可以用它来扭曲纸牌的角度,以后再用于识别。我曾尝试使用cv.boundingRect,但由于即时通讯使用实时视频,我只需要卡片,而不需要卡片的最近矩形。现在它可以使用boundingRect起作用,但是如果我倾斜图像的角度,则坐标是boundingRect而不是纸牌。看图片:straight angle...crooked angle

然后,我需要使用纸牌4个角的轮廓坐标,而不是使用boundingRect。到目前为止,这是我的方法:

def getContours(img, imgContour, standardimg):
global counter
contours, hierachy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

for contour in contours:
    area = cv2.contourArea(contour)
    areaMin = cv2.getTrackbarPos("area", "parameters")
    if area > areaMin:
        cv2.drawContours(imgContour, contour, -1, (255, 0, 255), 5)
        peri = cv2.arcLength(contour, True)
        approx = cv2.approxPolyDP(contour, 0.04 * peri, True)

        if len(approx) == 4:
            x, y, w, h = cv2.boundingRect(approx)

            cv2.rectangle(imgContour, (x, y), (x + w, y + h), (255, 255, 0), 3)


            cv2.putText(imgContour, "Area: " + str(int(area)), (x + w + 20, y + 45), cv2.FONT_HERSHEY_COMPLEX, 0.7,
                        (0, 255, 0), 2)

            if cv2.waitKey(1) & 0xFF == ord('c'):
                counter = counter + 1
                cv2.imwrite('warpedPicture' + str(counter) + '.jpg', imgContour)

                coordinates.insert(0, x)
                coordinates.insert(1, y)
                coordinates.insert(2, h)
                coordinates.insert(3, w)
                warpPicture(coordinates[0], coordinates[1], coordinates[2], coordinates[3], standardimg)
python opencv opencv-contour
1个回答
0
投票

Python / OpenCV中一种可能比边界框更好的可能方法如下:

  • 读取输入
  • 转换为灰色
  • 阈值
  • 获取外部轮廓
  • 计算周长
  • 将轮廓近似为四边形
  • 在输入上绘制四边形
  • 保存结果

输入A:

enter image description here

import cv2
import numpy as np

# load image
img = cv2.imread("5_hearts_A.png")
hh, ww = img.shape[:2]

# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# threshold the grayscale image
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]

# remove white borders
thresh = thresh[2:hh-2, 2:ww-2]
thresh = cv2.copyMakeBorder(thresh, 2,2,2,2, cv2.BORDER_REPLICATE)

# find outer contour
cntrs = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1]
cntr = cntrs[0]

# draw contour on copy of img as result
contour = img.copy()
cv2.drawContours(contour,[cntr], 0, (0,0,255), 1)

# limit contour to quadrilateral
peri = cv2.arcLength(cntr, True)
corners = cv2.approxPolyDP(cntr, 0.04 * peri, True)

# draw quadrilateral on input image from detected corners
result = img.copy()
cv2.polylines(result, [corners], True, (0,0,255), 1, cv2.LINE_AA)

# write result to disk
cv2.imwrite("5_hearts_A_contour.png", contour)
cv2.imwrite("5_hearts_A_quadrilateral.png", result)

# display results
cv2.imshow("THRESH", thresh)
cv2.imshow("CONTOUR", contour)
cv2.imshow("QUAD", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

轮廓图:

enter image description here

产生的四边形:

enter image description here

类似于图像B:

enter image description here

图像B的轮廓:

enter image description here

图像B的结果:

enter image description here

一种可能会做得更好的方法是对阈值图像进行Canny边缘检测。然后进行霍夫线变换。然后计算直线的交点以找到角。

© www.soinside.com 2019 - 2024. All rights reserved.