【问题标题】:Predict Rectangle in image using opencv python使用opencv python预测图像中的矩形
【发布时间】:2021-02-19 08:24:02
【问题描述】:

我想预测图像中的矩形并仅使用 opencv python 以框形绘制矩形。我使用下面的代码来预测和绘制矩形,但它不能正常工作。



    import numpy as np
    import cv2
    from PIL import Image
    import sys
    
    Path='D:\Artificial intelligence\Phyton'
    filename='Test.png'
    
    
    # Load image, grayscale, Gaussian blur, and Otsu's threshold
    image = cv2.imread('D:\Artificial intelligence\Phyton\Img21122020113231AM.Jpg')
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    thresh = cv2.threshold(gray, 190, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
    
    # Find contours and sort using contour area
    cnts = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
    for c in cnts:
        # Highlight largest contour
        cv2.drawContours(image, [c], -1, (36,255,12), 3)
        break
    
    
    cv2.imwrite(filename+'_Processingimage_color.jpg', image)

我的输入图像:

Input Image

我的结果:

My Result image

【问题讨论】:

  • 您不是在预测,而是在检测轮廓。那是不同的。另外,您应该先对图像进行一些过滤。
  • “Predicting” 是利用对先前位置(可能还有习惯/行为)的了解来提前说出对象将来可能移动到的位置,即注意到一个球在视频的前 5 帧中向右移动了 10 个像素,以预测它可能在下一帧中向右移动 10 个像素。

标签: python opencv rectangles


【解决方案1】:

对于形状检测,有一个很棒的教程叫做opencv-shape-detection。但是,教程中的预处理不会帮助您找到图像中的大框。您需要申请adaptiveThreshold 而不是threshold。步骤如下:

    1. 调整图像大小并计算比例
    1. 平滑图像
    1. 应用自适应阈值
    1. 查找并抓取轮廓。
    1. 计算周长和大致长度
    1. 如果长度等于 4(表示正方形或矩形),请绘制轮廓。

  • 第一步

    • 我们调整图像大小以使计算和检测更容易。但是,我们还需要计算比率,以免丢失每个轮廓的中心。
  • 第二步

    • 我们应用了高斯模糊来平滑图像。图像中的大部分伪影已被移除。

    • blr = cv2.GaussianBlur(gry, (5, 5), 0)
      
  • 第三步

    • 使用不同参数的简单阈值处理无法产生令人满意的结果。因此我使用adaptiveThreshold 得到结果:

    • thr = cv2.adaptiveThreshold(blr, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 41, 21)
      
  • 第四步

  • 第五步

  • 第六步

    • 如果近似长度等于4,则绘制轮廓。结果将是:


代码:


import cv2
import imutils

# Load the image
img = cv2.imread("zE2lg.jpg")

# Resize the image
rsz = imutils.resize(img, width=300)

# Calculate the ratio
ratio = img.shape[0] / float(rsz.shape[0])

# Convert to gray-scale
gry = cv2.cvtColor(rsz, cv2.COLOR_BGR2GRAY)

# Apply Gaussian-blur
blr = cv2.GaussianBlur(gry, (5, 5), 0)

# Apply threshold
thr = cv2.adaptiveThreshold(blr, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 41, 21)

# Find and grab contours
cnt = cv2.findContours(thr.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnt = imutils.grab_contours(cnt)

# Loop over contours
for c in cnt:
    mmn = cv2.moments(c)

    if mmn["m00"] != 0:
        x = int((mmn["m10"] / mmn["m00"]) * ratio)
        y = int((mmn["m01"] / mmn["m00"]) * ratio)

        prm = cv2.arcLength(c, True)  # perimeter
        apx = cv2.approxPolyDP(c, 0.09 * prm, True)  # approximation

        if len(apx) == 4:
            c = c.astype("float")
            c *= ratio
            c = c.astype("int")
            cv2.drawContours(img, [c], -1, (0, 0, 255), thickness=5)

【讨论】:

  • 感谢您的代码。但这不是一个准确的结果。我想预测完整的棕色框。
【解决方案2】:

您应该能够按照以下步骤在此特定图像中检测到您的纸板箱。您应该能够使用 numpy 和 OpenCV 完成所有这些工作。不过,这将是很多工作,所以我还没有完成。如果其他人想通过它并提供源代码,请随时将他们的答案标记为正确的而不是这个。

  1. 将图像的副本转换为 HSV 颜色空间。
  2. 检测您的纸板颜色,例如深橙色或深黄色。如果 HSV 范围是 0-360、0-255、0-255,那么您想要检测的颜色范围将在 20-60、20-255、20-100 左右。
  3. 将结果转换为二维黑白图像。
  4. 使用较小的内核大小执行形态腐蚀,以消除嘈杂的斑点。内核大小可能约为 3x3。
  5. 使用较大的内核大小执行形态膨胀,以连接任何断开的区域。也许内核大小约为 20x20。
  6. 找到最大的轮廓对象。
  7. 将轮廓转换为最适合的四边形,以摆脱右侧较小的纸板箱。我有时发现先将轮廓转换为凸包,然后再将其转换为四边形会很有帮助。
  8. 在原始图像上绘制四边形。或者裁剪出来。或者你想用它做什么。

这篇 stackoverflow 帖子将帮助您完成第 7 步: How to force approxPolyDP() to return only the best 4 corners? - Opencv 2.4.2

可以在此处找到我上面概述的方法(在检测到棕色纸板颜色后)的另一种潜在解决方案: Extracting the dimensions of a rectangle

【讨论】:

    猜你喜欢
    • 2020-03-05
    • 2013-03-23
    • 1970-01-01
    • 2021-07-03
    • 2019-11-29
    • 2012-05-21
    • 2016-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多