将 3 维字节数组转换为单字节数组 [关闭]

Posted

技术标签:

【中文标题】将 3 维字节数组转换为单字节数组 [关闭]【英文标题】:Converting 3-dimensional byte array to a single byte array [closed] 【发布时间】:2013-10-29 03:17:57 【问题描述】:

我有一个 3 维字节数组。

3-d 数组表示一个 jpeg 图像。每个通道/阵列代表 RGB 光谱的一部分。

我对保留黑色像素不感兴趣。黑色像素由这种非典型排列表示:

myarray[0,0,0] =0;
myarray[0,0,1] =0;
myarray[0,0,2] =0;

所以,我通过执行 byte[] AFlatArray = new byte[width x height x 3] 将这个 3d 数组展平为一个 1d 数组,然后为坐标分配相应的值。

但就像我说的,我不想要黑色像素。所以这个数组必须只包含 x,y 坐标的颜色像素。我想要的结果是从仅包含非黑色像素的 i 维字节数组中重新表示图像。我该怎么做?

由于 xy 坐标系,我似乎也必须存储黑色像素。我尝试写入二进制文件,但该文件的大小大于 jpeg 文件,因为 jpeg 文件被压缩。


我需要一个单字节数组,因为我有一个包含红绿色和蓝色分量的图像。我想存储两张图片之间的差异。所以,这是一个 3 暗淡的数组。由于并非所有像素都会有所不同,因此我只想存储差异。但是,即使拉平大小仍然大于图像的字节大小(因为它是 jpeg 和压缩的)。

我正在使用 emgu 图像框架。当您枚举图像的数据时,它可以为您提供 3 个通道,每个通道由字节数组中的一个维度表示。我正在使用的 3 个通道是 (R)ed、(G)reen 和 (B)lue。我可以在 HSL 或 HSV(等)的色彩​​空间中工作,然后我可以使用 3 个色相、饱和度和亮度通道。

【问题讨论】:

为什么你需要一个单字节数组,出于好奇? :) @minitech 我有一个包含红绿和蓝色分量的图像。我想存储两张图片之间的差异。所以,这是一个 3 暗淡的数组。由于并非所有像素都会有所不同,因此我只想存储差异。但是,即使拉平大小仍然大于图像的字节大小(因为它是 jpeg 和压缩的)。所以,没有人回答能解决我的问题,但他们确实回答了这个问题 我不明白两个图像之间的差异如何是一个3维数组。你的意思是一维有 3 个部分 (RGB)? @minitech 嗨,我正在使用 emgu 图像框架。当您枚举图像的数据时,它可以为您提供 3 个通道,每个通道由字节数组中的一个维度表示。我正在使用的 3 个通道是 (R)ed、(G)reen 和 (B)lue。我可以在 HSL 或 HSV(等)的色彩​​空间中工作,然后我可以使用 3 个色相、饱和度和亮度通道.. 新答案被禁止,但您可以使用Buffer.BlockCopyideone.com/ntjXuZ在一行中完成此操作 【参考方案1】:

通过将三个维度相乘来计算总大小,分配结果数组,并使用三个嵌套循环 - 每个维度一个。为输出数组中的当前位置做一个计数器;将项目放入输出数组时递增该计数器 - 如下所示:

byte[,,] threeD = new byte[X,Y,Z];
byte[] res = new byte[X*Y*Z];
int pos = 0;
for (int x = 0 ; x != X ; x++)
    for (int y = 0 ; y != Y ; y++)
        for (int z = 0 ; z != Z ; z++)
            res[pos++] = threeD[x,y,z];

【讨论】:

【参考方案2】:

如果不是jagged数组:

byte[] newArray = new byte[oldArray.Length];
for(int i = 0; i < oldArray.GetLength(0); i++) 
    for(int k = 0; k < oldArray.GetLength(1); k++) 
        for(int j = 0; j < oldArray.GetLength(2); j++) 
            int index = i * oldArray.GetLength(1) * 
                oldArray.GetLength(2) + k * oldArray.GetLength(2) + j;
            newArray[index] = oldArray[i, k, j];
        
    

或者在一个循环中:

   byte[] newArray = new byte[oldArray.Length];
   for (int i = 0; i < oldArray.Length; i++) 
       int ind3 = i % oldArray.GetLength(2);
       int ind2 = i / oldArray.GetLength(2) % oldArray.GetLength(1);
       int ind1 = i / (oldArray.GetLength(1) * oldArray.GetLength(2));
       newArray[i] = oldArray[ind1, ind2, ind3];
   

如果它是一个锯齿状数组,那么您将不知道 3D 数组中元素的确切总数,在这种情况下,我将使用一个列表,循环遍历三个维度,同时将元素添加到列表中,然后使用 List。 ToArray() 将列表转换为一维数组。

【讨论】:

哦,是的,抱歉,不知道那里发生了什么

以上是关于将 3 维字节数组转换为单字节数组 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何将字节数组转换为图片[关闭]

将 ctype 字节数组转换为字节

ValueError:无法使用 dtype='numeric' 将字节/字符串数组转换为十进制数

C 字节数组转换成字符串

将包含十六进制值的字节数组转换为十进制值

在Java中将字节[]写入文件[关闭]