车牌号识别(低级版)

import cv2
from matplotlib import pyplot as plt
import os
import numpy as np
from paddleocr import PaddleOCR, draw_ocr
from PIL import Image, ImageDraw, ImageFont


# 利用paddelOCR进行文字扫描,并输出结果
def text_scan(img_path):
    ocr = PaddleOCR(use_angle_cls=True, use_gpu=False)
    # img_path = r'test image/license_plate1.jpg'
    result = ocr.ocr(img_path, cls=True)
    for line in result:
        # print(line)
        return result


# 在图片中写入将车牌信息
def infor_write(img, rect, result):
    text = result[0][0][1][0]
    cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # cv2和PIL中颜色的hex码的储存顺序不同
    pilimg = Image.fromarray(cv2img)
    # PIL图片上打印汉字
    draw = ImageDraw.Draw(pilimg)  # 图片上打印
    font = ImageFont.truetype("simhei.ttf", 20, encoding="utf-8")  # 参数1:字体文件路径,参数2:字体大小
    draw.text((rect[2], rect[1]), str(text), (0, 255, 0), font=font)  # 参数1:打印坐标,参数2:文本,参数3:字体颜色,参数4:字体
    # PIL图片转cv2 图片
    cv2charimg = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
    return cv2charimg

def plt_show0(img):
    #cv2与plt的图像通道不同:cv2为[b,g,r];plt为[r,g,b]
    b,g,r=cv2.split(img)
    img=cv2.merge([r,g,b])
    plt.imshow(img)
    plt.show()
#plt显示灰度图片
def plt_show(img):
    plt.imshow(img,camp='gray')
    plt.show()

# 图像去噪灰度处理
def gray_guss(img):
    img = cv2.GaussianBlur(img, (1, 1), 0)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    return gray


# 图像尺寸变换
def img_resize(img):
    a = 400 * img.shape[0] / img.shape[1]
    a = int(a)
    img = cv2.resize(img, (400, a))
    return img


# Sobel检测,x方向上的边缘检测(增强边缘信息)
def Sobel_detec(img):
    Sobel_x = cv2.Sobel(img, cv2.CV_16S, 1, 0)
    absX = cv2.convertScaleAbs(Sobel_x)
    return absX


# 寻找某区域最大外接矩形框4点坐标
def find_retangle(contour):
    y, x = [], []
    for p in contour:
        y.append(p[0][0])
        x.append(p[0][1])
    return [min(y), min(x), max(y), max(x)]


# 寻找并定位车牌轮廓位置
def locate_license(img):
    blocks = []
    contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    for c in contours:
        x, y, w, h = cv2.boundingRect(c)
        r = find_retangle(c)
        a = (r[2] - r[0]) * (r[3] - r[1])
        s = (r[2] - r[0]) / (r[3] - r[1])
        print(w)
        if (w > (h * 3)) and (w < (h * 5)):
            blocks.append([r, a, s])
        # blocks.append([r, a, s])
    blocks = sorted(blocks, key=lambda b: b[1])[-3:]
    maxweight, maxindex = 0, -1
    for i in range(len(blocks)):
        b = oriimg[blocks[i][0][1]:blocks[i][0][3], blocks[i][0][0]:blocks[i][0][2]]
        hsv = cv2.cvtColor(b, cv2.COLOR_BGR2HSV)
        lower = np.array([70, 150, 50])
        upper = np.array([120, 255, 255])
        mask = cv2.inRange(hsv, lower, upper)
        w1 = 0
        for m in mask:
            w1 += m / 255
        w2 = 0
        for w in w1:
            w2 += w
        if w2 > maxweight:
            maxindex = i
            maxweight = w2
        print('blocks是', blocks[maxindex])
        print('blocks0是',blocks[maxindex][0])
    return blocks[maxindex][0]


