浅谈二维和三维图像数据
首先对于任何一个二维图像,加载入内存后都能看作一个二维像素数组。假如是一张8位图像,它的每个像素值可以用一个0~255的unsigned char表示,也就是说图像可以看成一个unsigned char的数组。假设它的长和宽分别为width和height,那么这个图像用byte B[height,width](c#二维数组)或者用unsigned char B[height][width](C++二维数组)来表示就非常的恰当。推而广之,假如是一个长宽高分别是width、height和depth的三维图像,那么就可以采用三维数组来byte B[depth,height,width](C#)或者unsigned char B[depth][height][width](C++)来表示。
由于内存地址实际上是线性的,在计算机里面多维数组都是用一维数组的方式组织的,实际上,若使用二维数组B[a][b]。对于一个长宽分别为b和a的位图B,内存中实际上是一个线性排列的布局,也就是说计算机会把一个二维数组看成是数组的数组,一个三维的数组就是数组的数组的数组。例如二维数组unsigned char B[height][width] ,内存中的就是height个长度为width的数组,那么假如数组的初始地址为B,那么B[i][j]的实际存储位置是在i个width后面再加j个位置。所以我们若把二维数组一维化,我们可以把B声明为一个一维数组 unsigned char B[width*height],当我们取第i行j列的像素的时候,就使用B[i*width+j]这个表达式。
这里有一个问题,为什么要讨论二维和三维图像的一维化,直接使用多维数组行吗?其实图像都统一使用一维数组的表达方式,很大程度是因为IO原因。因为对于一张位图,或者是.raw格式的无压缩图像,在读取图像的时候都是使用一维数组作为缓冲区(比如c语言的fread函数 size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) 中的buffer就是个一维数组)那么将图像文件读为一维数组后,一般为了避免不必要的开销,就不会再把这个数组的值按位置一一复制到一个二维数组去,而是直接使用这个一维数组。实际上,使用二维、三维数组作为二维、三维图像的存储结构也完全没有问题。只是在遇到这两种不同方式的时候,记住二维的B[j][i]对应于一维的B[i*width+j],三维的B[k][j][i]对应于一维的B[i+j*width+k*width*height]即可。
下面的代码是用C++封装了二维或三维图像的相关属性、方法和数据。可以看出,图像最基本要有长宽高这些表示尺寸的属性,然后需要一个表示像素类型的类别PixelType。对于8位图像,一般使用char或 unsigned char表示像素类型。对于16位或者32位图像,既可以用C++语言相应长度的short和int/float变量来表示,也可以声明一个新结构体,由若干个char或unsigned char成员来组成。使用结构体也是比较常用的方法,比如对于ARGB图像而言使用的PixelType是一个有四个unsigned char成员的结构体,这样这四个成员能分别表示对应的颜色的A、R、G、B分量。图像结构体中当然还必须有指向图像数据的指针*B,同时还要提供存取像素的方法。
#define T PixelType struct Bitmap2D {T *B;int width;int height;void SetPixel(int,int,T);T GetPixel(int,int); } struct Bitmap3D {T *B;int width;int height;int depthvoid SetPixel(int,int,int,T);T GetPixel(int,int,int); }
综合以上所述,对于二维图像j行i列的像素的操作的伪代码如下:
GetPixel(i,j)return B[i+width*j]SetPixel(i,j,v)B[i+width*j]=v
三维图像k层j行i列的像素存取方式如下:
GetPixel(i,j,k)return B[i+width*j+width*height*k]SetPixel(i,j,k,v)B[i+width*j+width*height*k]=v
附 三维图像
二维图像在平时使用计算机的时候比较常见,相比之下三维图像一般只出现在专业图像领域。对于三维图像可以有很多表现形式,比如图像序列(N张大小一样的二维图),RAW体数据(三维数组文件)等。如本文用作测试的三维图像Lobster.raw数据,来自www.volvis.org,是用CT扫描产生56张宽301高324的图片然后组合在一起的。内部的值偏大的像素集合组成一个三维的龙虾形状。
不像二维图片能直接完整的在屏幕上显示,想观察三维图像的内容一般得采用特别的办法。一种是观察某一维切片,比如如下的图就是lobster数据分别在Z轴上取5-10-15-....-55的切片制作的动态图。
用体绘制软件ParaView可以用体绘制技术直接在3D场景中观察三维图片的内容:
附2:三维图像的IO
三维图像经常会以.raw文件的形式提供,例如www.volvis.org上的所有sample,解压后都是一个.raw文件。Raw文件其实是存图像最简单的方式,是一种对图像无压缩的存储。实际上,这种格式就是把图像一维化的数组存储成文件,所以可以轻易的写出读取Raw文件的代码。不过由于这个文件不带自描述信息,所以在读的时候一定要清楚所读的文件是多少位的图像,长宽高是多少。例如上图所展示的lobster数据。从数据描述中可知其大小为301×324×56,8位,所以采用C++语言将其读为unsigned char数组的代码如下:
void InitArrayFromVolFile(unsigned char * &data,const char* fileName,int length) {long dataSize = length;std::FILE* file = fopen(fileName,"rb");if( file == NULL ){printf("open the file failed\n");}fread( data,sizeof(unsigned char),dataSize,file );fclose(file); }
再将其输出为文件的代码如下,都是比较简单的读写调用,由此同时可以看出,无论是2维还是3维图像,使用一维数组的方式存数据,对于IO来说是十分方便。
void OutPutVolume(const char* fileName,unsigned char* pointer,int width,int height,int depth) { int length=width*height*depth;FILE *const nfile = fopen(fileName,"wb");fwrite(pointer,sizeof(unsigned char),length,nfile);fclose(nfile); }
前段时间需要找各种三维图像来做实验,发现这个www.volvis.org及其不稳定,时不时就是服务器关闭了,这样会导致需要数据的时候比较麻烦,所以这里干脆把一些常用的数据下来到博客园贴着,以防不时之需。
数据预览 | 数据参数 | 数据描述 |
Aneurism
256x256x256 |
Rotational C-arm x-ray scan of the arteries of the right half of a human head. A contrast agent was injected into the blood and an aneurism is present. http://pan.baidu.com/s/1hqeHkXY |
|
Backpack Scan 16Bits (12bits set) 512 x 512 x 373 0.9766, 0.9766, 1.25 |
CT scan of a backpack filled with items. http://pan.baidu.com/s/1pJO4hwJ |
|
Bonsai
256x256x256 |
CT scan of a bonsai tree. http://pan.baidu.com/s/1sjPfZhr |
|
Boston Teapot
256x256x178 |
CT scan of the SIGGRAPH 1989 teapot with a small version of the AVS lobster inside. http://pan.baidu.com/s/1qWlS0SO |
|
Colon Phantom 8Bits 512 x 512 x 442 0.9316, 0.9316, 0.5 |
CT scan of a Colon phantom with several different objects and five pedunculated large polyps in the central object. http://pan.baidu.com/s/1eQgNj6y |
|
Engine
256x256x128 |
CT scan of two cylinders of an engine block. http://pan.baidu.com/s/1dDoWEY1 |
|
Foot
256x256x256 |
Rotational C-arm x-ray scan of a human foot. Tissue and bone are present in the dataset. http://pan.baidu.com/s/1hqHWORi |
|
Lobster
301x324x56 |
CT scan of a lobster contained in a block of resin. http://pan.baidu.com/s/1gdKaIo7 |
|
Head MRI CISS 8Bits (8bits set) 256 x 256 x 124 0.9, 0.9, 0.9 |
1.5T MRT 3D CISS dataset of a human head that highlights the CSF (Cerebro-Spinal-Fluid) filled cavities of the head. http://pan.baidu.com/s/1dD67C7R |
|
Neghip
64x64x64 |
Simulation of the spatial probability distribution of the electrons in a high potential protein molecule. http://pan.baidu.com/s/1sjxvEJr |
|
Colon Prone 8Bits 512 x 512 x 463 0.625, 0.625, 1.0 |
CT scan of abdomen in prone orientation (back faces ceiling, belly faces table. http://pan.baidu.com/s/1jGA1kvO |
|
Silicium
98x34x34 |
Simulation of a silicium grid. http://pan.baidu.com/s/1pcKQ6 |
|
Skull
256x256x256 |
Rotational C-arm x-ray scan of phantom of a human skull. http://pan.baidu.com/s/1hqqS0tQ |
浅谈二维和三维图像数据相关推荐
- python读取图像数据流_浅谈TensorFlow中读取图像数据的三种方式
本文面对三种常常遇到的情况,总结三种读取数据的方式,分别用于处理单张图片.大量图片,和TFRecorder读取方式.并且还补充了功能相近的tf函数. 1.处理单张图片 我们训练完模型之后,常常要用图片 ...
- MATLAB3 二维和三维图像的绘制
这篇文章是我在B站上跟随up主ln异教徒学习时根据其讲的内容和我的理解实践做的笔记,视频原地址如下 数学建模最新教程[0基础]_哔哩哔哩_bilibili 一维的情况y被当做纵坐标 当a是一个行向量或 ...
- ML之DR:基于鸢尾花(Iris)数据集利用多种降维算法(PCA/TSVD/LDA/TSNE)实现数据降维并进行二维和三维动态可视化应用案例
ML之DR:基于鸢尾花(Iris)数据集利用多种降维算法(PCA/TSVD/LDA/TSNE)实现数据降维并进行二维和三维动态可视化应用案例 目录 基于鸢尾花(Iris)数据集利用多种降维算法(PCA ...
- MATLAB学习笔记——二维和三维绘图
MATLAB学习笔记--二维和三维绘图 近期练习matlab的二维和三维绘图,整理一下,以防忘记. 文章目录 MATLAB学习笔记--二维和三维绘图 一.二维绘图 1.plot命令 2.fplot 命 ...
- matlab三维选取二维,基于Matlab绘制二维和三维图形以及其他图形控制函数的使用方法...
Matlab绘图 强大的绘图功能是Matlab的特点之一,Matlab提供了一系列的绘图函数,用户不需要过多的考虑绘图的细节,只需要给出一些基本参数就能得到所需图形,这类函数称为高层绘图函数.此外,M ...
- 嵌入式AI —— 6. 为糖葫芦加糖,浅谈深度学习中的数据增广
没有读过本系列前几期文章的朋友,需要先回顾下已发表的文章: 开篇大吉 集成AI模块到系统中 模型的部署 CMSIS-NN介绍 从穿糖葫芦到织深度神经网络 又和大家见面了,上次本程序猿介绍了CMSIS- ...
- 二维和三维CAD设计Autodesk AutoCAD 2021
Autodesk AutoCAD 2021 是一款Autodesk公司发布的非常强大的二维和三维CAD设计软件.用于二维绘图.详细绘制.设计文档和基本三维设计,现已经成为国际上广为流行的绘图工具.具有 ...
- 二维和三维CAD设计Autodesk AutoCAD中文2021/2022/2023
Autodesk AutoCAD 是全球著名的专业计算机辅助设计软件,用于二维绘图.详细绘制.设计文档和基本三维设计,广泛应用于机械设计.工业制图.工程制图.土木建筑.装饰装潢.服装加工等多个行业领域 ...
- MATLAB 的绘图:二维和三维
本节介绍MATLAB 的两种基本绘图功能:二维平面图形和三维立体图形. 5.1 二维平面图形 5.1.1 基本图形函数 plot 是绘制二维图形的最基本函数,它是针对向量或矩阵的列来绘制曲线的.也就是 ...
最新文章
- 事件标志组的删除与状态查询
- linux kernel中的cmdline的详细介绍
- Spring中如何使用注解来配置Bean?有哪些相关的注解?
- JVM初学之堆的内存模型
- 【重难点】【Java集合 01】HashMap 和 ConcurrentHashMap
- ubuntu16 下 源码配置Lnmp环境
- JSP标签JSTL(3)--迭代操作
- python写彩票程序30选7_写一个彩票程序:30选7
- 微商爆粉2.0全自动批量加人模拟手动操作
- linux zip文件解压命令详解
- Jenkins下载安装
- python编程中的不等于符号_python不等于符号怎么写
- ArcGIS裁剪栅格图像(图片)后,图…
- (bilibili)b站看不见视频评论区或不显示高级弹幕
- Dos界面telnet命令的基本使用
- 【暑期每日一题】洛谷 P1551 亲戚
- 分部积分法的快速运算 表格法
- 【 C++ 技术】 C++ 高性能服务器网络框架设计细节
- 优麒麟服务器配置备忘
- 一篇相当不错的js function详解 读了一定有收获