关于 raw 图像的理解

news2024/11/30 13:42:13

1、问题背景

在图像调试过程,当发现一个问题时,很多时候都要通过 dump raw图像来分析,如果raw图像上有,那就排除了是 ISP的处理导致。

下一步就是排查 sensor 或者镜头,这样可以有效的帮我们定位问题所在。

但遇到过有些 raw, 用工具打不开或者出图不对的情况,那可能是因为 raw 的存储格式不同导致,本文主要对 raw 的格式做下介绍说明。

2、问题分析

a. 什么是 raw

raw 数据是 sensor 输出的原始数据,常用的一般有raw8, raw10, raw12等,分别表示一个像素点有 8bit、10bit、12bit 数据。

是 sensor 将光信号转化为电信号时的电平高低的原始记录,单纯地没有进行任何处理的图像数据,即表现的是 sensor 和镜头本征特性的数据。

raw 数据在输出的时候是有一定顺序的,主要有四种: GRBG、RGGB、BGGR、GBRG,如下图为BGGR格式:

b. raw 分哪几种格式,有什么区别 ?

raw 一般分为 plain raw 和 mipi raw,主要是存储方式上的区别,如下图所示是 Plain raw10 的示意图。

10bit的raw,单个像素也就是10bit,需要两个字节(16bit)来存储。

那就会空出 6位用不到,因为有空余,这里就涉及到一个高位/低位对齐的问题,也就是存储数据时,右移6位低位对齐(如下图1所示),

左移6位高位对齐(如下图2所示)。这个主要看平台厂商对数据处理有什么要求,我司用的是高位对齐的数据,所以读取时,要有相应的移位操作才行。

如下图所示是 mipi raw10 的示意图,以大端存储方式为例,它是把4个像素放到5个字节(40bit)中,组成一个包去存储。

前4字节依次存放 raw10图像的前4个像素的后8位,4个像素的前2位依次存放在包的第5个字节中。

所以从存储方式来看,mipi raw 的存储方式是要比 plain raw 更节省内存。

c. 怎么正确查看 raw ?

一般raw图工具打开都会要求配置一下 raw 图尺寸、位宽、bayer格式、MSB/LSB,

但一般工具支持 plain raw 打开的居多,还有些并不支持MSB和LSB的选择,所以需要我们对raw 做一下处理。

如下是mipi raw 转 plain raw 、plain raw10 MSB 转LSB 的相关 python 代码,

分析代码的处理过程,也会加深我们关于raw图像的理解,

如下代码中使用的raw图像,可以在此链接获取:

https://pan.baidu.com/s/1H-s0YDcJCmeMxVKTTa3N6g?pwd=bxm9

提取码:bxm9

# plain raw10 的读取和 MSB转LSB的处理

import numpy as np

def read_plained_file(file_path_name,height,width,shift_bits):
    frame = np.fromfile(file_path_name, dtype="uint16")
    frame=frame[0:height*width]
    frame.shape = [height, width]

    # MSB ----> LSB,  LSB存低位数据,此时是高位对齐的,则右移代表向低位移了6位,数值是减小的状态。
    frame=np.right_shift(frame, shift_bits)  
    return frame

if __name__ == "__main__":
    file_name = "ov13b10_shading_4208X3120_MSB.raw"
    image = read_plained_file(file_name, 3120, 4208, 6)
    image = image / 1023

    # 将读取的 image 数据另存为 raw 数据
    output_file_name = "output_image.raw"

    # 将图像数据映射到 16 位无符号整数范围
    image_mapped = (image * 1023).astype('uint16')
    image_mapped.tofile(output_file_name)
    print(f"Image data has been saved to {output_file_name}")
# mipi raw10 转 plain raw10

import numpy as np
import math