# 图像预处理+车牌轮廓位置检测
def fine_lisecenpts(img):
    # 图像去噪灰度处理
    guss = gray_guss(img)

    # Sobel检测,增强边缘信息
    sobel = Sobel_detec(guss)

    # 图像阈值化操作——获得二值化图
    ret, threshold = cv2.threshold(sobel, 0, 255, cv2.THRESH_OTSU)

    # # 对二值化图像进行边缘检测(可选,通过边缘检测后,最终进行形态学运算得到的轮廓面积更大)
    # threshold=cv2.Canny(threshold,threshold.shape[0],threshold.shape[1])

    # 形态学运算(从图像中提取对表达和描绘区域形状有意义的图像分量)——闭操作
    kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 10))
    closing = cv2.morphologyEx(threshold, cv2.MORPH_CLOSE, kernelX, iterations=1)

    # 腐蚀(erode)和膨胀(dilate)
    kernelX = cv2.getStructuringElement(cv2.MORPH_RECT, (50, 1))
    kernelY = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 20))

    # x方向上进行闭操作(抑制暗细节)
    img = cv2.dilate(closing, kernelX)
    img = cv2.erode(img, kernelX)

    # y方向上进行开操作
    img = cv2.erode(img, kernelY)
    img = cv2.dilate(img, kernelY)

    # 进行中值滤波去噪
    Blur = cv2.medianBlur(img, 15)

    # 寻找轮廓
    rect = locate_license(Blur)
    print('rect是',rect)
    return rect, Blur


# 车牌字符识别
def seg_char(rect_list, img):
    img = oriimg[rect_list[1]:rect_list[3], rect_list[0]:rect_list[2]]

    # 图像去噪灰度处理
    gray = gray_guss(img)

    # 图像阈值化操作-获得二值化图(可选)
    # ret,charimage=cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

    # 图像进行闭运算
    k1 = np.ones((1, 1), np.uint8)
    close = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, k1)
    cv2.imshow('close', close)
    cv2.imwrite(r"E:\ultralytics-20240216\21\img2\6.jpg", close)
    cv2.waitKey()

    res = text_scan(r"E:\ultralytics-20240216\21\img2\6.jpg")

    return res
def put_chinese_text(img, text, left_top):
    # 转换 cv2 img 为 PIL Image
    img_PIL = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

    draw = ImageDraw.Draw(img_PIL)
    font = ImageFont.truetype('simhei.ttf', 30, encoding="utf-8")

    # 黄色文字
    fillColor = (255,255,0)

    position = left_top
    draw.text(position, text, font=font, fill=fillColor)

    # 转换回 OpenCV 格式
    img_out = cv2.cvtColor(np.asarray(img_PIL),cv2.COLOR_RGB2BGR)

    return img_out

# 主函数区
if __name__ == '__main__':
    img = cv2.imread(r"E:\ultralytics-20240216\21\img2\5.jpg")
    # 改变图像尺寸
    img = img_resize(img)
    oriimg = img.copy()
    # 寻找到车牌外轮廓矩形坐标
    print(1)
    rect, img = fine_lisecenpts(img)
    # 利用车牌轮廓坐标划分ROI区域用于字符识别,利用OCR识别车牌字符并返回字符串内容
    result = seg_char(rect, oriimg)
    print(result)
    print(rect)

# 循环读取车牌字符串并写入到图片中
    text = result[0][0][1][0]

    # 获取文本所在的矩形位置
    left_top = tuple(rect[0:2])
    right_bottom = tuple(rect[2:4])

    # 在原始图像上绘制矩形(黄色框)
    cv2.rectangle(oriimg, left_top, right_bottom, (0, 255, 255), 2)

    # 在矩形旁边写入文本
    # 注意你可能需要根据实际情况调整文本的位置
    text_position = (right_bottom[0] + 1, right_bottom[1])
    oriimg = put_chinese_text(oriimg, text, text_position)
    # cv2.putText(oriimg, text, text_position, cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2)

    cv2.imshow("Image with text", oriimg)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/726216.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[Mysql] 数据库基本概念

