当前位置: 首页 > 知识库问答 >
问题:

从周围的边界框中提取车牌平行四边形?

钮善
2023-03-14

因此,我训练了一个对象识别神经网络(YOLOv3)来检测以各种倾斜和直线角度拍摄的汽车图片牌照周围的边界框,该网络非常可靠。然而,现在我想利用图像处理从包围它的边界框中提取车牌平行四边形,而无需训练另一个神经网络。示例图像:

我曾尝试使用OpenCV内置函数执行边缘和轮廓检测,如下面的最小代码所示,但仅以这种方式在一小部分图像上成功:

import cv2
import matplotlib.pyplot as plt
import numpy as np

def auto_canny(image, sigma=0.25):
    # compute the median of the single channel pixel intensities
    v = np.median(image)

    # apply automatic Canny edge detection using the computed median
    lower = int(max(0, (1.0 - sigma) * v))
    upper = int(min(255, (1.0 + sigma) * v))
    edged = cv2.Canny(image, lower, upper)

    # return the edged image
    return edged


# Load the image
orig_img = cv2.imread(input_file)

img = orig_img.copy()

dim1,dim2, _ = img.shape

# Calculate the width and height of the image
img_y = len(img)
img_x = len(img[0])

#Split out each channel
blue, green, red = cv2.split(img)
mn, mx = 220, 350
# Run canny edge detection on each channel

blue_edges = auto_canny(blue)

green_edges = auto_canny(green)

red_edges = auto_canny(red)

# Join edges back into image
edges = blue_edges | green_edges | red_edges

contours, hierarchy = cv2.findContours(edges.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

cnts=sorted(contours, key = cv2.contourArea, reverse = True)[:20]
hulls = [cv2.convexHull(cnt) for cnt in cnts]
perims = [cv2.arcLength(hull, True) for hull in hulls]
approxes = [cv2.approxPolyDP(hulls[i], 0.02 * perims[i], True) for i in range(len(hulls))]

approx_cnts = sorted(approxes, key = cv2.contourArea, reverse = True)
lengths = [len(cnt) for cnt in approx_cnts]

approx = approx_cnts[lengths.index(4)]

#check the ratio of the detected plate area to the bounding box
if (cv2.contourArea(approx)/(img.shape[0]*img.shape[1]) > .2):
    cv2.drawContours(img, [approx], -1, (0,255,0), 1)

plt.imshow(img);plt.show()

以下是一些结果示例:

(最上面一行图像是边缘检测阶段的结果)

成功者:

失败:

有点成功:

如果未找到四边形/平行四边形,但绘制了面积最大的多边形:

所有这些结果都具有完全相同的参数集(阈值等)

我还尝试使用cv2应用Hough变换。HoughLines,但我不知道为什么无论我设置的累加器阈值有多低,垂直倾斜的线总是会丢失。而且,当我降低阈值时,我不知从哪里得到了这些对角线:

我用来画霍夫线的代码是:

lines = cv2.HoughLines(edges,1,np.pi/180,20)
for i in range(len(lines)):
    for rho,theta in lines[i]:
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a*rho
        y0 = b*rho
        x1 = int(x0 + 1000*(-b))
        y1 = int(y0 + 1000*(a))
        x2 = int(x0 - 1000*(-b))
        y2 = int(y0 - 1000*(a))

        cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2)
plt.imshow(img);plt.show()

仅仅使用图像处理技术来获得高成功率真的这么难吗?当然,机器学习可以像小菜一碟一样解决这个问题,但我认为这是一种过度的杀戮,而且我没有注释html" target="_blank">数据。

共有2个答案

佟阳焱
2023-03-14

我会做一个白色通过阈值过滤器,然后是一个斑点(忽略所有接触边缘的斑点)来获得你的车牌批量位置。在你发布的所有照片中,车牌都没有接触图像边缘,并且至少有一个像素的轮廓。为了得到角落,我会做以下操作:

取水滴中的任意一点,并找出距离该点最远的点。结果应该是一个拐点。然后取得到的角点,找到离那个角点最远的点。这应该给你两个相反的角落。然后找到与这两个点的合并距离最大的水滴点。在离所有三点最远的地方重复最后一次。现在你有四个角了。要对它们进行排序,请获取中点并创建每个角的向量。顺时针绕一圈。

如果您仍然需要这个解决方案,或者需要更好的描述,请告诉我,我可以在您的imgur集合上编写和测试代码。基于你的样本图片,我对这个策略有很高的信心。

何安宜
2023-03-14

你可以使用滤色器来检测所需的区域<似乎车牌的边界通常用白色标记。您可以检测图像中的白色像素,并在最外层位置之间绘制线。

算法看起来像:

  1. 指定要检测的RGB值

PyImagesearch中的这个颜色检测示例可能会帮助您编写代码

当然,检测白色车牌对白色汽车不起作用。

要考虑白色汽车,您可以检查您提供的边界框图像的边框是否检测到任何白色。如果是,请尝试在最外层的蓝色、红色或黑色像素之间画线(因为车牌字母有这种颜色)。

 类似资料:
  • 问题内容: 有没有办法像下面的图片一样在文本周围集成边框? 问题答案: 使用多个文本阴影: 另外,您可以使用仅在webkit中起作用的文本笔划:

  • 问题内容: 我正在使用和在CSS中创建一个半透明的圆圈。 在这个圆的周围,我希望有另一个完全透明的边界(例如10个像素),而又想有另一个半透明的边界(10个像素)。 这是我创建圈子的方式: 我需要怎么做才能在现有边界周围创建另一个边界,然后再创建另一个边界? 问题答案: 您可以使用简单的边框并将背景裁剪到,以在填充区域中创建透明部分: 您也可以考虑 您可以轻松缩放到任意数量的边界:

  • 尝试在SVG文本周围设置边框,但我得到的结果不一样。 HTML:(使用mute类) CSS:

  • 问题内容: 我有一幅包含多个边界框的图像。 我需要提取其中包含边界框的所有内容。到目前为止,从这个站点我已经得到了这个答案: 它有效,但是只有一个。我应该如何修改代码?我尝试将其放在轮廓循环中,但它仍会喷出一个图像而不是多个图像。 提前非常感谢您。 问题答案: 你去那里:

  • 问题内容: 我在我的应用程序中使用JTabbedPane。我添加了两个选项卡,它们是自定义类“ ContentPanel”的实例。这扩展了JPanel并设置了背景,边框等。基本上,这意味着我不必设置要应用此颜色方案的每个JPanel的属性。我注意到,不仅它们的边框出现了,而且另一个边框(我认为是蓝色的- 至少在我的屏幕上)出现在此边框周围,并与“选择器”标签本身相连(即,您单击以获得按钮的按钮)适

  • 问题内容: 似乎Chrome / Firefox无法在其上显示边框,但是如果选择器为,则可以渲染边框。 如何在tr上设置边框? 我的尝试不起作用: http://jsfiddle.net/edi9999/VzPN2/ 这是一个类似的问题:将边框设置为表tr,除IE 6和7外,其他所有功能都可以使用 ,但除IE之外,其他任何地方都可以使用。 问题答案: 将此添加到样式表: 在规范中实际上很好地描述了