当前位置: 首页 > news >正文

【图像处理】利用numpy、opencv、python实现车牌检测

|在这里插入图片描述

利用opencv实现车牌检测

整体流程涉及5个部分

  • 图像通道转换
  • 对比度增强
  • 边缘连接
  • 二值化
  • 边界区域裁剪

图像通道转换

将RGB图像转换为HSV图像,仅保留V通道。V通道表示颜色的明暗,常用于图像对比度拉伸、直方图均衡化等流程。
原图像:
在这里插入图片描述
V通道图像:
在这里插入图片描述

对比度增强

通过顶帽变换来实现对比度增强。顶帽变换用于提取图像的小区域和局部细节。白顶帽变换用于提取图像中比周围环境亮的小物体或细节;黑顶帽变换用于提取图像中比周围环境暗的小物体或细节。
白顶帽变换:
在这里插入图片描述
黑顶帽变化:
在这里插入图片描述
通过白顶帽、黑顶帽的联合处理: I e n h a n c e d = I o r i g i n a l + I w h i t e − t o p _ h a t − I b l a c k − t o p _ h a t I_{enhanced}=I_{original}+I_{white-top\_hat}-I_{black-top\_hat} Ienhanced=Ioriginal+Iwhitetop_hatIblacktop_hat,其中 I o r i g i n a l I_{original} Ioriginal表示原图像, I w h i t e − t o p _ h a t I_{white-top\_hat} Iwhitetop_hat表示白顶帽处理后图像, I b l a c k − t o p _ h a t I_{black-top\_hat} Iblacktop_hat表示黑顶帽处理后图像,得到对比度增强后的图像:

在这里插入图片描述

边缘连接

增强对比度后,很多车牌边缘不连续,例如
在这里插入图片描述
需要通过膨胀操作(Dilation Operation)来扩展边缘,实现边缘连接的目的。
添加膨胀操作后,图像转变为:
在这里插入图片描述

二值化

将单通道V图像转换为二值图像,具体策略为Adaptive thresholding
在这里插入图片描述

边界区域裁剪

  • 首先,利用cv2.findContours检测边界,并且获得边界的层级(hierarchy)。
  • 车牌检测可以理解为找到内边界,而整个图像的背景可以理解为是外边界。下图是检测出的内边界
    在这里插入图片描述
    对内边界进行阈值判断处理,过滤掉明显错误的情况。例如过滤面积小于2000的内边界(具体数值需要按照实际情况来定)
  • 对于每个内边界,计算外接最小的矩形(可以通过统计边界内最左、最上、最右、最下的点来合成矩形),作为初步检测框
    在这里插入图片描述
  • 有一些检测框可能包括多个车牌,宽度、高度比较大。对于这种情况,需要对检测框按照宽度、高度均匀分割。以下是一个高度过大的例子,需按高度均分
    在这里插入图片描述
  • 有一些车牌因为自身比较模糊,导致检测框不准确,可以通过统计信息来过滤掉,本方法暂不处理。例如
    在这里插入图片描述

最终,整张图有41个车牌,通过上述方法,检测到了40个车牌,效果不错。漏检的车牌本身边缘不清晰,检测难度较大
在这里插入图片描述

消融实验

方法最终图像检测框车牌检测数量
最终方法在这里插入图片描述40
去掉对比度增强在这里插入图片描述39
去掉边缘连接在这里插入图片描述39
内边界面积过滤阈值4000在这里插入图片描述38
内边界面积过滤阈值5000在这里插入图片描述38

代码

