车牌号识别(低级版)

news2024/11/25 11:00:06
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()

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自养号测评避坑指南

朋友们&#xff0c;今天来聊一聊关于自养号测评的一些重要知识点——自养号测评避坑指南。 在跨境电商领域中&#xff0c;自养号测评是每个卖家必需要会的技术。它能帮助商家提升店铺的权重和产品排名&#xff0c;从而带来曝光率和销售量。 但这个过程里也有不少坑&#xff0…

失眠焦虑的解脱之道:找回内心的平静

&#x1f343; 在这个快节奏的时代&#xff0c;失眠与焦虑似乎成了许多人的隐形敌人。每当夜幕降临&#xff0c;它们便悄悄潜入心底&#xff0c;扰乱我们的思绪&#xff0c;让宁静的夜晚变得无比漫长。然而&#xff0c;生活总有办法让我们找回内心的平静&#xff0c;只需稍作调…

OLED柔性屏的显示效果如何

OLED柔性屏的显示效果非常出色&#xff0c;具有多方面的优势。以下是关于OLED柔性屏显示效果的详细分析&#xff1a; 色彩表现&#xff1a;OLED柔性屏的每个像素都可以独立发光&#xff0c;因此色彩准确性极高。黑色呈现得非常深邃&#xff0c;而亮部则展现出鲜明而生动的细节。…

2024网络安全学习路线 非常详细 推荐学习

关键词&#xff1a;网络安全入门、渗透测试学习、零基础学安全、网络安全学习路线 首先咱们聊聊&#xff0c;学习网络安全方向通常会有哪些问题 1、打基础时间太长 学基础花费很长时间&#xff0c;光语言都有几门&#xff0c;有些人会倒在学习 linux 系统及命令的路上&#…

【云原生】Kubernetes----Rancher助力Kubernetes监控

目录 引言 一、为什么需要监控K8s集群&#xff1f; 二、Rancher监控K8s集群的优势 三、Rancher和k8s的区别 四、Rancher 安装及配置 &#xff08;一&#xff09;安装rancher 1.下载镜像 2.运行容器 3.登录Rancher平台 4.添加集群 5.查看集群 6.Rancher 部署监控系统…

私域引流宝PHP源码 以及搭建教程

私域引流宝PHP源码 以及搭建教程

uni-date-picker 禁用日期功能

在uni-datetime-picker组件中 calendar.vue <template><view class"uni-calendar" mouseleave"leaveCale"><view v-if"!insert && show" class"uni-calendar__mask" :class"{uni-calendar--mask-show:an…

Linux服务器快速下载GoogleDriver小技巧——利用gdown工具

Linux服务器快速下载GoogleDriver小技巧——利用gdown工具 1. 安装gdown pip install gdown安装好后如果在终端输入gdown显示如下错误&#xff1a;gdown: command not found&#xff0c;则说明gdown默认安装的位置需要软链接一下&#xff0c;执行以下命令&#xff1a; sudo …

坑记(MySQL之delete操作)

背景知识 我们知道MySQL有两种删除操作&#xff1a;delete和truncate。 二者之间是否一样&#xff0c;且看以下内容&#xff1a; 操作名称操作简介deleteDML中的一种&#xff0c;操作对象是记录&#xff0c;即table中的一行&#xff0c;可恢复&#xff0c;速度慢truncateDDL中…

怎么防止源代码泄露?9种方法教会你!

怎么防止源代码泄露&#xff1f;首先要了解员工可以通过哪些方式将源代码传输出去&#xff01; 物理方法&#xff1a; — 网线直连&#xff0c;即把网线从墙上插头拔下来&#xff0c;然后和一个非受控电脑直连; — winPE启动&#xff0c;通过光盘或U盘的winPE启动&#xff0c;甚…

execl拷贝图片

1&#xff1a;拷贝图片 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h>int main(int argc, const char *argv[]) {//在子进程拥有和父进程一样的拷贝文件(确保拷贝文件为空)int fp_…

SSC30KD SigmaStar 摄像头主控芯片

SSC30KD SigmaStar 摄像头主控芯片

# RocketMQ 实战:模拟电商网站场景综合案例(十一)

RocketMQ 实战&#xff1a;模拟电商网站场景综合案例&#xff08;十一&#xff09; 一、RocketMQ 实战&#xff1a;模拟电商网站场景综合案例-- web 端项目开发 1、在 shop-order-web 工程模块中&#xff0c;创建 Controller 类 OrderControllre.java /*** shop\shop-order…

Threejs-09、贴图的加载与环境遮蔽强度设置

1、创建文理加载器 let textureLoader new THREE.TextureLoader();2、加载贴图 // 加载文理 let texture textureLoader.load("./img/image.png") // 加载ao贴图 let aoMap textureLoader.load("./img/image.png");3、创建一个平面 let planeGeomet…

这总商务会议图怎么绘制?一行代码搞定...

今天这篇推文小编给大家介绍一个一直想绘制的图表-议会图(parliament diagrams),当然这也是柱形图系列变形的一种。绘制这种图表也是超级简单的&#xff0c;只需使用R-ggpol包进行绘制即可&#xff0c;当然&#xff0c;改包还提供其他优秀的绘图函数&#xff0c;下面就一起来看…

Final Cut Pro:剪辑之巅,创意无界

Final Cut Pro是一款由Apple推出的专业视频剪辑软件&#xff0c;以其强大的功能和卓越的性能&#xff0c;成为众多影视制作人员、广告设计师和视频编辑师的首选工具。 Final Cut Pro获取 Final Cut Pro提供了丰富的剪辑功能&#xff0c;包括多轨道编辑、精确剪辑控制、实时预览…

AI绘画工具介绍(清晰图例)

一、引言 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经逐渐渗透到我们生活的各个领域&#xff0c;绘画艺术界也不例外。近年来&#xff0c;AI在绘画领域的应用日益广泛&#xff0c;展现出了令人瞩目的发展趋势。通过深度学习和图像处理技术&#xff…

如何在浏览器书签栏设置2个书签实现一键到达网页顶部和底部

本次设置浏览器为&#xff1a;Chrome浏览器&#xff08;其他浏览器可自行测试&#xff09; 1&#xff0c;随便收藏一个网页到浏览器书签栏 2&#xff0c;右键这个书签 3&#xff0c;修改 4&#xff0c;修改名称 5&#xff0c;修改网址&#xff1a; javascript:(function(…

vue 之 vuex

目录 vuex 是什么 Vuex管理哪些状态呢&#xff1f; Vuex 页面刷新数据丢失怎么解决 1. 使用浏览器的本地存储 2. 使用 Vuex 持久化插件 3. 使用后端存储 注意事项 Vuex 为什么要分模块并且加命名空间 vuex 是什么 vuex 是专门为 vue 提供的全局状态管理系统&#xff0c…

flask南京市旅游景点信息可视化的设计与实现-计算机毕业设计源码02941

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对南京市旅游景点信息可视化等问题&#xff0…