Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用OpenCV和Tesseract的摩洛哥车牌识别(LPR)_Opencv_Ocr_Tesseract_Image Recognition - Fatal编程技术网

使用OpenCV和Tesseract的摩洛哥车牌识别(LPR)

使用OpenCV和Tesseract的摩洛哥车牌识别(LPR),opencv,ocr,tesseract,image-recognition,Opencv,Ocr,Tesseract,Image Recognition,我正在做一个关于识别摩洛哥车牌的项目,该车牌看起来像下图: 摩洛哥车牌 请用OpenCV把车牌号和TSSESACTACT切掉中间的阿拉伯数字和字母。< /P> 我研究了这篇研究论文: 我已经在Windows10中安装了OpenCV和Tesseract for python。当我使用fra语言在车牌的纯文本部分运行tesseract时,我得到了7714315l Bv。我如何分离数据 编辑: 我们在摩洛哥使用的阿拉伯字母是: أ ب ت ج ح د هـ 预期结果为:77143د6 垂直线是不相关的

我正在做一个关于识别摩洛哥车牌的项目,该车牌看起来像下图:

摩洛哥车牌

请用OpenCV把车牌号和TSSESACTACT切掉中间的阿拉伯数字和字母。< /P> 我研究了这篇研究论文:

我已经在Windows10中安装了OpenCV和Tesseract for python。当我使用fra语言在车牌的纯文本部分运行tesseract时,我得到了7714315l Bv。我如何分离数据

编辑: 我们在摩洛哥使用的阿拉伯字母是: أ ب ت ج ح د هـ 预期结果为:77143د6 垂直线是不相关的,我必须使用它们来分开图像和读取数据

提前谢谢

由于两条垂直线不相关,您可以使用以下命令裁剪图像:

import numpy as np
import cv2

image = cv2.imread("lines.jpg")
grayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

dst = cv2.Canny(grayImage, 0, 150)
cv2.imwrite("canny.jpg", dst)

lines = cv2.HoughLinesP(dst, 1, np.pi / 180, 50, None, 60, 20)

lines_x = []
# Get height and width to constrain detected lines
height, width, channels = image.shape
for i in range(0, len(lines)):
    l = lines[i][0]
    # Check if the lines are vertical or not
    angle = np.arctan2(l[3] - l[1], l[2] - l[0]) * 180.0 / np.pi
    if (l[2] > width / 4) and (l[0] > width / 4) and (70 < angle < 100):
        lines_x.append(l[2])
        # To draw the detected lines
        #cv2.line(image, (l[0], l[1]), (l[2], l[3]), (0, 0, 255), 3, cv2.LINE_AA)

#cv2.imwrite("lines_found.jpg", image)
# Sorting to get the line with the maximum x-coordinate for proper cropping
lines_x.sort(reverse=True)
crop_image = "cropped_lines"
for i in range(0, len(lines_x)):
    if i == 0:
        # Cropping to the end
        img = image[0:height, lines_x[i]:width]
    else:
        # Cropping from the start
        img = image[0:height, 0:lines_x[i]]
    cv2.imwrite(crop_image + str(i) + ".jpg", img)
结果:

由于两条垂直线不相关,因此可以使用以下命令裁剪图像:

import numpy as np
import cv2

image = cv2.imread("lines.jpg")
grayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

dst = cv2.Canny(grayImage, 0, 150)
cv2.imwrite("canny.jpg", dst)

lines = cv2.HoughLinesP(dst, 1, np.pi / 180, 50, None, 60, 20)

lines_x = []
# Get height and width to constrain detected lines
height, width, channels = image.shape
for i in range(0, len(lines)):
    l = lines[i][0]
    # Check if the lines are vertical or not
    angle = np.arctan2(l[3] - l[1], l[2] - l[0]) * 180.0 / np.pi
    if (l[2] > width / 4) and (l[0] > width / 4) and (70 < angle < 100):
        lines_x.append(l[2])
        # To draw the detected lines
        #cv2.line(image, (l[0], l[1]), (l[2], l[3]), (0, 0, 255), 3, cv2.LINE_AA)

