工作杂记-YUV的dump和read

工作小记-YUV的dump和read

  • 工作杂记-YUV的dump和read
  • 利用dump生成图片 yuv2img
  • yuv2img代码

工作杂记-YUV的dump和read

工作中涉及到模型验证相关的工作,这里是三个模型的共同作用,在感知模型读取图片的时候,把输入替换成自己给定的输入,保证一致性,再来看输出。
知道了模型输入的宽高和步长之后,有如下的dump_yuv和read_yuv函数。其中bpu_addr和bpu_addr_uv是y分量和uv分量的地址。

bool ReadYUVImage(const std::string &img_path, int width, int height,uint64_t bpu_addr, uint64_t bpu_addr_uv) {std::ifstream input_img_file(img_path, std::ios::binary);input_img_file.seekg(0, std::ios::end);int len = input_img_file.tellg();input_img_file.seekg(0, std::ios::beg);std::vector<uint8_t> img_data(width * height * 3 / 2);if (len < width * height * 3 / 2) {HSLOG_E << "file length is not right " << len << " img_file:" << img_path;return false;} else {input_img_file.read(reinterpret_cast<char *>(img_data.data()),width * height * 3 / 2);memcpy(reinterpret_cast<void *>(bpu_addr), img_data.data(), width * height);memcpy(reinterpret_cast<void *>(bpu_addr_uv),img_data.data() + width * height, width * height / 2);}input_img_file.close();return true;
}void DumpYUVImage(const std::string &out_file, int width, int height,uint64_t bpu_addr, uint64_t bpu_addr_uv) {std::ofstream fout(out_file, std::ios::out | std::ios::binary);std::vector<uint8_t> src_input_image(width * height * 3 / 2);memcpy(src_input_image.data(), reinterpret_cast<void *>(bpu_addr),width * height);memcpy(src_input_image.data() + width * height,reinterpret_cast<void *>(bpu_addr_uv), width * height / 2);fout.write(reinterpret_cast<char *>(src_input_image.data()),width * height * 3 / 2);fout.close();
}

利用dump生成图片 yuv2img

这里需要了解yuv相关的排布知识。
YUV格式有两大类:planar和packed。
对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。
对于packed的YUV格式,每个像素点的Y,U,V是连续交*存储的。

YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。

planar的YUV格式分为YUV420P和YUV420SP,YUV420P包含I420和YV12。I420格式和YV12格式的不同处在U平面和V平面的位置不同。在I420格式中,U平面紧跟在Y平面之后,然后才是V平面(即:YUV);但YV12则是相反(即:YVU)。
YUV420SP, Y分量平面格式,UV打包格式, 即NV12。 NV12与NV21类似,U 和 V 交错排列,不同在于UV顺序。
I420: YYYYYYYY UU VV =>YUV420P
YV12: YYYYYYYY VV UU =>YUV420P
NV12: YYYYYYYY UVUV =>YUV420SP
NV21: YYYYYYYY VUVU =>YUV420SP
yuv排布

注意转化时要知道文件的uv排列先后顺序,实测u,v颠倒后的图片色差会有变化。
正确的结果 👇
在这里插入图片描述
错误的结果👇
在这里插入图片描述

核心代码,这里有一个opencv的坑,在merge时 会报错Invalid number of channels in input image: ‘VScn::contains(scn)’ ‘scn’,原因时Y U V的shape不一致,解决方案时把UV插值成和Y一样的,在merge,这样shape就成了(h,w,3)这种形式。再调用cv2.COLOR_YUV2BGR去做转化。

    # 分离UV通道为U和VU = UV[:, ::2]V = UV[:, 1::2]# 扩展U和V通道为与Y通道一致的大小U = cv2.resize(U, (width, height), interpolation=cv2.INTER_LINEAR)V = cv2.resize(V, (width, height), interpolation=cv2.INTER_LINEAR)# 合并Y、U、V通道数据YUV420p_image = cv2.merge((Y, U, V))# 转换为RGB格式image_rgb = cv2.cvtColor(YUV420p_image, cv2.COLOR_YUV2BGR)

