【python ++ opencv + pytorch 】车牌提取、分割、识别

6 篇文章 4 订阅
订阅专栏

话不多说,先看最后成果图(如果想要全部工程,文章最后我会把github链接放上):
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

可以看到最终的识别车牌号码是:苏G99999。

其实前年冬天偶然想着用c++来做一个小项目,然后就用 c++ opencv 实现了车牌的提取和分割,然后找了一些博客自己跟着做,然后做出来了,但是效果并不是很好,用 c++ 的方法大概只能做到车牌提取和字符分割,但是最后的一步,切割出来的字符的识别,看了很多大佬的说法,都说用 CNN 来做效果最好,所以那个时候也就做到了分割,最后一步识别做不下去了。在这里插入图片描述
在这里插入图片描述
上面就是用 c++ 跑出来的效果和当时这个小项目的日志,只做到车牌提取、分割。

然后去年的时候去学习了深度学习,用的框架的是 pytorch ,训练了很多 CNN 的模型,然后就想着,把之前没做完的车牌识别用 python + opencv + pytorch 搭建一个 CNN 模型来解决这个问题,目前这个模型我用自己收集的数据去跑,准确率在 90% 左右,然后用自己生成的车牌字符去跑一下,准确率还算可以。(如果需要训练的车牌字符数据集,可以帮忙点个赞,给我发个邮件)
我的思路分三步:
1、将车牌从图片里面抠出来
2、将车牌一个个字符分割开
3、将车牌 resize 成相应的尺寸
4、用 CNN 训练出车牌字符分类模型
5、用训练出来的模型去跑我们提取出的车牌字符得到车牌号
第一步:抠出车牌
这里主要是用到 opencv 里面的膨胀和腐蚀的一系列操作将车牌的矩形提取出来,然后根据提取出来的矩形来提取车牌。
第二步:将抠出来的车牌分割成一个一个字符
这里先将车牌二值化之后,然后根据每个像素点在x轴上的投影来分割字符。(第一二步我写的方法效果还算可以,但是我感觉应该可以再优化一下,应为提取出的字符的图片噪声越小,CNN 的识别率越高,所以此处可不必参照我的方法来做,最主要是…这段代码写的太烂了,我自己都不堪回首)