#cv2.imwrite("lines_found.jpg", image)
# Sorting to get the line with the maximum x-coordinate for proper cropping
lines_x.sort(reverse=True)
crop_image = "cropped_lines"
for i in range(0, len(lines_x)):
    if i == 0:
        # Cropping to the end
        img = image[0:height, lines_x[i]:width]
    else:
        # Cropping from the start
        img = image[0:height, 0:lines_x[i]]
    cv2.imwrite(crop_image + str(i) + ".jpg", img)
结果:


这就是我现在所取得的成就

第二张图像上的检测是使用以下代码进行的:

从第三个图像开始工作的完整代码如下:

import cv2
import numpy as np
import tesserocr as tr
from PIL import Image

image = cv2.imread("cropped.png")

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow('gray', image)

thresh = cv2.adaptiveThreshold(gray, 250, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 255, 1)
cv2.imshow('thresh', thresh)

kernel = np.ones((1, 1), np.uint8)
img_dilation = cv2.dilate(thresh, kernel, iterations=1)

im2, ctrs, hier = cv2.findContours(img_dilation.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

sorted_ctrs = sorted(ctrs, key=lambda ctr: cv2.boundingRect(ctr)[0])

clean_plate = 255 * np.ones_like(img_dilation)

for i, ctr in enumerate(sorted_ctrs):
    x, y, w, h = cv2.boundingRect(ctr)

    roi = img_dilation[y:y + h, x:x + w]

    # these are very specific values made for this image only - it's not a factotum code
    if h > 70 and w > 100:
        rect = cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

        clean_plate[y:y + h, x:x + w] = roi
        cv2.imshow('ROI', rect)

        cv2.imwrite('roi.png', roi)

img = cv2.imread("roi.png")

blur = cv2.medianBlur(img, 1)
cv2.imshow('4 - blur', blur)

pil_img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

api = tr.PyTessBaseAPI()

try:
    api.SetImage(pil_img)
    boxes = api.GetComponentImages(tr.RIL.TEXTLINE, True)
    text = api.GetUTF8Text()

finally:
    api.End()

# clean the string a bit
text = str(text).strip()

plate = ""

# 77143-1916 ---> NNNNN|symbol|N
for char in text:
    firstSection = text[:5]

    # the arabic symbol is easy because it's nearly impossible for the OCR to misunderstood the last 2 digit
    # so we have that the symbol is always the third char from the end (right to left)
    symbol = text[-3]

    lastChar = text[-1]

    plate = firstSection + "[" + symbol + "]" + lastChar

print(plate)
cv2.waitKey(0)
对于阿拉伯语符号,您应该从TesseractOCR安装其他语言,并可能使用版本4

输出:77143[9]6

括号之间的数字是未检测到的阿拉伯符号


希望我能帮助你。

这就是我现在所取得的成就

第二张图像上的检测是使用以下代码进行的:

从第三个图像开始工作的完整代码如下:

import cv2
import numpy as np
import tesserocr as tr
from PIL import Image

image = cv2.imread("cropped.png")

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow('gray', image)

thresh = cv2.adaptiveThreshold(gray, 250, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 255, 1)
cv2.imshow('thresh', thresh)

kernel = np.ones((1, 1), np.uint8)
img_dilation = cv2.dilate(thresh, kernel, iterations=1)

im2, ctrs, hier = cv2.findContours(img_dilation.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

sorted_ctrs = sorted(ctrs, key=lambda ctr: cv2.boundingRect(ctr)[0])

clean_plate = 255 * np.ones_like(img_dilation)

for i, ctr in enumerate(sorted_ctrs):
    x, y, w, h = cv2.boundingRect(ctr)

    roi = img_dilation[y:y + h, x:x + w]

    # these are very specific values made for this image only - it's not a factotum code
    if h > 70 and w > 100:
        rect = cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

        clean_plate[y:y + h, x:x + w] = roi
        cv2.imshow('ROI', rect)

        cv2.imwrite('roi.png', roi)

img = cv2.imread("roi.png")

blur = cv2.medianBlur(img, 1)
cv2.imshow('4 - blur', blur)

pil_img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

api = tr.PyTessBaseAPI()

try:
    api.SetImage(pil_img)
    boxes = api.GetComponentImages(tr.RIL.TEXTLINE, True)
    text = api.GetUTF8Text()

finally:
    api.End()

# clean the string a bit
text = str(text).strip()

plate = ""

# 77143-1916 ---> NNNNN|symbol|N
for char in text:
    firstSection = text[:5]

    # the arabic symbol is easy because it's nearly impossible for the OCR to misunderstood the last 2 digit
    # so we have that the symbol is always the third char from the end (right to left)
    symbol = text[-3]

    lastChar = text[-1]

    plate = firstSection + "[" + symbol + "]" + lastChar

print(plate)
cv2.waitKey(0)
对于阿拉伯语符号,您应该从TesseractOCR安装其他语言,并可能使用版本4

输出:77143[9]6

括号之间的数字是未检测到的阿拉伯符号



希望我能帮助你。

期望的结果是什么?我想用TEXSACT中的ARA语言把数字分开,中间的字母分开。如何使用OpenCV来分离数据?据我所知,中间的两条垂直直线段是不相关的?是的,我需要删除它们,但是在我必须使用它们来分离/获得3个图像CV2对象之前。然后用TestSerAct读取/OCR。期望的结果是什么?我想用TESSACT中的ARA语言分开读取数字和中间的字母。如何使用OpenCV来分离数据?据我所知,中间的两条垂直直线段是不相关的?是的,我需要删除它们,但是在我必须使用它们来分离/获得3个图像CV2对象之前。然后用tesseract阅读/ocr。非常感谢!我是OpenCV新手,请指导我如何裁剪中间部分,这是阿拉伯语的部分,但我不知道如何操作。您可以从第二幅图像的x坐标裁剪到第一幅图像的x坐标,x坐标在x线上,第一幅图像的位置是0,第二幅图像的位置是1,即中间部分=图像[0:height,lines_x[1]:lines_x[0]它可以工作!现在唯一剩下的就是将此代码添加到我拥有的OpenCV车牌检测部分并应用tesseract。我使用了此代码:还添加了一个]你的代码。当我在一张较小的图片中应用你的代码时,它不起作用…行是空的..你能在评论中添加图像链接吗?我能想出一个更可靠的方法谢谢你!我是OpenCV新手,请指导我如何裁剪中间部分,它是阿拉伯语的,但我不知道如何做。你可以从x裁剪部分第二个图像的坐标到第一个图像的x坐标,x坐标在线_x中,i是第一个图像的位置0,1是第二个图像的位置,即中间部分=图像[0:高度,线_x[1]:线_x[0]它工作了!现在唯一剩下的就是将此代码添加到我拥有的OpenCV车牌检测部分并应用tesseract。我使用了此代码:还添加了一个]当我在一张较小的图片中应用你的代码时,它不起作用…行是空的..你能在评论中添加一个指向图像的链接吗?我能想出一个更可靠的方法非常感谢你的回答,非常感谢你的帮助!我使用的是Pyteseract最新版本0.2.6,它无法读取车牌上的字母د。。。我如何解决这个问题?好吧,看看,下载必要的tessdata语言并在代码中设置正确的标志。当然,我已经有了tessdata/ara.traineddata,并且代码打印为pytesseract.image\u to\u stringImage。打开'lines.jpg',lang ara'返回错误的答案…调用@Kinght金 - 他是OpenCv的高手。非常感谢您的回答,非常感谢您的帮助!我使用的是PyteSeract最新版本0.2.6,它无法读取车牌上的字母د……我如何解决这个问题?好吧,看看,下载必要的tessdata语言,并在代码中设置正确的标志。当然,我已经有了tessdata/a培里达
代码printpyteseract.image\u to\u stringImage.open'lines.jpg',lang='ara'返回错误答案…Invoke@Kinght金 - 他是OpenCv的高手。