def read_mipi10_file(file_path_name,height,width):
    # 单行长度的补齐
    new_width = int(math.floor((width + 3) / 4) * 4) #对四字节补齐
    packet_num_L = int(new_width / 4)
    width_byte_num = packet_num_L * 5 #单行byte长度
    width_byte_num = int(math.floor((width_byte_num + 7) / 8) * 8)#单行做8个字节补齐
    image_bytes=width_byte_num*height
    frame = np.fromfile(file_path_name, count=image_bytes,dtype ="uint8")
    print("b shape",frame.shape)
    print('%#x'%frame[0])

    frame.shape = [height, width_byte_num] #按字节整理的图像矩阵
    one_byte = frame[:,0:image_bytes:5]
    two_byte = frame[:,1:image_bytes:5]
    three_byte = frame[:,2:image_bytes:5]
    four_byte = frame[:,3:image_bytes:5]
    five_byte = frame[:,4:image_bytes:5]

    #数据转换防止溢出
    one_byte = one_byte.astype('uint16')
    two_byte = two_byte.astype('uint16')
    three_byte = three_byte.astype('uint16')
    four_byte = four_byte.astype('uint16')
    five_byte = five_byte.astype('uint16')

    #用矩阵的方法进行像素的拼接
    one_byte = np.left_shift(one_byte, 2) + np.bitwise_and((five_byte), 3)
    two_byte = np.left_shift(two_byte, 2) + np.right_shift(np.bitwise_and((five_byte), 12), 2)
    three_byte = np.left_shift(three_byte, 2) + np.right_shift(np.bitwise_and((five_byte), 48), 4)
    four_byte = np.left_shift(four_byte, 2) + np.right_shift(np.bitwise_and((five_byte), 192), 6)

    #重组帧
    frame_pixels=np.zeros(shape=(height,new_width))
    frame_pixels[:, 0: new_width:4]=one_byte[:, 0: packet_num_L]
    frame_pixels[:, 1: new_width:4]=two_byte[:, 0: packet_num_L]
    frame_pixels[:, 2: new_width:4]=three_byte[:, 0: packet_num_L]
    frame_pixels[:, 3: new_width:4]=four_byte[:, 0: packet_num_L]

    #裁剪无用的数据,这里表示的是0-2559列,包含完整的数据了。
    frame_out=frame_pixels[:,0:width]
    return frame_out

if __name__ == "__main__":
    file_name="imx335_2560x1440_GRBG_mipi.raw"
    image=read_mipi10_file(file_name,1440, 2560)
    image=image/1023

    # 将读取的 image 数据另存为 raw 数据
    output2_file_name = "output2_image.raw"
    # 将图像数据映射到 16 位无符号整数范围
    image_mapped = (image * 1023).astype('uint16')
    image_mapped.tofile(output2_file_name)
    print(f"Image data has been saved to {output2_file_name}")

参考资料:

大话成像-数字成像算法基础课程

 

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

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

相关文章

成为AI产品经理——TPR、FPR、ROC、AUC

目录 一、PR图、BEP 1.PR图 2.BEP 二、灵敏度、特异度 1.灵敏度 2.特异度 三、真正率、假正率 1.真正率 2.假正率 三、ROC、AUC 1.ROC 2.AUC 四、KS值 一、PR图、BEP 1.PR图 二分类问题模型通常输出的是一个概率值,我们需要设定一个阈值&#xff…

P16 C++构造函数

目录 前言 01 什么是构造函数呢? 02 非构造函数初始化变量 03 构造函数初始化变量 04 带参数的构造函数。 最后的话 前言 我们继续学习 C 的面向对象编程,本章主要是讲其中的 构造函数。 01 什么是构造函数呢? 构造函数基本上是一种特…

2023年最新Visual Studio下载安装以及C语言环境搭建教程(含C语言入门教程)

文章目录 写在前面C语言简介Visual Studio简介Visual Studio安装教程 C语言入门Visual Studio使用教程 写在后面 写在前面 2023年最新Visual Studio下载安装以及C语言环境搭建教程来啦!一起来看看吧~ C语言简介 C语言是一种高级编程语言,由美国贝尔实…

卷积神经网络经典backbone

特征提取是数据分析和机器学习中的基本概念,是将原始数据转换为更适合分析或建模的格式过程中的关键步骤。特征,也称为变量或属性,是我们用来进行预测、对对象进行分类或从数据中获取见解的数据点的特定特征或属性。 1.AlexNet paper&#…

NX二次开发UF_CURVE_ask_wrap_curve_parents 函数介绍