def readjpg():

    img = cv2.imread(plate_path)
    # cv2.imshow('test', img)

    n = 1
    img_width = img.shape[0]
    img_height = img.shape[1]

    img_resize_width = round(n*img_width)
    img_resize_height = round(n*img_height)

    print(f'width:{img_width}, height:{img_height}')
    print(f'round_width:{img_resize_width}, rpund_height:{img_resize_height}')

    new_img_1 = cv2.resize(img, (img_resize_height, img_resize_width))
    # cv2.imshow('img2', new_img_1)
    # cv2.imshow('img', img)

    # 将输入的图像从一种颜色格式转化为另一种颜色格式(OpenCV中的默认颜色格式通常称为RGB,但实际上是BGR(字节是相反的)
    mark = cv2.cvtColor(new_img_1, cv2.COLOR_BGR2GRAY)
    # cv2.imshow('mark', mark)

    # 先做高斯模糊
    mark = cv2.GaussianBlur(mark, (3, 3), 3, 0)
    # cv2.imshow('guss', mark)

    # 边缘检测
    mark = cv2.Canny(mark, 300, 200, 3)
    # cv2.imshow('candy', mark)

    # 腐蚀和膨胀
    kernel_X = cv2.getStructuringElement(cv2.MORPH_RECT, (20, 1))           # 定义矩形卷积核
    mark = cv2.dilate(mark, kernel_X, (-1, -1),iterations=2)                # 膨胀操作
    mark = cv2.erode(mark, kernel_X, (-1, -1), iterations=4)                # 腐蚀操作

    kernel_Y = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 15))           # 定义矩形卷积核
    mark = cv2.dilate(mark, kernel_X, (-1, -1), iterations=2)               # 膨胀操作
    mark = cv2.erode(mark, kernel_Y, (-1, -1), iterations=1)                # 腐蚀操作

    mark = cv2.dilate(mark, kernel_Y, (-1, -1), iterations=2)
    mark = cv2.medianBlur(mark, 15)
    mark = cv2.medianBlur(mark, 15)

    # cv2.imshow('erode', mark)

    conyours, h = cv2.findContours(mark, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # print(len(conyours))
    find_palat_flag = False
    for index in range(len(conyours)):
        area = cv2.contourArea(conyours[index])
        print(area)
        if area > MIN_PALAT_AREA:
            rect = cv2.boundingRect(conyours[index])
            # print(rect)
            print(rect[0], rect[1], rect[2], rect[3])
            wid_div_height = rect[2]/rect[3]
            print(f'wid_div_height:{wid_div_height}')
            if wid_div_height > 3 and wid_div_height< 8:
                find_palat_flag = True
                print(rect)
                img_x = int(rect[0])
                img_y = int(rect[1])
                img_width = int(rect[2])
                img_height = int(rect[3])
                print(f'x:{img_x}, y:{img_y}, width:{img_width}, height:{img_height}')

                # imgx[110:130,50:70,2]表示一个范围:[高度起始点:高度结束点,宽度起始点:宽度结束点,哪个通道],起始点均以左上角
                plate_img = new_img_1[img_y:img_y + img_height, img_x-10:img_x + img_width]    # 分割出识别到的车牌的块 宽度两边加10
                # plate_img = cv2.cvtColor(plate_img, cv2.COLOR_BGR2HSV)
                plate_img = cv2.cvtColor(plate_img, cv2.COLOR_BGR2GRAY) # 转化为灰度图
                # plate_img = cv2.Canny(plate_img, 450, 120, 3)           # 边缘检测
                # 进行闭运算
                # kernel = np.ones((3, 3), np.uint8)
                # plate_img = cv2.morphologyEx(plate_img, cv2.MORPH_CLOSE, kernel)
                # cv2.imshow('palat2', plate_img)
                _, plate_img = cv2.threshold(plate_img, 140, 255, cv2.THRESH_BINARY)    # 二值化

                # 腐蚀和膨胀
                kernel_X = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))  # 定义矩形卷积核
                plate_img = cv2.dilate(plate_img, kernel_X, (-1, -1), iterations=1)  # 膨胀操作
                plate_img = cv2.erode(plate_img, kernel_X, (-1, -1), iterations=1)  # 腐蚀操作

                cv2.imshow('palat3', plate_img) # 打印出被抠出来的车牌
                cv2.imwrite('palat.jpg', plate_img)

                # 分割车牌
                # 竖直方向上的投影
                plate_width = img_width + 10
                plate_height = img_height

                pix_list = []
                for i in range(plate_width):
                    num_pix = 0
                    for j in range(plate_height):
                        if plate_img[j][i] > 0:
                            num_pix += 1
                        # print(f'plate_img[{j}][{i}]:{plate_img[j][i]}')

                    num_pix = num_pix - 2
                    if num_pix <= 0:
                        num_pix = 0
                    print(f'num_pix:{num_pix}')

                    pix_list.append(num_pix)

                next_pix_len = 0
                index_start_list = []
                index_end_list = []
                flag_1 = True
                sum_len = 0
                sum_len_list = []
                print(f'pix_list_len:{len(pix_list)}')
                for i in range(len(pix_list)):
                    if pix_list[i] > 0:
                        sum_len += pix_list[i]
                        next_pix_len += 1
                        if flag_1:
                            index_start = i
                            index_start_list.append(index_start)
                            flag_1 = False
                    else:
                        if next_pix_len >=3:
                            sum_len_list.append(sum_len)
                            # print(f'sum_len = {sum_len}')
                            sum_len = 0
                            print(f'i:{i} next_pix_len:{next_pix_len}')
                            flag_1 = True
                            index_end_list.append(next_pix_len + index_start)
                        next_pix_len = 0
                    # print(f'index_start = {index_start}')
                # print(index_start_list)
                print(index_end_list)
                print(sum_len_list)
                sum_sort = []
                for index_o in range(len(sum_len_list)):
                    sum_sort.append(sum_len_list[index_o])
                print(f'sum_sort:[{sum_sort}]')

                # print(sorted(sum_len_list))
                print(f'len(index_end_list) = {len(index_end_list)}')
                sum_len_list_sort = sorted(sum_len_list)
                print(f'sum_len_list_sort:[{sum_len_list_sort}]')
                print(f'sum_sort:[{sum_sort}]')
                if len(sum_len_list_sort) > 7:
                    for index_m in range(0, len(sum_len_list_sort) - 7):
                        for index_p in range(len(sum_sort)):
                            if sum_sort[index_p] == sum_len_list_sort[index_m]:
                                print(f'{sum_sort[index_p]}=={sum_len_list_sort[index_m]}')
                                print(f'idx = {index_p}')
                                # print(f'index_start_list[index_p]={index_start_list[index_p]}')
                                del index_start_list[index_p]
                                del index_end_list[index_p]
                for index_i in range(len(index_end_list)):
                    print(f'[{index_start_list[index_i]}~{index_end_list[index_i]}]')
                    # cv2.imwrite(f'{index_i}.jpg', plate_img[0:plate_height, index_start_list[index_i]:index_end_list[index_i]+2])
                    singnum_img = plate_img[0:plate_height, index_start_list[index_i]:index_end_list[index_i]+2]
                    singnum_img_width = singnum_img.shape[1]
                    singnum_img_height = singnum_img.shape[0]
                    # print(f'singnum_img width:{singnum_img_width} singnum_img height:{singnum_img_height}')
                    y_top = 0
                    y_down = 0
                    y_pix_up_flag = True
                    y_pix_down_flag = True
                    for index_num_img_y in range(singnum_img_height):
                        for index_num_img_x in range(singnum_img_width):
                            if singnum_img[index_num_img_y][index_num_img_x] > 0:
                                y_pix_down_flag = False
                                if y_pix_up_flag:
                                    y_top = index_num_img_y
                                    y_pix_up_flag = False
                            else:
                                if not y_pix_down_flag:
                                    y_down = index_num_img_y
                                    y_pix_down_flag = True
                    print(f'y_top:{y_top}  y_down:{y_down}')
                    singnum_img = singnum_img[y_top:y_down+1, 0:singnum_img_width]
                    singnum_img_width = singnum_img.shape[1]
                    singnum_img_height = singnum_img.shape[0]
                    print(f'singnum_img width:{singnum_img_width} singnum_img height:{singnum_img_height}')
                    cv2.imwrite(f'{root_path}\\single_num\\{index_i}.jpg',singnum_img)

                # (img_x, img_y) 为左上角点坐标 (img_x+img_width, img_height+img_y) 为右下角点坐标,两个对角点确定一个矩形
                # cv2.rectangle(new_img_1, (img_x, img_y), (img_x+img_width, img_height+img_y),  (0, 0, 255), 2)
                cv2.rectangle(new_img_1, rect, (0, 0, 255), 2)                              # 将识别到的车牌在图像中框出来
                cv2.imshow('palat', new_img_1)

    if not find_palat_flag:
        print("Can't find palat!!!!")

    cv2.waitKey(0)
    return 0

