【问题标题】:How to mark the inner corners of a quad marker shape correctly?如何正确标记四边形标记形状的内角?
【发布时间】:2021-04-15 08:10:21
【问题描述】:
  • 我在图像中有 4 个红色标记,我正在检测它们的轮廓并获取直角坐标 [x0,y0,w,h]。

  • 我的目标是识别此序列中的角:

  • 我的问题是当我应用这个很酷的answer 时,有时会遇到问题,因为根据Y 值的排序并不总是正确的,正如您在此处看到的那样:
import numpy as np
import cv2

boundRectsList = [(282, 236, 33, 44), (432, 235, 35, 46), (432, 68, 37, 44), (282, 68, 34, 46)]

# Sort the list based on ascending y values:
boundRectsSorted = sorted(boundRectsList, key=lambda x: x[1])

maskCopy = 255*np.ones((512,768,3), dtype=np.uint8)

# Rectangle dictionary:
# Each entry is an index of the currentRect list
# 0 - X, 1 - Y, 2 - Width, 3 - Height
# Additionally: -1 is 0 (no dimension):
pointsDictionary = {0: (2, 3),
                    1: (-1, 3),
                    2: (2, -1),
                    3: (-1, -1)}

# Store center rectangle coordinates here:
centerRectangle = [None]*4

# Process the sorted rects:
rectCounter = 0

for i in range(len(boundRectsSorted)):

    # Get sorted rect:
    currentRect = boundRectsSorted[i]

    # Get the bounding rect's data:
    rectX = currentRect[0]
    rectY = currentRect[1]
    rectWidth = currentRect[2]
    rectHeight = currentRect[3]

    # Draw sorted rect:
    cv2.rectangle(maskCopy, (int(rectX), int(rectY)), (int(rectX + rectWidth),
                             int(rectY + rectHeight)), (0, 255, 0), 5)

    # Get the inner points:
    currentInnerPoint = pointsDictionary[i]
    borderPoint = [None]*2

    # Check coordinates:
    for p in range(2):
        # Check for '0' index:
        idx = currentInnerPoint[p]
        if idx == -1:
            borderPoint[p] = 0
        else:
            borderPoint[p] = currentRect[idx]

    # Draw the border points:
    color = (0, 0, 255)
    thickness = 2
    centerX = rectX + borderPoint[0]
    centerY = rectY + borderPoint[1]
    radius = 10
    cv2.circle(maskCopy, (centerX, centerY), radius, color, thickness)

    # Mark the circle
    org = (centerX - 5, centerY + 5)
    font = cv2.FONT_HERSHEY_SIMPLEX
    cv2.putText(maskCopy, str(rectCounter), org, font,
            2, (0, 0, 0), 2, cv2.LINE_8)

    # Store the coordinates into list
    if rectCounter == 0:
        centerRectangle[0] = centerX
        centerRectangle[1] = centerY
    else:
        if rectCounter == 1:
            centerRectangle[2] = centerX - centerRectangle[0]
        else:
            if rectCounter == 2:
                centerRectangle[3] = centerY - centerRectangle[1]
    # Increase rectCounter:
    rectCounter += 1

cv2.namedWindow("Sorted Rects", cv2.WINDOW_NORMAL)
cv2.imshow("Sorted Rects", maskCopy)
cv2.waitKey(0)

是否有正确的方法来获取内角的上序列?提前致谢。

【问题讨论】:

    标签: python list opencv image-processing geometry


    【解决方案1】:

    我会使用自定义排序函数,它同时考虑x 和y 坐标,并允许一些公差w.r.t。 y 坐标。在这里,我将简单地从 earlier answer from me 中回收代码(另外,关于所描述函数的详细信息,请参见那里):

    import numpy as np
    import cv2
    from functools import cmp_to_key                                        # <--
    
    
    def rect_sort(a, b):                                                    # <--
        if abs(a[1] - b[1]) <= 15:                                          # <--
            return a[0] - b[0]                                              # <--
        return a[1] - b[1]                                                  # <--
    
    
    boundRectsList = [(282, 236, 33, 44), (432, 235, 35, 46), (432, 68, 37, 44), (282, 68, 34, 46)]
    
    boundRectsSorted = sorted(boundRectsList, key=cmp_to_key(rect_sort))    # <--
    
    # [...]
    

    我得到了想要的输出:

    ----------------------------------------
    System information
    ----------------------------------------
    Platform:      Windows-10-10.0.16299-SP0
    Python:        3.9.1
    PyCharm:       2021.1
    NumPy:         1.20.2
    OpenCV:        4.5.1
    ----------------------------------------
    

    【讨论】:

      【解决方案2】:

      如果如问题中所述,您在通用情况下针对quad 而不仅仅是一个矩形,那么您应该考虑一种更通用的方法,而不仅仅是假设您在其中一个方面有细微的差异轴。

      1- 找到两条对角线的交点(使用简单的线交点

      2- 交点坐标将空间划分为4个区域(左、上、右、下)。

      3- 通过将角的坐标与交点坐标进行比较,您可以将它们标记为 (TL, TR ..) 或 (0, 1, 2, 3)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-11-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多