文章作者:里海 来源网站:https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_ask_wrap_curve_parents Defined in: uf_curve.h int UF_CURVE_ask_wrap_curve_parents(tag_t curve_tag, tag_t * defining_face, tag_t * defining_plane, tag_t * defin…

【单调栈】子数组的最小值之和

import java.util.Deque; import java.util.LinkedList;/** 参考链接:https://leetcode.cn/problems/sum-of-subarray-minimums/solutions/1930857/gong-xian-fa-dan-diao-zhan-san-chong-shi-gxa5/* https://leetcode.cn/problems/sum-of-subarray-minim…

gitee仓库使用教程

下载安装git;在本地项目文件夹右击鼠标点击Git Bash Here;输入git init,这个目录变成git可以管理的仓库,会出现一个.git文件夹,如果没出现的话需要选择“显示隐藏文件”(不会的同学自行百度一下) 4.绑定本地…

Figma 插件学习(二)- 常用属性和方法

一. 如何调试figma插件 Plugins > Development > Show/Hide console 打开控制台即可开始调试 二.节点类型 根据不同的节点类型,也是会有不同的方法和属性,介绍几个常用节点类型 1.FrameNode 框架节点是用于定义布局层次结构的容器。它类似于HTM…

高校大学校园后勤移动报修系统 微信小程序uniapp+vue

本文主要是针对线下校园后勤移动报修传统管理方式中管理不便与效率低的缺点,将电子商务和计算机技术结合起来,开发出管理便捷,效率高的基于app的大学校园后勤移动报修app。该系统、操作简单、界面友好、易于管理和维护;而且对后勤…

弹窗concrt140.dll丢失的解决方法,深度解析concrt140.dll丢失的原因

在计算机使用过程中,我们经常会遇到一些错误提示或者系统崩溃的情况。其中,concrt140.dll是一个常见的错误提示,这个错误通常会导致某些应用程序无法正常运行。为了解决这个问题,本文将介绍5种详细的解决方法,帮助您恢…

I/O多路转接之epoll

承接上文 I/O多路转接之poll-CSDN博客 简介 epoll的相关系统调用 epoll底层原理 编写epoll的server 重新回归一下epoll原理,LT,ET epoll改成ET工作模式 -- 初识(有bug) epoll初识 按照man手册的说法: 是为处理大批量句柄而作了改进的poll. 它是在2.5.4…

所有网站文本复制方法(知网、百度文库等)

实现文字复制自由 在肝学校结课论文是发现要用的论文文字都无法复制,所以想到了以前学到的一个方法,开始忘了,突然想起来,现在记录一下。 拿我现在肝的课程结课论文为例: 方法一 在谷歌浏览器的网址前面有一个列表一…

WebSocket了解

一.什么是WebSocket WebSocket是HTML5下一种新的协议(websocket协议本质上是一个基于tcp的协议)它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的Websocket是一个持久化的协议 二.websocket的原理 web…

持续集成部署-k8s-配置与存储-存储类:动态创建NFS-PV案例

动态创建NFS-PV案例 1. 前置条件2. StorageClass 存储类的概念和使用3. RBAC 配置4. storageClass 配置5. 创建应用,测试 PVC 的自动配置6. 解决 PVC 为 Pending 状态问题7. 单独测试自动创建 PVC 1. 前置条件 这里使用 NFS 存储的方式,来演示动态创建 …

[NOIP2006]明明的随机数

一、题目 登录—专业IT笔试面试备考平台_牛客网 二、代码 set去重,再利用vector进行排序 std::set是一个自带排序功能的容器,它已经按照一定的规则(默认是元素的小于比较)对元素进行了排序。因此,你不能直接对std::s…

2.5 逆矩阵

一、逆矩阵的注释 假设 A A A 是一个方阵,其逆矩阵 A − 1 A^{-1} A−1 与它的大小相同, A − 1 A I A^{-1}AI A−1AI。 A A A 与 A − 1 A^{-1} A−1 会做相反的事情。它们的乘积是单位矩阵 —— 对向量无影响,所以 A − 1 A x x A^{…

【挑战业余一周拿证】一、亚马逊云科技简介 - 第 2 节 - 模块 简介

CSDN 官方中文视频(免费):点击进入 第 2 节 - 模块 1 简介 这门课程将为您提供需要了解的所有重要信息,让您能够轻松讨论亚马逊云科技并了解它为 何对您的企业有利 亚马逊云科技为每个企业都提供了非常广泛的服务,从…

Vscode工具使用指南

通用 快捷键文件 / 编辑查找 / 替换窗口插件主题 连接linux 快捷键 文件 / 编辑 新建文件:CtrlN放大或缩小:Ctrl /-代码行缩进,展开:Ctrl[ 和 Ctrl]在当前行下方插入一行:CtrlEnter在当前行上方插入一行:…

Springboot+vue的客户关系管理系统(有报告),Javaee项目,springboot vue前后端分离项目

演示视频: Springbootvue的客户关系管理系统(有报告),Javaee项目,springboot vue前后端分离项目 项目介绍: 本文设计了一个基于Springbootvue的前后端分离的客户关系管理系统,采用M&#xff08…

常见的1/2/3位数码管接线详解

今天玩数码管的时候接触到了数码管的接线,分享一下供刚开始接触的童鞋参考 首先了解什么是数码管 数码管是一种可以显示数字和其他信息的电子设备,是显示屏其中一类, 通过对其不同的管脚输入相对的电流,会使其发亮,从而…