这个接口是将第一步抠车牌和第二步车牌分割都封装了,写的比较烂…
在这里插入图片描述
在这里插入图片描述

第三步:将车牌 resize 成相应的尺寸
这里主要是为了后面将图片放到训练出的模型里面跑,将所有图片统一 size ,具体为将图片填充成 长:宽=4:5 的 size 然后 resize 成 32x40 ,这样可以保证提取出来的图片不会 resize 的时候拉伸变形。

def resize_image(image, height = IMAGE_HEIGHT, width = IMAGE_WIDTH):
    top, botton, left, right = 0, 0, 0, 0

    h, w, c = image.shape

    loggest_edge = max(h, w)

    # 计算短边需要多少增加多少宽度使之长宽相等
    if h < loggest_edge:
        dh = loggest_edge - h
        top = dh // 2
        botton = dh - top
    elif w < loggest_edge:
        dw = IMG_WIDTH - w
        left = dw // 2
        right = dw - left
    else:
        pass

    BLACK = [0, 0, 0]
    # 将图像转换为一个正方形的image,两边或者上下缺少的的用黑色矩形填充
    constant = cv2.copyMakeBorder(image, top, botton, left, right, cv2.BORDER_CONSTANT, value=BLACK)

    return cv2.resize(constant, (height, width))