前言---数据库系统发展史 当今主流数据库介绍 一、操作系统 Linux操作系统 &#xff1a;RedHat CentOS Debian Ubuntu OpenSUSE 信创标准 会让系统逐渐国产化 国产系统&#xff1a;华为 欧拉 阿里 龙蜥 腾讯 tencentOS 银河麒麟 中标麒麟…

Linux远程管理日志

实验介绍 本实验旨在实现主机将日志远程发送到堡垒机或远程服务器上&#xff0c;实现通过一台机器管理整个网络内的主机的效果。 准备两台虚拟机作为生产主机和管理机&#xff0c;保证网络通畅&#xff0c;展示如下&#xff1a; 关闭firewalld&#xff0c;通过配置rsyslog&a…

分布式锁实现方案

分布式锁 1 什么是分布式锁 ​ 就是在分布式环境下&#xff0c;保证某个公共资源只能在同一时间被多进程应用的某个进程的某一个线程访问时使用锁。 2 几个使用场景分析 一段代码同一时间只能被同一个不同进程的一个线程执行 库存超卖 (库存被减到 负数)&#xff0c;上面案…

【机器学习】【深度学习】MXnet神经网络图像风格迁移学习简介

使用部分 一、编程环境 编程环境使用Windows11上的Anaconda环境&#xff0c;Python版本为3.6. 关于Conda环境的建立和管理&#xff0c;可以参考我的博客&#xff1a;【Anaconda】【Windows编程技术】【Python】Anaconda的常用命令及实操 二、项目结构&#xff08;代码非原创…

CTF-pwn-虚拟化-【d3ctf-2021-d3dev】

文章目录 参考流程附件检查启动信息逆向分析漏洞查看设备配置信息exp 参考 https://x1ng.top/2021/11/26/qemu-pwn/ https://bbs.kanxue.com/thread-275216.htm#msg_header_h1_0 https://xz.aliyun.com/t/6562?time__1311n4%2BxnD0DRDBAi%3DGkDgiDlhjmYh2xuCllx7whD&alic…

Opencv学习项目2——pytesseract

上一次我们使用pytesseract.image_to_boxes来检测字符&#xff0c;今天我们使用pytesseract.image_to_data来检测文本并显示 实战教程 和上一次一样&#xff0c;添加opencv-python和pytesseract库 首先我们先来了解一下pytesseract.image_to_data pytesseract.image_to_data(…

无人值守工厂设备日志采集工具

免费试用下载: Gitee下载 最新版本 优势: A. 开箱即用. 解压直接运行.不需额外安装. B. 批管理设备. 设备配置均在后台管理. C. 无人值守 客户端自启动,自更新. D. 稳定安全. 架构简单,内存占用小,通过授权访问.

Exposure X7软件安装包下载 丨不限速下载丨亲测好用

根据使用者情况表明Exposure的设计鼓励您进行创造性的工作&#xff0c;使用涂刷和遮罩工具将效果有选择地应用于图片的特定区域&#xff0c;非破坏性图层使您能够混合预设和调整&#xff0c;以获得无尽的外观。我们都知道Exposure是用于创意照片编辑的最佳图片编辑器&#xff0…

【机器学习】使用Python实现图神经网络(GNN):图结构数据的分析与应用

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、引言二、图神经网络的基础知识1. 图的基本概念和术语2. 传统的图分析方法3. 图神经网络的基本原理4. GNN的基本模型 三、主要的图神经网络模型1. 图卷积网络&#xff08;Graph Convolutional Network, GCN&#xff09;2…

086. 分隔链表

题目链接 一、题目描述 (一) 题目 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。你应当保留两个分区中每个节点的初始相对位置。 (二) 示例 示例 1&#xff1a; 输入&a…

2024.6.16 机器学习周报