"""
主要的步骤为:
1)提取单通道图片,选项为 (灰度图片/HSV中的value分支)
2)提升对比度,选项为 (形态学中的顶帽/灰度拉伸)
3)边缘连接(膨胀)
4)二值化
5)利用findcontours函数找到边缘
6)裁剪图片,车牌图片存储
7) 对车牌预处理
8)方向矫正
9)车牌精确区域搜索
10) 字符分割
11) 字符识别
"""import cv2
import copy
import numpy as np
import math
import osdef SingleChannel(img) :"""用于车牌检测得到单通道图片,主要测试两种方式,灰度通道以及hsv中的v通道:param img: 输入图片:return:"""hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)hue, saturation, value = cv2.split(hsv)cv2.imshow("SingleChannel", value)return valuedef Contrast(img) :"""用于车牌检测利用tophat,提高图片对比度,:param img: 输入图片:return:"""kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))# applying topHat/blackHat operationstopHat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)cv2.imshow("tophat", topHat)blackHat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)cv2.imshow("blackhat", blackHat)add = cv2.add(img, topHat)subtract = cv2.subtract(add, blackHat)cv2.imshow('Constrast', subtract)return subtractdef threshold(img) :"""用于车牌检测采用cv2.adaptiveThreshold方法,对图片二值化:param img: 输入图像:return:"""thresh = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 19, 9)cv2.imshow("thresh", thresh)return threshglobal crop_num
crop_num = 0def drawCoutrous(img_temp) :"""对输入图像查找内边缘,设置阈值,去除一些面积较小的内边缘:param img_temp: 输入图像,经过预处理:return:"""threshline = 2000imgCopy = copy.deepcopy(img_temp)contours, hierarchy = cv2.findContours(imgCopy, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)# print(len(contours), contours[0].shape)# print(hierarchy.shape)maxarea = 0conid = 0img_zero = np.zeros(img.shape)# print("img_zero.shape is : ",img_zero.shape)num_contours = 0contoursList = []for i in range(len(contours)) :if hierarchy[0][i][3] >= 0 :temparea = math.fabs(cv2.contourArea(contours[i]))# print(math.fabs(cv2.contourArea(contours[i])))if temparea > maxarea :conid = imaxarea = tempareaif temparea > threshline :num_contours += 1if num_contours % 7 == 0 :cv2.drawContours(img_zero, contours, i, (0,0,255),1)if num_contours % 7 == 1 :cv2.drawContours(img_zero, contours, i, (255,0,0),1)if num_contours % 7 == 2 :cv2.drawContours(img_zero, contours, i, (0,255,0),1)if num_contours % 7 == 3 :cv2.drawContours(img_zero, contours, i, (0,255,255),1)if num_contours % 7 == 4 :cv2.drawContours(img_zero, contours, i, (255,0,255),1)if num_contours % 7 == 5 :cv2.drawContours(img_zero, contours, i, (255,255,0),1)if num_contours % 7 == 6:cv2.drawContours(img_zero, contours, i, (255, 255, 255), 1)# print(contours[i].shape)contoursList.append(contours[i])# print("maxarea: ",maxarea)# print("number of contours is ", num_contours)# cv2.drawContours(img_zero, contours, conid, (0, 0, 255), 1)cv2.imshow("with contours",img_zero)return contoursListdef DrawRectangle(img, img_temp, ConList) :"""得到车牌边缘的的x,y坐标最小最大值,再原图上绘制bounding box,得到裁剪后的车牌图像:param img:      原图:param img_temp:    二值图像:param ConList:     图像的边缘轮廓:return:   null"""length = len(ConList)rectanglePoint = np.zeros((length, 4, 1, 2), dtype = np.int32)img_zeros = np.zeros(img_temp.shape)img_copy = copy.deepcopy(img)img_copy_1 = copy.deepcopy(img)# print("img_zeros, length; ", img_zeros.shape, length)for i in range(length) :contours = ConList[i]minx, maxx, miny, maxy = 1e6, 0, 1e6, 0for index_num in range(contours.shape[0]) :if contours[index_num][0][0] < minx :minx = contours[index_num][0][0]if contours[index_num][0][0] > maxx :maxx = contours[index_num][0][0]if contours[index_num][0][1] < miny :miny = contours[index_num][0][1]if contours[index_num][0][1] > maxy :maxy = contours[index_num][0][1]# print(minx, maxx, miny, maxy)rectanglePoint[i][0][0][0], rectanglePoint[i][0][0][1] = minx, minyrectanglePoint[i][1][0][0], rectanglePoint[i][1][0][1] = minx, maxyrectanglePoint[i][2][0][0], rectanglePoint[i][2][0][1] = maxx, maxyrectanglePoint[i][3][0][0], rectanglePoint[i][3][0][1] = maxx, miny# rectanglePoint.dtype = np.int32# print(rectanglePoint[i].shape)crop_save(minx, maxx, miny, maxy, img_copy_1)# print("dx: ",maxx-minx,"dy: ",maxy-miny, "area: ", (maxx-minx)*(maxy-miny))cv2.polylines(img_copy, [rectanglePoint[i]], True, (0,0,255),2)cv2.imshow("img_zeros_haha", img_copy)def crop_save(minx, maxx, miny, maxy, img_original) :"""裁剪原图,根据minx,maxx,miny,maxy:param minx: x坐标最小值:param maxx: x坐标最大值:param miny: y坐标最小值:param maxy: y坐标最大值:param img_original: 由于需要将绘制结果再原图中显示,输入原图:return:"""global crop_numepsx = 60epsy = 30dx = maxx - minxdy = maxy - minyif dx == dy :returnif dx >= 600 - epsx :dx1, dx2, dx3, dx4 = minx, minx + 1 * int(dx / 3), minx + 2 * int(dx / 3), maxxsave_pth = './crop40/cropimg_' + str(crop_num) + '.jpg'# cv2.imwrite(save_pth, img_original[dx1:dx2, miny:maxy,:])cv2.imwrite(save_pth, img_original[miny:maxy, dx1:dx2, :])crop_num += 1save_pth = './crop40/cropimg_' + str(crop_num) + '.jpg'cv2.imwrite(save_pth, img_original[miny:maxy, dx2:dx3, :])crop_num += 1save_pth = './crop40/cropimg_' + str(crop_num) + '.jpg'cv2.imwrite(save_pth, img_original[miny:maxy, dx3:dx4, :])crop_num += 1elif dx >= 400 - epsx :dx1, dx2, dx3 = minx, minx + 1 * int(dx / 2), maxxsave_pth = './crop40/cropimg_' + str(crop_num) + '.jpg'cv2.imwrite(save_pth, img_original[miny:maxy, dx1:dx2, :])crop_num += 1save_pth = './crop40/cropimg_' + str(crop_num) + '.jpg'cv2.imwrite(save_pth, img_original[miny:maxy, dx2:dx3, :])crop_num += 1elif dy >= 240 - epsy :dy1, dy2, dy3, dy4 = miny, miny + 1 * int(dy / 3), miny + 2 * int(dy / 3), maxysave_pth = './crop40/cropimg_' + str(crop_num) + '.jpg'cv2.imwrite(save_pth, img_original[dy1: dy2, minx:maxx, :])crop_num += 1save_pth = './crop40/cropimg_' + str(crop_num) + '.jpg'cv2.imwrite(save_pth, img_original[dy2: dy3, minx:maxx, :])crop_num += 1save_pth = './crop40/cropimg_' + str(crop_num) + '.jpg'cv2.imwrite(save_pth, img_original[dy3: dy4, minx:maxx, :])crop_num += 1elif dy >= 160 - epsy :dy1, dy2, dy3 = miny, miny + 1 * int(dy / 2), maxysave_pth = './crop40/cropimg_' + str(crop_num) + '.jpg'cv2.imwrite(save_pth, img_original[dy1: dy2, minx:maxx, :])crop_num += 1save_pth = './crop40/cropimg_' + str(crop_num) + '.jpg'cv2.imwrite(save_pth, img_original[dy2: dy3, minx:maxx, :])crop_num += 1elif dx <= 200 + epsx :dx1, dx2 = minx, maxxsave_pth = './crop40/cropimg_' + str(crop_num) + '.jpg'cv2.imwrite(save_pth, img_original[miny:maxy, dx1:dx2, :])crop_num += 1else :passif __name__ == '__main__' :pth = 'License_plates.jpg'img = cv2.imread(pth)img = cv2.resize(img, (292 * 4, 173 * 4))cv2.imshow("original",img)# 1)提取单通道图片,选项为 (灰度图片/HSV中的value分支)singlechannel_img = SingleChannel(img)# 2)提升对比度contrast_img = Contrast(singlechannel_img)# contrast_img = singlechannel_img# 3)边缘连接(膨胀)kernel = np.ones((2, 2), np.uint8)dilation_img = cv2.dilate(contrast_img, kernel, iterations=1)cv2.imshow("dilate", dilation_img)# dilation_img = contrast_img# 4) 二值化threshold_img = threshold(dilation_img)# 5)利用findcontours函数找到边缘contoursList = drawCoutrous(threshold_img)# 6) 裁剪图片,车牌图片存储DrawRectangle(img, threshold_img, contoursList)cv2.waitKey()cv2.destroyAllWindows()