def readpath(path_name):
    for dir_item in os.listdir(path_name):
        full_path = os.path.abspath(os.path.join(path_name, dir_item))  # 组合照片和路径的名字
        if os.path.isdir(full_path):    # 如果是文件夹,递归调用
            readpath(full_path)
        else:
            if dir_item.endswith('.jpg'):
                image = cv2.imread(full_path)
                image = resize_image(image, IMAGE_WIDTH, IMAGE_HEIGHT)

                images.append(image)
                # print('full_path:', full_path)
                # print('dir_item:', dir_item)
                labels.append(dir_item)
    return images, labels

def load_dataset(path_name):
    images, labels = readpath(path_name)

    resizedata_path = RESIZE_IMG_PATH
    # resizedata_path = 'D:\\DeapLearn Project\\Face_Recognition\\moreface\\7219face\\test\\resizeface\\'
    for i in range(len(images)):
        if not os.path.exists(resizedata_path):
            os.mkdir(resizedata_path)
        img_name = '%s//%s' % (resizedata_path, labels[i])
        cv2.imwrite(img_name, images[i])

在这里插入图片描述

第四步:用 CNN 训练出车牌字符分类模型
我找了一个车牌字符的数据集,总共有 0-9 的数字 还有 A-Z 除去‘I’和’‘O’的 24 个大写英文字母 还有 6个省的缩写:在这里插入图片描述在这里插入图片描述
每个分类的文件夹内有若干张二值化的字符图片,然后根据这个数据集来训练出模型。

# 数据集类
class MyDataSet(Dataset):
    def __init__(self, data_path:str, transform=None):  # 传入训练样本路径
        super(MyDataSet, self).__init__()
        self.data_path = data_path
        if transform is None:
            self.transform = transforms.Compose(
                [
                    transforms.Resize(size=(32, 40)), # 原本就是 32x40 不需要修改尺寸
                    transforms.ToTensor(),
                    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),
                    # transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
                ]
            )
        else:
            self.transform = transform
        self.path_list = os.listdir(data_path)

    def __getitem__(self, idx:int):
        img_path = self.path_list[idx]
        label = int(img_path.split('.')[1])
        label = torch.as_tensor(label, dtype=torch.int64)
        img_path = os.path.join(self.data_path, img_path)
        img = Image.open(img_path)
        img = self.transform(img)
        return img, label

    def __len__(self)->int:
        return len(self.path_list)


train_ds = MyDataSet(train_path)
test_data = MyDataSet(test_path)
# for i, item in enumerate(tqdm(train_ds)):
#     print(item)
#     break

# 数据加载
new_train_loader = DataLoader(train_ds, batch_size=32, shuffle=True, pin_memory=True, num_workers=0)
new_test_loader = DataLoader(test_data, batch_size=32, shuffle=False, pin_memory=True, num_workers=0)

# for i, item in enumerate(new_train_loader):
#     print(item[0].shape)
#     break
#
# img_PIL_Tensor = train_ds[1][0]
# new_img_PIL = transforms.ToPILImage()(img_PIL_Tensor).convert('RGB')
# plt.imshow(new_img_PIL)
# plt.show()


# 设置训练类
class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = torch.nn.Conv2d(3, 64, kernel_size=3, padding=1)
        self.conv2 = torch.nn.Conv2d(64, 64, kernel_size=3, padding=1)
        self.conv3 = torch.nn.Conv2d(64, 128, kernel_size=3, padding=1)
        self.conv4 = torch.nn.Conv2d(128, 128, kernel_size=3, padding=1)
        self.conv5 = torch.nn.Conv2d(128, 256, kernel_size=3, padding=1)
        self.conv6 = torch.nn.Conv2d(256, 256, kernel_size=3, padding=1)
        self.maxpooling = torch.nn.MaxPool2d(2)
        self.avgpool = torch.nn.AvgPool2d(2)
        self.globalavgpool = torch.nn.AvgPool2d((8, 10))
        self.bn1 = torch.nn.BatchNorm2d(64)
        self.bn2 = torch.nn.BatchNorm2d(128)
        self.bn3 = torch.nn.BatchNorm2d(256)
        self.dropout50 = torch.nn.Dropout(0.5)
        self.dropout10 = torch.nn.Dropout(0.1)

        self.fc1 = torch.nn.Linear(256, 40)

    def forward(self, x):
        batch_size = x.size(0)
        x = self.bn1(F.relu(self.conv1(x)))
        x = self.bn1(F.relu(self.conv2(x)))
        x = self.maxpooling(x)
        x = self.dropout10(x)
        x = self.bn2(F.relu(self.conv3(x)))
        x = self.bn2(F.relu(self.conv4(x)))
        x = self.maxpooling(x)
        x = self.dropout10(x)
        x = self.bn3(F.relu(self.conv5(x)))
        x = self.bn3(F.relu(self.conv6(x)))
        x = self.globalavgpool(x)
        x = self.dropout50(x)

        x = x.view(batch_size, -1)

        x = self.fc1(x)
        return x

