2

我有一个 3 维字节数组。

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

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

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

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

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

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


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

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

4

2 回答 2

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];
于 2013-10-20T17:59:53.887 回答
0

如果它不是锯齿状数组:

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()将列表转换为一维数组。

于 2013-10-20T18:13:12.533 回答