相关文章:

【图像处理】利用numpy、opencv、python实现车牌检测

| 利用opencv实现车牌检测 整体流程涉及5个部分 图像通道转换对比度增强边缘连接二值化边界区域裁剪 图像通道转换 将RGB图像转换为HSV图像&#xff0c;仅保留V通道。V通道表示颜色的明暗&#xff0c;常用于图像对比度拉伸、直方图均衡化等流程。 原图像&#xff1a; V通…...

ModuleNotFoundError: No module named ‘torchvision.transforms.functional_tensor‘

问题&#xff1a; 运行代码时&#xff0c;报错&#xff1a; … File “/home/xzy/anaconda3/envs/groundinggpt/lib/python3.10/site-packages/pytorchvideo/transforms/augmix.py”, line 6, in from pytorchvideo.transforms.augmentations import ( File “/home/xzy/anac…...

Android无障碍服务监听实现自动点击按钮

原理&#xff1a; 通过监听窗口改变事件&#xff0c;监听目标应用&#xff0c;通过视图ID&#xff08;或文本、或描述、或其他如坐标之类的&#xff09;找到目标视图&#xff0c;使用无障碍动作点击方法点击它 无障碍服务实现&#xff1a; 1、写一个自己的无障碍服务继承Acc…...

Deveco Studio首次编译项目初始化失败

