python - 如何检测图像中的纸板箱?

标签 python opencv

我正在寻找 python 解决方案。

我正在使用opencv来检测图像中的框,但我觉得结果不一致。盒子应该始终是二维的,但偶尔可能会有点倾斜或白色。

我只能检测盒子区域。

我尝试过这个:

import cv2

# reading image
img = cv2.imread('cardboard.jpg')

# thresholding the image
ret,thresh = cv2.threshold(img, 127, 229, cv2.THRESH_TOZERO_INV)
edged = cv2.cvtColor(thresh, cv2.COLOR_BGR2GRAY)

# collectiong contours
_, contours,h = cv2.findContours(edged, cv2.RETR_TREE,
                    cv2.CHAIN_APPROX_SIMPLE)

# looping through contours
for cnt in contours:

    x, y, w, h = cv2.boundingRect(cnt)
    if w > 100 and h > 100:
        approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)

        if len(approx) < 6:
            cv2.drawContours(img_x,[cnt],0,(0,215,255),3)

cv2.imwrite('contours/img.jpg', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

enter image description here

enter image description here

最佳答案

我尝试了你的代码,它只适用于第二张图像(识别 9 个盒子中的 8 个),因为你的盒子有白色标签,它与背景形成了很好的对比。但是,它不适用于上传的第一张图片。

在第二张图片中,由于光照变化,您的代码无法识别所有框(这会导致阈值处理问题,因此仅检测到 8 个框),因此我建议阅读有关计算机视觉的光照,因为它可以简化您的操作编码很多。话虽这么说,我已经对您的代码进行了更改,也许可以让您了解如何继续(代码中包含注释)...我已经用第二张图像对其进行了测试,它确实识别了所有框,但它仍然应该是进一步测试。如果您想检测您发布的两种图像上的框,则需要采用不同的方法。

代码:

import cv2

# reading image
img = cv2.imread('boxes.jpg')

# thresholding the image
ret,thresh = cv2.threshold(img, 127, 229, cv2.THRESH_TOZERO)
edged = cv2.cvtColor(thresh, cv2.COLOR_BGR2GRAY)

# ADDED BINARY THRESHOLD
ret,thresh = cv2.threshold(edged,100,255,cv2.THRESH_BINARY)


# collectiong contours
_, contours,h = cv2.findContours(edged, cv2.RETR_TREE,
                    cv2.CHAIN_APPROX_SIMPLE)
cv2.imshow('img', thresh)

# looping through contours
for cnt in contours:

    x, y, w, h = cv2.boundingRect(cnt)
    if w > 50 and h > 50:

        #ADDED SIZE CRITERION TO REMOVE NOISES
        size = cv2.contourArea(cnt)
        if size > 500:

            #CHANGED DRAWING CONTOURS WITH RECTANGLE
            cv2.rectangle(img,(x,y),(x+w,y+h),(0,215,255),2)

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果:

enter image description here

编辑:

我已经为第二张图片制作了代码示例,这在进一步的尝试中可能有用。首先,您确定一个范围来对图像进行阈值设置,达到阈值上限并绘制轮廓。

enter image description here

然后将图像转换为 HSV 色彩空间并使用 cv2.inRange() 查找颜色。

enter image description here

然后通过搜索轮廓并在其上绘图来填充它。

enter image description here

最后在轮廓上绘制矩形。

import cv2
import numpy as np

# reading image
img = cv2.imread('boxes.jpg')
img_x = img.copy()


for low_thresh in range(0,25):

    ret,thresh = cv2.threshold(img, low_thresh*10, 255, cv2.THRESH_TOZERO_INV)
    edged = cv2.cvtColor(thresh, cv2.COLOR_BGR2GRAY)
    _, contours,h = cv2.findContours(edged, cv2.RETR_TREE,
                        cv2.CHAIN_APPROX_SIMPLE)

    for cnt in contours:
        size = cv2.contourArea(cnt)
        if 500 < size < 50000:
            x, y, w, h = cv2.boundingRect(cnt)

            if w > 100 and h > 100:
                approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)

                if len(approx) < 6:
                    cv2.drawContours(img,[cnt],0,(0,215,255),3)

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

lower_yellow = np.array([25,50,50])
upper_yellow = np.array([50,255,255])
mask_yellow = cv2.inRange(hsv, lower_yellow, upper_yellow)
res_yellow = cv2.bitwise_and(img,img, mask=mask_yellow)
gray_yellow = cv2.cvtColor(res_yellow, cv2.COLOR_BGR2GRAY)
_,thresh_yellow = cv2.threshold(mask_yellow,10,255,cv2.THRESH_BINARY)
_, contours_yellow, hierarhy = cv2.findContours(thresh_yellow,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

for c in contours_yellow:
    size = cv2.contourArea(c)
    if size > 500:
        cv2.drawContours(thresh_yellow, [c], -1, 255, -1)

_, contours_yellow, hierarhy3 = cv2.findContours(thresh_yellow,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

for c in contours_yellow:
    size = cv2.contourArea(c)
    if size > 500:
        cv2.drawContours(thresh_yellow, [c], -1, 255, -1)
        x, y, w, h = cv2.boundingRect(c)
        cv2.rectangle(img_x,(x,y),(x+w,y+h),(0,255,0),2)

cv2.imshow('img', img_x)
cv2.waitKey(0)
cv2.destroyAllWindows()

enter image description here

希望对大家有一点帮助。干杯!

关于python - 如何检测图像中的纸板箱?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51670043/

相关文章:

c++ - 加速人员检测程序,使用 OpenCV 3.0 编写

python - 如何在python中访问xml文档中的Beautifulsoup保留字?

python - 过零率

python - 使用字典来匹配密码子

opencv - 如何分类是单个数字还是多个数字

android - 如何在android相机api上进行图像分析

c# - ARKit 中是否公开了 pnp 求解器,或者如何使用 EmguCV c# 包装器在 Unity3D 项目中使用 opencv 的 SolvePnP 函数

python - 如何计算代表最低可能重量差异的数字

python - 如何释放在 SWIG 的自定义构造函数中分配的内存?

python - OpenCV 在 cv.Resize 上崩溃