在这里插入图片描述

第五步:用训练出来的模型去跑我们提取出的车牌字符得到车牌号
这里直接加载上一步训练出的模型,然后将我们 resize 好车牌字符图片导入模型就能得到预测的车牌号。

def test():
    correct = 0
    total = 0
    with torch.no_grad():
        for _, data in enumerate(new_test_loader, 0):
            inputs, _ = data[0], data[1]
            inputs = inputs.to(device)
            outputs = model(inputs)
            # print(outputs.shape)
            _, prediction = torch.max(outputs.data, dim=1)
            print('-'*40)
            # print(target)
            # print(prediction)
            print(f'Predicted license plate number:'
                  f'{SINGLE_CHAR_LIST[prediction[0]]}'
                  f'{SINGLE_CHAR_LIST[prediction[1]]}'
                  f'{SINGLE_CHAR_LIST[prediction[2]]}'
                  f'{SINGLE_CHAR_LIST[prediction[3]]}'
                  f'{SINGLE_CHAR_LIST[prediction[4]]}'
                  f'{SINGLE_CHAR_LIST[prediction[5]]}'
                  f'{SINGLE_CHAR_LIST[prediction[6]]}')

在这里插入图片描述

可以看到预测的车牌号为:苏G99999
和我们输入的图片上车牌号一致。
以上就是整个车牌识别的过程,这里我只贴出了一些关键步骤的代码,如需要整个工程,可去GitHub取。
参考文章:
行歌er 大佬的c++实现车牌识别
B站刘老师的《PyTorch深度学习实践》课程

工程GitHub: Github链接(帮忙点个星,谢谢了)
想要数据集给我发个邮件1009088103@qq.com