编译项目失败 Ohpm install失败的时候重新使用管理者打开程序 build init 初始化失败遇到了以下报错信息 Installing pnpm8.13.1... npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/pnpm failed, r…...

Redis缓存应用场景【Redis场景上篇】

文章目录 1.缓存基础2.缓存异步场景1.缓存穿透2.缓存击穿3.缓存雪崩总结 3.缓存一致性 1.缓存基础 Redis由于性能高效&#xff0c;通常可以做数据库存储的缓存。一般而言&#xff0c;缓存分为服务端缓存和客户端缓存。缓存有以下三种模式&#xff1a; Cache Aside&#xff08…...

线程与进程基础

文章目录 前言一、 线程与进程1.1 什么是线程与进程&#xff1f;1.2 并发与并行1.3 同步调用与异步调用1.4 为什么要使用多线程&#xff1f; 前言 在学习juc前&#xff0c;需要先对进程和线程之间整体有一个认知。我们之前或多或少接触过&#xff0c;一些特别高大上的概念&…...

electron 打包 webview 嵌入需要调用电脑摄像头拍摄失败问题

electron 打包 webview 嵌入需要调用电脑摄像头拍摄失败问题 这篇文章是接我cocos专栏的上一篇文章继续写的&#xff0c;我上一篇文章写的是 cocos 开发触摸屏项目&#xff0c;需要嵌入一个网页用来展示&#xff0c;最后通过 electron 打包成 exe 程序&#xff0c;而且网页里面…...

OpenCV的简单练习

1、读取一张彩色图像并将其转换为灰度图。 import matplotlib.pyplot as pltimg plt.imread("./flower.png") # 灰度化 img_gray img[:,:,0]*0.299 img[:,:,1]*0.587 img[:,:,2]*0.114plt.subplot(121) plt.imshow(img) plt.subplot(122) plt.imshow(img_gray,c…...

JAVA:建造者模式(Builder Pattern)的技术指南

1、简述 建造者模式(Builder Pattern)是一种创建型设计模式,它通过将对象的构造过程与表示分离,使得相同的构造过程可以创建不同的表示。建造者模式尤其适用于创建复杂对象的场景。 设计模式样例:https://gitee.com/lhdxhl/design-pattern-example.git 本文将详细介绍建…...

12.11函数 结构体 多文件编译

1.脑图 定义一个数组&#xff0c;用来存放从终端输入的5个学生的信息【学生的信息包含学生的姓名、年纪、性别、成绩】 1>封装函数 录入5个学生信息 2>封装函数 显示学生信息 3>封装函数 删除第几个学生信息&#xff0c;删除后调用显示学生信息函数 显示 4> 封…...

Debezium系列之:使用Debezium采集oceanbase数据库

