繁体   English   中英

使用 opencv python 预测图像中的矩形

[英]Predict Rectangle in image using opencv python

我想预测图像中的矩形并仅使用 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)

我的输入图像:

输入图像

我的结果:

我的结果图片

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

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

  • 步骤1

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

    • 在此处输入图像描述

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

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

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

    • 在此处输入图像描述

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

    • 以与使用不同层次结构参数相同的方式查找轮廓。 请参阅轮廓层次结构
  • 第 5 步

    • 对于每个轮廓,计算周长和近似参数。 轮廓特征
  • 第 6 步

    • 如果近似长度等于 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)

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

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

这篇 stackoverflow 帖子将有助于第 7 步: 如何强制 approxPolyDP() 只返回最好的 4 个角? - Opencv 2.4.2

可以在此处找到我上面概述的方法的另一种潜在解决方案(在检测到棕色纸板颜色之后): 提取矩形的尺寸

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM