我有一个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文件。
我需要一个单字节数组,因为我的图像有红绿色和蓝色组件。我想存储2张图片之间的差异。所以,这是一个3昏暗的阵列。由于并非所有像素都不同,我只想存储差异。但是,即使缩小尺寸仍然大于图像的字节大小(因为它是jpeg和压缩)。
我正在使用emgu图像框架。当您枚举图像数据时,它可以为您提供3个通道,每个通道由字节数组中的维度表示。我正在使用的3个频道是(R)ed,(G)reen和(B)lue。我可以在HSL或HSV(等)的色彩空间工作,然后我可以使用3个色调,饱和度和亮度通道。
答案 0 :(得分: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];
答案 1 :(得分:0)
如果它不是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()将列表转换为一维数组。