Debezium系列之:使用Debezium采集oceanbase数据库 一、oceanbase数据库二、安装OceanBase三、安装oblogproxy四、基于Docker的简单采集案例五、生产实际应用案例Debezium 是一个开源的分布式平台,用于监控数据库变化和捕捉数据变动事件,并以事件流的形式导出到各种消费者。D…...

VMware虚拟机 Ubuntu没有共享文件夹的问题

在虚拟机的Ubuntu系统中&#xff0c;共享文件目录存放在 mnt/hgfs 下面&#xff0c;但是我安装完系统并添加共享文件后发现&#xff0c;在mnt下连/hgfs目录都没有。 注意&#xff1a;使用共享文件目录需要已安装VMtools工具。 添加共享文件目录 一&#xff1a;在超级用户下 可…...

spring使用rabbitmq当rabbitmq集群节点挂掉 spring rabbitmq怎么保证高可用

##spring rabbitmq代码示例 Controller代码 import com.alibaba.fastjson.JSONObject; import com.newland.mi.config.RabbitDMMQConfig; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.MessageProperties; import org.springframewo…...

简单vue3前端打包部署到服务器,动态配置http请求头后端ip方法教程

vue3若依框架前端打包部署到服务器&#xff0c;需要部署到多个服务器上&#xff0c;每次打包会很麻烦&#xff0c;今天教大家一个动态配置请求头api的方法&#xff0c;部署后能动态获取(修改)对应服务器的请求ip 介绍两种方法&#xff0c;如有需要可以直接尝试步骤一&#xff…...

C语言关于溢出和不溢出的判断

通过实验来判断整数溢出&#xff0c;浮点数溢出的情况 #include <stdio.h> #include <limits.h> #include <float.h> int main(void) { // 整数溢出 int int_max INT_MAX; // INT_MAX 是 int 类型的最大值 int int_min INT_MIN; // INT_MIN …...

活动预告 |【Part1】Microsoft Azure 在线技术公开课:使用 Microsoft Fabric 实现数据湖仓

课程介绍 通过 Microsoft Learn 免费参加 Microsoft Azure 在线技术公开课&#xff0c;掌握创造新机遇所需的技能&#xff0c;加快对 Microsoft Cloud 技术的了解。参加“使用 Microsoft Fabric 实现数据湖仓”活动&#xff0c;了解如何在 AI 的帮助下统一数据分析。了解如何简…...

Unreal的Audio::IAudioCaptureStream在Android中录制数据异常

修改OpenAudioCaptureStream启动参数为PCM_32&#xff0c;在PC上正常&#xff0c;在Android系统&#xff0c;读取的的数据计算出的音量值在0.4-0.6之间跳动&#xff0c;数据异常。 Audio::FAudioCaptureDeviceParams Params;/** 设置声卡不支持的采样数和通道数开始音频流不会成…...

6、AI测试辅助-测试报告编写(生成Bug分析柱状图)

AI测试辅助-测试报告编写&#xff08;生成Bug分析柱状图&#xff09; 一、测试报告1. 创建测试报告2. 报告补充优化2.1 Bug图表分析 3. 风险评估 总结 一、测试报告 测试报告内容应该包含&#xff1a; 1、测试结论 2、测试执行情况 3、测试bug结果分析 4、风险评估 5、改进措施…...

【第五节】docker应用系列篇: 使用Docker容器实现ElasticSearch+Kibana部署

系列文章目录 【第五节】docker应用系列篇&#xff1a; 使用Docker容器实现ElasticSearchKibana部署 系列文章目录前言一、 docker运行es二、 docker运行kibina 前言 配一次&#xff0c;真觉得方面 一、 docker运行es docker pull elasticsearch:7.17.0# mkdir -p /opt/es/co…...

openwrt 通过DHCP/DNS(Dnsmasq)屏蔽指定域名(hosts)

1、准备好hosts文件 2、登录openwrt后台&#xff1a;系统-TTYD终端-root登录&#xff1a; cd /etc ls vi hosts_by_me vi hosts_by_me 创建/打开 hosts_by_me文件&#xff0c;把准备好的hosts文件的内容复制粘贴进去&#xff0c;然后保存退出:wq cat hosts_by_me查看确认保…...

【NOIP】1998真题解析 luogu-P1008 三连击 | GESP三、四级以上可练习

