关于 raw 图像的理解

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 npdef 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 frameif __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 raw10import numpy as np
import mathdef 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*heightframe = 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_outif __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.mzph.cn/news/172189.shtml

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

相关文章

IDEA出现cannot download sources解决方案

IDEA出现cannot download sources解决方案 问题描述 当我想看第三方库的源码的注释时需要下载源码。 点击Dodnload Sources后可能会出现cannot download sources的问题。 解决方案 这时我们只需在根目录下打开Terminal后执行下面一行代码 mvn dependency:resolve -Dclassi…

王者荣耀Java

代码 package com.sxt;import javax.swing.*; import java.awt.*;public class Background extends GameObject {public Background(GameFrame gameFrame) {super(gameFrame);// TODO Auto-generated constructor stub}Image bg Toolkit.getDefaultToolkit().getImage("…

notion 3.0.0 版本最新桌面端汉化教程,支持MAC和WIN版本

notion客户端汉化(目前版本3.0.0) 最近notion桌面端更新了3.0.0版本后会导致老版本汉化失效,本项目实现了最新版Notion桌面端的汉化。 文件下载地址:汉化文件下载地址 项目说明 本项目针对新的客户端做了汉化文化,依…

超实用!Spring Boot 常用注解详解与应用场景

目录 一、Web MVC 开发时,对于三层的类注解 1.1 Controller 1.2 Service 1.3 Repository 1.4 Component 二、依赖注入的注解 2.1 Autowired 2.2 Resource 2.3 Resource 与 Autowired 的区别 2.3.1 实例讲解 2.4 Value 2.5 Data 三、Web 常用的注解 3.1…

可以在Playgrounds或Xcode Command Line Tool开始学习Swift

一、用Playgrounds 1. App Store搜索并安装Swift Playgrounds 2. 打开Playgrounds,点击 文件-新建图书。然后就可以编程了,如下: 二、用Xcode 1. 安装Xcode 2. 打开Xcode,选择Creat New Project 3. 选择macOS 4. 选择Comman…

3.前端--HTML标签-文本图像链接【2023.11.25】

1.HTML常用标签(文本图像链接&#xff09; 文本标签 标题 <h1> - <h6> 段落<p> 我是一个段落标签 </p> 换行 <br /> <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta ht…

VMWare虚拟机ubuntu克隆打不开

ubuntu克隆打不开 复制的存有ubuntu克隆的文件夹&#xff0c;导入vmware打不开 说找不到这个文件&#xff0c;那就到目录把它的删掉 的删掉 换000001.vmdk后缀的

电子学会C/C++编程等级考试2021年06月(三级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:数对 给定2到15个不同的正整数,你的任务是计算这些数里面有多少个数对满足:数对中一个数是另一个数的两倍。 比如给定1 4 3 2 9 7 18 22,得到的答案是3,因为2是1的两倍,4是2个两倍,18是9的两倍。 时间限制:1000 内存限制…

使用Selenium、Python和图鉴打码平台实现B站登录

selenium实战之模拟登录b站 基础知识铺垫&#xff1a; 利用selenium进行截图&#xff1a; driver.save_screenshot() 注意图片文件名要用png结尾. 关于移动&#xff1a; ActionChains(bro).move_to_element_with_offset()# 对于某个图像ActionChains(bro).move_by_offset(…

一种LED驱动专用控制电路

一、基本概述 TM1620是一种LED&#xff08;发光二极管显示器&#xff09;驱动控制专用IC,内部集成有MCU数字接口、数据锁存 器、LED驱动等电路。本产品质量可靠、稳定性好、抗干扰能力强。主要适用于家电设备(智能热 水器、微波炉、洗衣机、空调、电磁炉)、机顶盒、电子称、…

033.Python面向对象_类补充_生命周期

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…

[NOIP2006]明明的随机数

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

【JAVA杂货铺】一文带你走进面向对象编程|继承|重载|重写|期末复习系列 | (中4)

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏:Java学习系列专栏&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 继承 私有成员变量在继承中的使用​编辑 当子类和父类变量不重名时: 当子类和父类重名时: &#x1f4dd;总结: 继承的含义: …

卷积神经网络经典backbone

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

jQuery_06 过滤器的使用

什么是过滤器&#xff1f; 过滤器就是用来筛选dom对象的&#xff0c;过滤器是和选择器一起使用的。在选择了dom对象后在进行过滤筛选。 jQuery对象中存储的dom对象顺序与页面标签声明有关系。 声明顺序就是dom中存放的顺序 1.基本过滤器 使用dom对象在数组中的位置来作为过滤条…

一网打尽异步神器CompletableFuture

Future接口以及它的局限性 我们都知道&#xff0c;Java中创建线程的方式主要有两种方式&#xff0c;继承Thread或者实现Runnable接口。但是这两种都是有一个共同的缺点&#xff0c;那就是都无法获取到线程执行的结果&#xff0c;也就是没有返回值。于是在JDK1.5 以后为了解决这…

FloodFill

"绝境之中才窥见&#xff0c;Winner&#xff0c;Winner" FloodFill算法简介: floodfill又翻译成漫水填充。我们可以将下面的矩阵理解为一片具有一定高度的坡地&#xff0c;此时突发洪水&#xff0c;洪水会将高度<0的地方填满。 话句话来说&#xff0c;Fl…

IDEA2023版本创建Sping项目只能勾选17和21,却无法使用Java8?(已解决)

文章目录 前言分析解决方案一&#xff1a;替换创建项目的源方案二&#xff1a;升级JDK版本 参考文献 前言 起因 想创建一个springboot的项目&#xff0c;本地安装的是1.8&#xff0c;但是在使用Spring Initializr创建项目时&#xff0c;发现版本只有17和21。 在JDK为1.8的情况下…

代码随想录算法训练营第四十六天【动态规划part08】 | 139.单词拆分、背包总结

139.单词拆分 题目链接&#xff1a; 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 求解思路&#xff1a; 单词是物品&#xff0c;字符串s是背包&#xff0c;单词能否组成字符串s&#xff0c;就是问物品能不能把背包装满。 动规五部曲 确定dp数…

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

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