0

我需要检测使用 OpenCV 标记的选项。目前,我已经能够检测到所有方块,但标记的方块除外。我已经使用以下代码完成了此操作。

canny = (cv2.Canny(roi_box, 30, 100))
cv2_imshow(canny)
img = roi_box.copy()

contours, heirarchy = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cntsSorted = sorted(contours, key=lambda x:cv2.contourArea(x))

print("contours %i" % len(contours))
for i in range(45, 0, -1):
    cv2.drawContours(img, cntsSorted[i], -1, (0, 255,0), 4)
    if (cv2.contourArea(cntsSorted[i]) > 300):
        cv2_imshow(img)

标记的正方形面积约为 50。有人可以建议我如何解决这个问题吗?

我的工作到现在

4

1 回答 1

1
    1. 找到图像的特征。
    • 对于每个通道(bluegreenred),您可以将medianBlurCanny、 和bitwise-or一起应用。

      img = cv2.imread("npDro.png")
      bor = np.zeros(img.shape[:2], dtype="uint8")
      for chn in cv2.split(img):
          chn = cv2.medianBlur(chn, 11)
          cny = cv2.Canny(chn, 50, 200)
          bor = cv2.bitwise_or(bor, cny)
      
    • 结果:(重新调整w/2, h/2:)

      • 在此处输入图像描述
    • 应用medianBlur和操作不是必须做Cannybitwise-or预处理。但是,在此示例中,仅应用Canny或仅应用MedianBlur没有用。您可能会找到另一种组合。上面的代码只是一个例子。

    1. 寻找轮廓
    • cnt = cv2.findContours(bor.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
      cnt = imutils.grab_contours(cnt)
      cnt = sorted(cnt, key=cv2.contourArea, reverse=True)[:4]
      
    • If我对轮廓进行排序的原因是还检测到了文本值。因此我只得到前四个正方形的轮廓。

    1. 对于每个检测到contour的绘制rectangle.
    • for (i, c) in enumerate(cnt):
      M = cv2.moments(c)
      cX = int(M["m30"] / M["m20"])
      cY = int(M["m03"] / M["m02"])
      cv2.rectangle(img,
                    pt1=(cX-30, cY-30),
                    pt2=(cX+20, cY+20),
                    color=(255, 0, 0), thickness=3)
      
  • 结果:

    • 在此处输入图像描述

代码:


import cv2
import imutils
import numpy as np

img = cv2.imread("npDro.png")
bor = np.zeros(img.shape[:2], dtype="uint8")
for chn in cv2.split(img):
    chn = cv2.medianBlur(chn, 11)
    cny = cv2.Canny(chn, 50, 200)
    bor = cv2.bitwise_or(bor, cny)
cnt = cv2.findContours(bor.copy(), cv2.RETR_EXTERNAL,
                       cv2.CHAIN_APPROX_SIMPLE)
cnt = imutils.grab_contours(cnt)
cnt = sorted(cnt, key=cv2.contourArea, reverse=True)[:4]
for (i, c) in enumerate(cnt):
    M = cv2.moments(c)
    cX = int(M["m30"] / M["m20"])
    cY = int(M["m03"] / M["m02"])
    cv2.rectangle(img,
                  pt1=(cX-30, cY-30),
                  pt2=(cX+20, cY+20),
                  color=(255, 0, 0), thickness=3)
cv2.imshow("img", img)
cv2.waitKey(0)
于 2020-12-11T21:42:39.220 回答