NOIP 1998 普及组真题&#xff0c;主要考察枚举算法与数位分离。题目要求将 这些数字进行组合&#xff0c;寻找符合特定比例的三位数。这是一个很经典的暴力枚举题。GESP三、四级以上可练习。题目难度⭐⭐☆☆☆&#xff0c;洛谷难度等级普及−。 luogu-P1008 [NOIP 1998 普…...

HunyuanVideo-Foley部署教程:vSphere虚拟机中GPU直通RTX4090D配置指南

HunyuanVideo-Foley部署教程&#xff1a;vSphere虚拟机中GPU直通RTX4090D配置指南 1. 环境准备与硬件要求 1.1 硬件配置清单 显卡&#xff1a;RTX 4090D 24GB显存&#xff08;必须&#xff09;CPU&#xff1a;10核及以上&#xff08;推荐Intel Xeon或AMD EPYC&#xff09;内…...

安全自定义暗黑2体验:d2s-editor的无门槛存档编辑方案

安全自定义暗黑2体验&#xff1a;d2s-editor的无门槛存档编辑方案 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor 副标题&#xff1a;从零开始的本地化存档修改掌握之路 你是否曾因反复刷装备而失去对暗黑破坏神2的耐心&#x…...

语音转文字神器:Speech Seaco Paraformer镜像快速部署与实战技巧

语音转文字神器&#xff1a;Speech Seaco Paraformer镜像快速部署与实战技巧 1. 引言&#xff1a;为什么选择Speech Seaco Paraformer 在日常工作和学习中&#xff0c;我们经常需要将会议录音、访谈内容或课程讲解转换成文字。传统的人工转录不仅耗时耗力&#xff0c;而且成本…...

ESP32-S3 + OV5640摄像头实战:用SD卡模块做个离线拍照盒(附完整代码)

ESP32-S3 OV5640摄像头实战&#xff1a;打造智能离线拍照盒的完整指南 在创客和硬件爱好者的世界里&#xff0c;将高性能硬件与实用功能相结合的项目总是令人兴奋。ESP32-S3搭配OV5640摄像头就是一个绝佳组合&#xff0c;能够实现高质量的图像采集和处理。本文将带你从零开始&…...

物联网毕业设计本科生开题指导

【单片机毕业设计项目分享系列】 &#x1f525; 这里是DD学长&#xff0c;单片机毕业设计及享100例系列的第一篇&#xff0c;目的是分享高质量的毕设作品给大家。 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的单片机项目缺少创新和亮点…...

基于SiameseUniNLU的文本匹配与NLI实战:开源中文推理模型部署案例

基于SiameseUniNLU的文本匹配与NLI实战&#xff1a;开源中文推理模型部署案例 1. 项目介绍与核心价值 SiameseUniNLU是一个创新的中文自然语言理解模型&#xff0c;它采用统一的架构来处理多种NLP任务。这个模型最大的特点是用一套代码就能完成文本匹配、自然语言推理、实体识…...

在github上部署个人的vitepress文档网站

我开发的BMapViewer组件正式上线了&#xff0c;文档使用了vitepress搭建编写&#xff0c;使用github Pages进行部署&#xff0c;现在可以正常访问了&#xff0c;接下来我会完整的写一遍网站部署过程。 我的文档网站&#xff1a;https://banyan666.github.io/BMapViewer-docs/ …...

Hunyuan-MT-7B部署教程:像素语言传送门在阿里云ACK集群中实现高可用服务编排

Hunyuan-MT-7B部署教程&#xff1a;像素语言传送门在阿里云ACK集群中实现高可用服务编排 1. 项目概述 像素语言跨维传送门(Pixel Language Portal)是基于腾讯Hunyuan-MT-7B大模型构建的创新翻译工具。与传统翻译软件不同&#xff0c;它将语言转换过程设计为16-bit像素冒险体验…...

告别手动抓包!用Playwright+Python自动嗅探网页M3U8视频流(附完整代码)

自动化嗅探网页M3U8视频流&#xff1a;Playwright与Python的完美结合 在当今数字化时代&#xff0c;视频内容已成为网络信息的主要载体之一。对于开发者而言&#xff0c;如何高效地从网页中提取视频资源一直是个值得探讨的话题。传统的手动F12抓包方式不仅效率低下&#xff0c;…...