gpt4 book ai didi

python - 如何可靠地检测条码的 4 个角?

转载 作者:行者123 更新时间:2023-12-02 16:37:45 25 4
gpt4 key购买 nike

我正在尝试检测这个 Code128 Python 条码 + zbar模块:



(图片下载链接here)。

这有效:

import cv2, numpy
import zbar
from PIL import Image
import matplotlib.pyplot as plt

scanner = zbar.ImageScanner()
pil = Image.open("000.jpg").convert('L')
width, height = pil.size
plt.imshow(pil); plt.show()
image = zbar.Image(width, height, 'Y800', pil.tobytes())
result = scanner.scan(image)

for symbol in image:
print symbol.data, symbol.type, symbol.quality, symbol.location, symbol.count, symbol.orientation

但只检测到一个点: (596, 210) .

如果我应用黑白阈值:
pil = Image.open("000.jpg").convert('L')
pil = pil .point(lambda x: 0 if x<100 else 255, '1').convert('L')

更好,我们有 3 个点:(596, 210), (482, 211), (596, 212)。但它增加了一个难度(为每个新图像自动找到最佳阈值 - 这里为 100)。

不过,我们没有条形码的 4 个角。

问题:如何使用 Python 可靠地找到图像上条形码的 4 个角? (也许是 OpenCV 或其他库?)

笔记:
  • 有可能,这是一个很好的例子(但遗憾的是,它不是评论中提到的开源):

    Object detection, very fast and robust blurry 1D barcode detection for real-time applications

    角点检测似乎非常好而且非常快,即使条形码只是整个图像的一小部分 (这对我很重要)。

  • 有趣的解决方案:Real-time barcode detection in video with Python and OpenCV但该方法存在局限性(见文章:条码应特写等),限制了潜在用途。此外,我更多的是为此寻找一个现成的库。
  • 有趣的解决方案2:Detecting Barcodes in Images with Python and OpenCV但同样,它看起来不像是一个生产就绪的解决方案,而更像是一个正在进行的研究。事实上,我在这张图片上尝试了他们的代码,但检测并没有产生成功的结果。必须注意的是,检测时不考虑条形码的任何规范(事实上有一个 start/stop symbol 等)
    import numpy as np
    import cv2
    image = cv2.imread("000.jpg")
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    gradX = cv2.Sobel(gray, ddepth = cv2.CV_32F, dx = 1, dy = 0, ksize = -1)
    gradY = cv2.Sobel(gray, ddepth = cv2.CV_32F, dx = 0, dy = 1, ksize = -1)
    gradient = cv2.subtract(gradX, gradY)
    gradient = cv2.convertScaleAbs(gradient)
    blurred = cv2.blur(gradient, (9, 9))
    (_, thresh) = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7))
    closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
    closed = cv2.erode(closed, None, iterations = 4)
    closed = cv2.dilate(closed, None, iterations = 4)
    (_, cnts, _) = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    c = sorted(cnts, key = cv2.contourArea, reverse = True)[0]
    rect = cv2.minAreaRect(c)
    box = np.int0(cv2.boxPoints(rect))
    cv2.drawContours(image, [box], -1, (0, 255, 0), 3)
    cv2.imshow("Image", image)
    cv2.waitKey(0)
  • 最佳答案

    解决方案2非常好。导致图像失败的关键因素是阈值。如果删除参数 225一直到 55 ,你会得到更好的结果。

    我重新编写了代码,在这里和那里进行了一些调整。如果您愿意,可以使用原始代码。 documentation for OpenCV is quite good ,而且有很好的Python tutorials .

    import numpy as np
    import cv2

    image = cv2.imread("barcode.jpg")
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # equalize lighting
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
    gray = clahe.apply(gray)

    # edge enhancement
    edge_enh = cv2.Laplacian(gray, ddepth = cv2.CV_8U,
    ksize = 3, scale = 1, delta = 0)
    cv2.imshow("Edges", edge_enh)
    cv2.waitKey(0)
    retval = cv2.imwrite("edge_enh.jpg", edge_enh)

    # bilateral blur, which keeps edges
    blurred = cv2.bilateralFilter(edge_enh, 13, 50, 50)

    # use simple thresholding. adaptive thresholding might be more robust
    (_, thresh) = cv2.threshold(blurred, 55, 255, cv2.THRESH_BINARY)
    cv2.imshow("Thresholded", thresh)
    cv2.waitKey(0)
    retval = cv2.imwrite("thresh.jpg", thresh)

    # do some morphology to isolate just the barcode blob
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 9))
    closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
    closed = cv2.erode(closed, None, iterations = 4)
    closed = cv2.dilate(closed, None, iterations = 4)
    cv2.imshow("After morphology", closed)
    cv2.waitKey(0)
    retval = cv2.imwrite("closed.jpg", closed)

    # find contours left in the image
    (_, cnts, _) = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    c = sorted(cnts, key = cv2.contourArea, reverse = True)[0]
    rect = cv2.minAreaRect(c)
    box = np.int0(cv2.boxPoints(rect))
    cv2.drawContours(image, [box], -1, (0, 255, 0), 3)
    print(box)
    cv2.imshow("found barcode", image)
    cv2.waitKey(0)
    retval = cv2.imwrite("found.jpg", image)

    边缘.jpg
    enter image description here

    阈值.jpg
    enter image description here

    关闭.jpg
    enter image description here

    找到.jpg enter image description here

    控制台输出:
    [[596 249]
    [470 213]
    [482 172]
    [608 209]]

    关于python - 如何可靠地检测条码的 4 个角?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50667644/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com