目录 引言 Abstract 文献阅读 1、题目 2、引言 3、创新点 4、匹配问题 5、SuperGlue架构 5.1、注意力图神经网络&#xff08;Attentional Graph Neural Network&#xff09; 5.2、最佳匹配层&#xff08;Optimal matching layer&#xff09; 5.3、损失 6、实验 6.…

数据分析第三讲:numpy的应用入门(二)

NumPy的应用&#xff08;二&#xff09; 数组对象的方法 获取描述统计信息 描述统计信息主要包括数据的集中趋势、离散程度和频数分析等&#xff0c;其中集中趋势主要看均值和中位数&#xff0c;离散程度可以看极值、方差、标准差等&#xff0c;详细的内容大家可以阅读《统计…

【Java】已解决java.sql.SQLException异常

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决java.sql.SQLException异常 在Java中&#xff0c;java.sql.SQLException是一个通用的异常类&#xff0c;用于表示在数据库操作中发生的错误。无论是类型错误、数据类型不匹配…

YOLOv10改进 | 注意力篇 | YOLOv10引入iRMB

1. iRMB介绍 1.1 摘要:本文重点关注开发现代、高效、轻量级的模型来进行密集预测,同时权衡参数、FLOP 和性能。 反向残差块(IRB)作为轻量级 CNN 的基础设施,但基于注意力的研究尚未认识到对应的部分。 这项工作从统一的角度重新思考高效IRB和Transformer有效组件的轻量级…

国际版游戏陪练源码电竞系统源码支持Android+IOS+H5

&#x1f3ae;电竞之路的得力助手 一、引言&#xff1a;电竞新纪元&#xff0c;陪练小程序助力成长 在电竞热潮席卷全球的今天&#xff0c;每一个电竞爱好者都渴望在竞技场上脱颖而出。然而&#xff0c;独自一人的游戏之路往往充满了挑战和困难。幸运的是&#xff0c;国际版游…

Flutter框架高阶——Window应用程序设置窗体窗口背景完全透明

文章目录 1.修改 main.cpp1&#xff09;C 与 Win32 API2&#xff09;EnableTransparency()3&#xff09;中文注释 2.编写 Flutter 代码1&#xff09;bitsdojo_window2&#xff09;window_manager3&#xff09;区别对比4&#xff09;同时使用&#xff08;1&#xff09;设置初始化…

全球AI视频技术竞赛加速:Runway即将推出更优更快的第三代AI视频模型|TodayAI

Runway即将在未来几天推出其更优更快的第三代AI视频模型&#xff0c;这是新一代模型中最小的一个。据公司透露&#xff0c;这款名为Gen-3的模型将带来“在真实度、一致性和动态效果上的重大提升”&#xff0c;同时在速度上也有显著的加快。 去年六月&#xff0c;Runway首次推出…

【每日刷题】Day70

【每日刷题】Day70 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 922. 按奇偶排序数组 II - 力扣&#xff08;LeetCode&#xff09; 2. 905. 按奇偶排序数组 - 力扣&…

数据库 | 试卷三

1.数据库的网状模型应满足的条件是&#xff08; &#xff09; A&#xff0e;允许一个以上结点无双亲&#xff0c;也允许一个结点有多个双亲 B&#xff0e;必须有两个以上的结点 C&#xff0e;有且仅有一个结点无双亲&#xff0c;其余结点都只有一个双亲 D&#xff0e;每个结…

模拟原神圣遗物系统-小森设计项目,需求分析

需求分析 我操控某个角色的圣遗物时发现&#xff0c;一开始玩啥也不懂慢慢了解&#xff0c;今天才想起要不做一个 &#xff0c;然后开始想需求 跟Ai聊技术 聊着聊着 发现圣遗物 这个东西有点意思 本来今天打算写一下数据库 的外键想起了一些高兴的事情&#xff08;美人鱼&#…