yuv2img代码

如下是根据dump的yuv文件生成图片,其中三个函数,分别为灰度(only y 分量),420sp直接转RGB,420sp 提取 U、V分量后,再插值和Y分量组成YUV444,再转成RGB。

Y = np.frombuffer(buffer[:Y_size], dtype=np.uint8).reshape(height, width)
UV = np.frombuffer(buffer[Y_size:], dtype=np.uint8).reshape(height // 2, width)# 分离UV通道为U和V
U = UV[:, ::2] # 实际上是选择 UV 数组的所有行,但只选择每一行中的偶数列元素,即第0列、第2列、第4列等
V = UV[:, 1::2] # 扩展U和V通道为与Y通道一致的大小
U = cv2.resize(U, (width, height), interpolation=cv2.INTER_LINEAR)
V = cv2.resize(V, (width, height), interpolation=cv2.INTER_LINEAR)# 合并Y、U、V通道数据
YUV420p_image = cv2.merge((Y, U, V))
import cv2
import numpy as np
import re
import osdef convert_YUV420sp_RGB(yuv_file):# 从文件名中提取宽度和高度match = re.search(r'_w_(\d+)_h_(\d+)', yuv_file)if match:width = int(match.group(1))height = int(match.group(2))else:print("无法提取分辨率信息:", yuv_file)returnprint(width, height)with open(yuv_file, "rb") as f:buffer = f.read()image = np.frombuffer(buffer, np.uint8).reshape(height*3//2, width)print(image.size, image.shape)image_rgb = cv2.cvtColor(image, cv2.COLOR_YUV420SP2RGB)yuv_file = os.path.basename(yuv_file)output_file = yuv_file.replace(".yuv", ".jpg")output_file = os.path.join(output_folder_path, f"{output_file}.jpg")cv2.imwrite(output_file, image_rgb)# print(output_file)def convert_YUV420sp_YUV444_RGB(yuv_file):# 从文件名中提取宽度和高度match = re.search(r'_w_(\d+)_h_(\d+)', yuv_file)if match:width = int(match.group(1))height = int(match.group(2))else:print("无法提取分辨率信息:", yuv_file)return# 读取YUV420sp图像数据with open(yuv_file, "rb") as f:buffer = f.read()# 解析Y、UV通道数据Y_size = width * heightUV_size = width * height // 2Y = np.frombuffer(buffer[:Y_size], dtype=np.uint8).reshape(height, width)UV = np.frombuffer(buffer[Y_size:], dtype=np.uint8).reshape(height // 2, width)# 分离UV通道为U和VU = UV[:, ::2]V = UV[:, 1::2]# 扩展U和V通道为与Y通道一致的大小U = cv2.resize(U, (width, height), interpolation=cv2.INTER_LINEAR)V = cv2.resize(V, (width, height), interpolation=cv2.INTER_LINEAR)# 合并Y、U、V通道数据YUV420p_image = cv2.merge((Y, U, V))# 转换为RGB格式image_rgb = cv2.cvtColor(YUV420p_image, cv2.COLOR_YUV2BGR)yuv_file = os.path.basename(yuv_file)output_file = yuv_file.replace(".yuv", ".jpg")output_file = os.path.join(output_folder_path, f"{output_file}.jpg")cv2.imwrite(output_file, image_rgb)# print(output_file)def convert_YUV420sp_GRAY(yuv_file):file_name = os.path.splitext(yuv_file)[0]match = re.search(r'_w_(\d+)_h_(\d+)', yuv_file)if match:width = int(match.group(1))height = int(match.group(2))else:print("无法提取分辨率信息:", yuv_file)return# 打开YUV文件并读取数据with open(yuv_file, 'rb') as file:buffer = file.read()Y_size = width * heightY_data = buffer[:Y_size]# 将Y数据转换为NumPy数组Y = np.frombuffer(Y_data, dtype=np.uint8).reshape((height, width))gray_image = cv2.cvtColor(Y, cv2.COLOR_GRAY2BGR)yuv_file = os.path.basename(yuv_file)output_file = yuv_file.replace(".yuv", ".jpg")output_file = os.path.join(output_folder_path, f"{output_file}.jpg")cv2.imwrite(output_file, gray_image)return# 定义输入YUV文件夹路径
input_folder_path = "./dump_yuv"  # 替换为包含YUV文件的文件夹路径# 定义输出JPEG文件夹路径
output_folder_path = input_folder_path + "_output"  # 保存JPEG文件的文件夹路径
if not os.path.exists(output_folder_path):os.makedirs(output_folder_path)# 获取输入文件夹中的所有YUV文件
yuv_files = [file for file in os.listdir(input_folder_path) if file.endswith(".yuv")]for yuv_file in yuv_files:print(yuv_file)# convert_YUV420sp_YUV444_RGB(input_folder_path + "/" + yuv_file)# convert_YUV420sp_RGB(input_folder_path + "/" + yuv_file)convert_YUV420sp_GRAY(input_folder_path + "/" + yuv_file)
model_id:0 percepts_[0] rect num:1
model_id:0 rect:388.95 1034.04 520.791 1163.19 7.03816 0
model_id:0 percepts_[5] rect num:8
model_id:0 rect:2164.7 1034.81 2261.26 1110.25 8.7623 5
model_id:0 rect:2464.56 996.751 2519.25 1059.25 7.19807 5
model_id:0 rect:2654.99 593.22 2744.83 696.733 8.5591 5
model_id:0 rect:2914.5 570.069 3007.19 666.134 8.76954 5
model_id:0 rect:3044.18 553.215 3152.04 664.448 8.68193 5
model_id:0 rect:3185.64 543.125 3295.19 652.673 7.15572 5
model_id:0 rect:3750.75 609.548 3836 781.291 8.73659 5
model_id:0 rect:3761.16 792.687 3836 1073.72 9.44854 5
model_id:0 percepts_[11] rect num:3
model_id:0 rect:247.464 1250.77 334.153 1311.08 7.29449 11
model_id:0 rect:1664.7 1409.73 2243.79 1526.45 7.30121 11
model_id:0 rect:3057.62 1149.15 3528.76 1186.85 7.29843 11
model_id:0 percepts_[13] rect num:3
model_id:0 rect:1390.61 1212.43 1441.98 1423.03 8.79426 13
model_id:0 rect:1992.3 1189.52 2025.68 1335.91 7.29169 13
model_id:0 rect:2816.59 1182.99 2865.39 1378.19 7.29921 13

再额外附一段画框的代码

import cv2
import re# 读取图片
image_path = './dump_yuv_v3_output/model_50_frame_1694608049106_w_3840_h_2160.jpg.jpg'
image = cv2.imread(image_path)# 打开包含矩形框坐标的文件
with open('rect.txt', 'r') as file:lines = file.readlines()# 正则表达式模式,用于匹配包含model_id和percepts的行
model_pattern = re.compile(r'model_id:\d+ percepts_\[(\d+)\] rect num:(\d+)')# 正则表达式模式,用于匹配包含model_id和rect的行
rect_pattern = re.compile(r'model_id:\d+ rect:(\d+(?:\.\d+)?) (\d+(?:\.\d+)?) (\d+(?:\.\d+)?) (\d+(?:\.\d+)?)')# 初始化一个字典来存储percepts_值和颜色的映射
percepts_color_mapping = {"0": (0, 0, 255),   # 红色"5": (0, 255, 0),   # 绿色"11": (255, 0, 0),   # 蓝色"13": (0, 255, 255), # 黄色
}# 遍历文件中的每一行
for line in lines:# 尝试匹配包含矩形坐标的行model_match = model_pattern.match(line)if model_match:percept_index = model_match.group(1)num_rects = model_match.group(2)print(f"Percept Index: {percept_index}")print(f"Number of Rectangles: {num_rects}")# 匹配对应的框rect_match = rect_pattern.search(line)if rect_match:x1, y1, x2, y2 = map(float, rect_match.groups())# 获取颜色color = percepts_color_mapping.get(percept_index)  # 默认为红色# 绘制矩形框x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)print(x1, y1, x2, y2)cv2.rectangle(image, (x1, y1), (x2, y2), color, 2)font = cv2.FONT_HERSHEY_SIMPLEXcv2.putText(image, str(percept_index), (x1, y1 - 10), font, 0.5, color, 1, cv2.LINE_AA)# 保存包含绘制框的图像
output_image_path = 'output_image.png'
cv2.imwrite(output_image_path, image)# 保存包含绘制框的图像
output_image_path = 'output_image.png'
cv2.imwrite(output_image_path, image)

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32--WDG看门狗

文章目录 WDG简介IWDGIWDG的超时计算WWDGWWDG超时和窗口值设定独立看门狗工程WWDG工程 WDG简介 WDG看门狗&#xff08;Watchdog Timer&#xff09;是一种常见的硬件设备&#xff0c;在STM32F10系列中&#xff0c;有两种看门狗&#xff0c;分别是独立看门狗和窗口看门狗&#x…

Contextual Transformer Networks for Visual Recognition

Contextual Transformer Networks for Visual Recognition 1. 摘要2. 目的3. 网络设计 代码地址 1. 摘要 Transformer with self-attention has led to the revolutionizing of natural language processing field, and recently inspires the emergence of Transformer-style …

基于VUE的图书借阅管理系统的设计与实现

目录 一、摘要 二、技术描述 三、部分截图 四、获取方式 一、摘要 随着我国经济的高速发展&#xff0c;人们对图书的需求也愈发旺盛&#xff0c;而传统图书管理模式存在以下弊端&#xff1a;信息存储和分类操作不够高效&#xff0c;导致查找书籍困难&#xff1b;借还书流程…

Floorplanning with Graph Attention

Floorplanning with Graph Attention DAC ’22 目录 Floorplanning with Graph Attention摘要1.简介2.相关工作3.问题公式化4. FLORA的方法4.1 解决方案概述4.2 C-谱聚类算法 4.3 基于GAT的模型4.4 合成训练数据集生成 摘要 布图规划一直是一个关键的物理设计任务&#xff0…

基于SSM的网络安全宣传网站设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

笔训【day4】

目录 选择题 1、进制 格式 2、 数组名在&和sizeof后&#xff0c;表数组本身 3、求二维数组某元素地址 ​编辑 ​编辑 4、x x & (x-1) 二进制位1的个数 ​编辑 5、斐波那契递归次数 编程题 1、计算糖果 2、进制转换 选择题 1、进制 格式 十进制转二进制就除…

python sqlalchemy(ORM)- 01 简单使用

[doc] 简介 sqlalchemy 是python操作sql数据库的工具&#xff0c;是一个对象关系映射的框架&#xff1b;在python中提供高效、高性能的数据库访问&#xff0c;企业级的数据持久化模式&#xff1b;pypi 地址sqlalchemy官网 sqlalchemy架构 sql操作是独立于ORM操作的&#xf…

Hydra参数

kali的hyda参数 参数&#xff1a; hydra [[[-l LOGIN|-L FILE] [-p PASS|-P FILE]] | [-C FILE]] [-e ns][-o FILE] [-t TASKS] [-M FILE [-T TASKS]] [-w TIME] [-f] [-s PORT] [-S] [-vV] server service [OPT] -R 继续从上一次进度接着破解。 -S 采用SSL链接。 -s PORT 可通…

Outlook屏蔽Jira AI提醒

前言&#xff1a;最近不知道为什么jira上的ai小助手抽风&#xff0c;一周发个几千封邮件…导致我现在都不想在邮箱里面跟找垃圾一样找消息了。实在忍无可忍&#xff0c;决定屏蔽AI小助手&#xff0c;方法很简单&#xff0c;follow me~~ 第一步&#xff1a;双击打开电脑版Outloo…

iOS 面试题以及自我理解答案

1、简述push原理&#xff0c;push的证书和其他的有什么不一样&#xff1f; 第 一阶段&#xff1a;BeejiveIM服务器把要发送的消息、目的iPhone的标识打包&#xff0c;发给APNS。 第二阶段&#xff1a;APNS在自身的已注册Push服务 的iPhone列表中&#xff0c;查找有相应标识的iP…

vue3 组件v-model绑定props里的值,修改组件的值要触发回调

很早之前就写了&#xff0c;一直没写篇博客记录下 <select v-model"typeVal" />const emit defineEmits([update:type]); const props defineProps({type: { type: String, default: }, });const typeVal computed({get() {return props.type;},set(value…

Docker系列--镜像和容器备份与恢复的方法

原文网址&#xff1a;Docker系列--镜像和容器备份与恢复的方法_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍备份和恢复Docker镜像与容器的方法。 命令对比 保存与导出 docker save&#xff1a;保存的是镜像&#xff08;image&#xff09;。&#xff08;保存的是分层的…

关于:未同意隐私政策,应用获取ANDROID ID问题

一、环境 Unity2018 4.21f1、Android Studio、Windows10 二、问题描述 我在提交华为应用时&#xff0c;总是提示【未同意隐私政策&#xff0c;应用获取ANDROID ID个人信息】&#xff0c;但是我已经全部去掉了&#xff0c;后面问了人工客服&#xff0c;反馈了如下信息 调用堆…

【数据库——MySQL(实战项目1)】(2)图书借阅系统——数据库测试、视图以及存储过程

目录 1. 简述2. 数据表 增、删、改 测试2.1 借阅人表2.2 图书表2.3 借阅信息表 3. 功能代码3.1 创建视图显示所有逾期未归还的借阅信息&#xff08;包括借阅人姓名&#xff0c;借阅人类别&#xff0c;书名&#xff0c;借出日期&#xff0c;应归还日期&#xff0c;逾期时长&…

简单聊聊低代码

在数字经济迅速发展的背景下&#xff0c;越来越多的企业开始建立健全业务系统、应用、借助数字化工具提升管理效率&#xff0c;驱动业务发展&#xff0c;促进业绩增长。在这一过程中&#xff0c;和许多新技术一样&#xff0c;低代码&#xff08;Low-code&#xff09;开发被推上…

各种业务场景调用API代理的API接口教程

API代理的API接口在各种业务场景中具有广泛的应用&#xff0c;本文将介绍哪些业务场景可以使用API代理的API接口&#xff0c;并提供详细的调用教程和代码演示&#xff0c;同时&#xff0c;我们还将讨论在不同场景下使用API代理的API接口所带来的好处。 哪些业务场景可以使用API…

分布式系统开发技术中的CAP定理原理

分布式系统开发技术中的CAP定理原理 在分布式系统开发中&#xff0c;CAP定理&#xff08;一致性、可用性和分区容忍性&#xff09;是指导我们设计、开发和维护系统的核心原理。该定理阐述了分布式系统中一致性、可用性和扩展性之间无法同时满足的矛盾关系&#xff0c;为我们提…

沪深300期权一个点多少钱?

经中国证监会批准&#xff0c;深圳证券交易所于2019年12月23日上市嘉实沪深300ETF期权合约品种。该产品是以沪深300为标的物的嘉实沪深300ETF交易型指数基金为标的衍生的标准化合约&#xff0c;下文介绍沪深300期权一个点多少钱?本文来自&#xff1a;期权酱 一、沪深300期权涨…

安全设备和防火墙

文章目录 微步TDP态势感知防火墙防火墙的负载均衡 微步TDP态势感知 安全设备的主要功能在黑名单&#xff0c;只要记住黑名单的功能在哪即可 常用的是威胁选项卡的监控功能&#xff0c;监控模块会把实时的告警列出来&#xff0c;只要列出来就能分析流量是误报还是真实的&#x…

html与css知识点

html 元素分类 块级元素 1.独占一行&#xff0c;宽度为父元素宽度的100% 2.可以设置宽高 常见块级元素 h1~h6 div ul ol li dl dt dd table form header footer section nav article aside 行内元素 1.一行显示多个 2.不能设置宽高&#xff0c;宽高由元素内容撑开 常见行内…