基于Python车牌识别系统实现
商务合作 / 项目定制 / 学习交流。个人vx:lovely_wml
10-16 4万+
本文将以基于Python车牌识别系统实现为方向,介绍车牌识别技术的基本原理、常用算法和方法,并详细讲解如何利用Python语言实现一个完整的车牌识别系统。
Python+OpenCV实现车牌字符分割识别
09-20
主要为大家详细介绍了Python+OpenCV实现车牌字符分割识别,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
基于深度学习车牌检测识别(Pytorch)(ResNet +Transformer)
最新发布
小白学视觉
08-27 135
点击上方“小白学视觉”,选择加"星标"或“置顶”重磅干货,第一时间送达车牌识别概述基于深度学习车牌识别,其中,车辆检测网络直接使用YOLO侦测。而后,才是使用网络侦测车牌识别车牌号。车牌的侦测网络,采用的是resnet18,网络输出检测边框的仿射变换矩阵,可检测任意形状的四边形。车牌号序列模型,采用Resnet18+transformer模型,直接输出车牌号序列。数据集上,车牌检测使用CCPD...
车牌字符分割
04-19
本代码使用python3.6实现车牌字符分割,涉及到中值滤波,边缘检测,二值化,车牌定位,垂直投影,倾斜矫正,字符分割,绝对能实现功能。10积分很值得。内带测试图片。适合想学习车牌识别的朋友。
车牌分割python_Python实现车牌定位及分割
weixin_39785400的博客
12-11 826
具体步骤1、将采集到的彩色车牌图像转换成灰度图2、灰度化的图像利用高斯平滑处理后,再对其进行中直滤波3、使用Sobel算子对图像进行边缘检测4、对二值化的图像进行腐蚀,膨胀,开运算,闭运算的形态学组合变换5、对形态学变换后的图像进行轮廓查找,根据车牌的长宽比提取车牌代码实现图像灰度化gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)高斯平滑,中值滤波处理gau...
Pytorch实现车牌识别
weixin_64179839的博客
05-24 288
掌握了数据预处理、数据集划分、模型设计与训练、损失函数和优化器选择、训练过程监控以及模型评估的重要性。使用Batch Normalization提高了训练稳定性。未来可通过数据增强、模型优化、超参数调优和错误分析进一步提升模型性能。
第P10周:PyTorch实现车牌识别
zoey123456789的博客
07-06 6077
在之前的案例中,我们多是使用函数直接导入已经分类好的数据集形成Dataset,然后使用DataLoader加载Dataset,但是如果对无法分类的数据集,我们如何导入,并进行识别呢?本周内容将自定义一个MyDataset加载车牌数据集并完成识别⛽ 我的环境。
基于 PyTorchOpenCV 的入门级车牌识别项目+毕业设计+课程设计
06-13
# 基于 PyTorchOpenCV 的入门级车牌识别项目 任务是处理车牌号码识别。 使用 OpenCV 中的传统图像方法对输入图像进行预处理,然后将车牌过滤和字符识别交给神经网络处理。 用到的两个神经网络都是由我自己使用...
基于Python+OpenCV车牌识别系统.zip
04-05
如图像处理(滤波、形态学操作、色彩空间转换等)、特征检测与描述(如SIFT、SURF、ORB等)、物体识别与检测(如Haar级联分类器、HOG、DNN等)、视频分析、相机校正、立体视觉、机器学习(SVM、KNN、决策树等)、...
OpenCV+Python车牌字符分割识别入门 (含新能源车牌识别
热门推荐
Alexantao 的专栏
10-09 1万+
车牌识别三大步骤: 1、从图中找出车牌 2、从车牌识别车牌号 3、通过训练提高识别率 本次仅实现第二步,这也是核心,其他两个属于附属功能,第三个可以通过GAN或Tesseract来进行训练,这个下篇再进行介绍。 核心步骤: 图片处理:1、将图片灰度化;2、将灰度图片二值化;3、校正;4、去燥; 图像切割识别:1、图像切割;2、图像识别 代...
车牌分割源代码 可以运行 直接出效果
03-03
车牌分割源代码,可以运行 直接出效果 P0802:粘连字符切分 P0803:文字识别 P0804:彩色车牌分割
车牌数据集 100000张已经切割好的车牌数据集
05-25
车牌数据集 100000张已经切割好的车牌数据集 车牌数据集 100000张已经切割好的车牌数据集 车牌数据集 100000张已经切割好的车牌数据集 车牌数据集 100000张已经切割好的车牌数据集 车牌数据集 100000张已经切割好的车牌数据集 车牌数据集 100000张已经切割好的车牌数据集 车牌数据集 100000张已经切割好的车牌数据集
opencv python车牌定位字符分割
04-19
opencv python车牌定位,字符分割.
基于PyTorchOpenCV 的入门级车牌识别项目源码+模型.zip
04-28
基于PyTorchOpenCV 的入门级车牌识别项目源码+模型.zip大二的图像处理课程的第三次大作业。任务是处理车牌号码识别。为了完成该作业,我参考了网上诸多资料,最终选择了如今的解决方案。即使用 OpenCV 中的传统...
课程设计——基于 PyTorchOpenCV车牌识别系统设计与实现(包含源码、训练数据集)
白话机器学习
07-07 1028
完整项目获取1、资源项目源码均已通过严格测试验证,保证能够正常运行;2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通;3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
Python正则表达式提取车牌
m0_72958694的博客
08-22 489
本文简要介绍了在Python中使用正则表达式(Regular Expressions)来提取车牌号是一个常见的任务,尤其是在处理车辆信息或进行图像识别后的文本处理时。中国的车牌号格式多种多样,但通常包含省份简称、英文字母和数字。
探索智能车牌识别:License_Plate_Detection_Pytorch
gitblog_00003的博客
04-14 463
探索智能车牌识别:License_Plate_Detection_Pytorch License_Plate_Detection_Pytorch 项目地址: https://gitcode.com/gh_mirrors/li/License_Plate_Dete...
Python车牌特征提取(朴素线性特征)
阴无月的博客
03-22 328
Python模式识别特征提取 文章目录Python模式识别特征提取1.图像灰度化2.图像切割3.特征提取3.1 按照阈值二值化图片3.2 构造特征值向量4.计算欧氏距离Q&AQ:向量一定要分割成3*3的嘛,5*5的可以嘛?Q:提取到的特征值应该怎么保存呢?保存之后如何更新呢?Q:你觉得这样提取特征的办法有什么缺陷呢?你能想到更好的特征值用来 **感知** 数字0,1,2,3,4...8,9字符的形状嘛?   1.图像灰度化 import cv2 img = cv2.imread("a.jpg") #
opencv 车牌识别代码 python
10-26
引用提供了一份基于OpenCV车牌号码识别Python代码,可以对输入图片进行识别,最终返回一张打印识别结果的图片。该代码使用了形态学处理和SVM算法进行车牌字符识别。需要注意的是,该方法存在一定的局限性,例如对于灰度图或者图片颜色不明显的情况,无法通过检测蓝色来识别车牌位置。同时,如果图片质量很低,例如很模糊,则需要经过更多的预处理,例如去噪。否则连通域检测会出错。如果图片有扭曲,则过滤外接矩形的长宽比也要相应调整。总体来说,仅仅使用形态学处理的车牌识别方法,对于质量好的图片是可以实现。但是实际中可能会遇到更复杂的情况,这时候往往需要深度学习的方法进行识别。 如果您需要更加准确和鲁棒的车牌识别方法,可以考虑使用深度学习的方法。深度学习方法可以通过卷积神经网络(CNN)对车牌进行端到端的识别,不需要手动提取特征。常用的深度学习框架包括TensorFlow、PyTorch等,也有一些开源的车牌识别项目,例如EasyPR、HyperLPR等。这些项目提供了完整的车牌识别流程,包括数据集的准备、模型的训练和测试等。如果您对深度学习不熟悉,可以先学习一些基础知识,例如卷积神经网络、反向传播算法等。
写文章

热门文章

  • 【python + opencv + pytorch】车牌提取、分割、识别 pro版 13088
  • pytorch 加载使用预训练模型和 fine tune 模型微调(冻结一部分层)实战 9914
  • 【python ++ opencv + pytorch 】车牌提取、分割、识别 9301
  • 用 pytorch 搭建一个残差网络(ResNet50)分类器(基于 kaggle 猫狗数据集) 4895
  • C++必掌握知识点 1746

分类专栏

  • 深度学习 6篇
  • 数据结构与算法 4篇

最新评论

  • 【python + opencv + pytorch】车牌提取、分割、识别 pro版

    平夕1009: 数据集自取 链接:https://pan.baidu.com/s/1xwtQg6lD3XFrDOCyg7FIHw 提取码:1009

  • 【python ++ opencv + pytorch 】车牌提取、分割、识别

    平夕1009: 数据集自取 链接:https://pan.baidu.com/s/1fhwaUNuPsS6Doaplldx7aA 提取码:1009

  • 【python ++ opencv + pytorch 】车牌提取、分割、识别

    2201_75852780: 大佬,github上已经starl了,博客也已经点赞,求这个数据集1355406368@qq.com

  • 【python ++ opencv + pytorch 】车牌提取、分割、识别

    qq_43087816: 大佬,我也求一份数据集合1538893128@qq.com

  • 【python ++ opencv + pytorch 】车牌提取、分割、识别

    平夕1009: 下班后发你

最新文章

  • 【python + opencv + pytorch】车牌提取、分割、识别 pro版
  • C++ 重点(智能指针,多线程,GDB调试等)
  • C++必掌握知识点
2022年3篇
2021年4篇
2020年4篇

目录

目录

评论 117
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳坪山网站建设公司企业网站优化湖南岚鸿优化天津去哪找网站关键词优化武汉移动网站优化快速获取排名龙口全网营销网站优化公司蒲江网站排名优化中卫网站优化推广铁岭珠宝行业网站优化方案亳州网站推广优化哪家有实力枣阳seo网站优化衡水网站建设优化网站seo优化怎么收费呀开封网站搜索优化可以用于seo优化网站模版如何选择优化公司网站推广网站排名优化效果好不好东至网站优化哪家性价比高巢湖网站优化电话蚌埠市网站优化常德网站搜索优化方案高淳区小企业网站优化哪里好汕尾网站竞价优化案例梅州公司网站关键词优化方法上海网站推广优化故城县网站优化建设南平网站优化免费咨询承德网站优化推广公司教育网站视频加载优化seo优化网站查询360网站如何优化如何优化企业网站香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

深圳坪山网站建设公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化