如何在for循环中创建数组

时间:2010-11-07 21:26:07

标签: c#

好的,我需要创建两个这样的数组:

        double[][] TrainPatterns = { 
            new double[] { 0.0, 0.0 },
            new double[] { 0.0, 1.0 },
            new double[] { 0.0, 2.0 }
        };
        double[][] TrainResults = {
            new double[] { 0.0 },
            new double[] { 1.0 },
            new double[] { 1.0 }
        };

但每件都有100件。

我正在从图像中读取数组的值(TrainPatterns包含像素的x和y坐标,TrainResults包含像素的颜色,0表示黑色,1表示白色)。

我正在迭代这样的图像:

        Bitmap objBitmap = new Bitmap("im.bmp");
        for (int y = 0; y < objBitmap.Height; y++)
        {
            for (int x = 0; x < objBitmap.Width; x++)
            {
                // here I need to insert new double[] { (double)x, (double)y } to the
                // TrainPatterns array
                Color col = objBitmap.GetPixel(x, y);
                if (col.R == 255 && col.G == 255 && col.B == 255)
                {
                    // white color
                    // here I need to insert new double[] { 1.0 } to the
                    // TrainResults 
                }
                if (col.R == 0 && col.G == 0 && col.B == 0)
                {
                    // black color
                    // here I need to insert new double[] { 0.0 } to the
                    // TrainResults 
                }
            }
        }

如何在for循环中动态地向这些数组中添加项?我知道图像的宽度为10px,高度为10px,所以我知道阵列的长度都是100。

5 个答案:

答案 0 :(得分:2)

你肯定想在开始循环之前分配数组,你需要在完成后使用结果。当像素不是白色或黑色时,你应该做一些有意义的事情。像这样:

        Bitmap objBitmap = new Bitmap("im.bmp");
        double[][] array = new double[objBitmap.Height][];
        for (int y = 0; y < objBitmap.Height; y++) {
            array[y] = new double[objBitmap.Width];
            for (int x = 0; x < objBitmap.Width; x++) {
                Color col = objBitmap.GetPixel(x, y);
                if (col == Color.White) array[y][x] = 1.0;
                else if (col == Color.Black) array[y][x] = 0.0;
                else array[y][x] = 0.5;  // whatever
            }
        }
        // Do something with array
        //...

不确定位图的生命周期,你应该在某处调用objBitmap.Dispose()。利用使用语句。

答案 1 :(得分:1)

for (int x = 0; x < objBitmap.Width; x++)创建你的双打数组之前,插入前面提到的循环中。然后在循环插入后,在TrainPatterns中插入任何循环之前已经实例化的循环。

答案 2 :(得分:1)

使用List<double>而不是double[]。这些可以在创建后更改大小,而数组则不能。

var trainResults = new List<double[]>();

for(int y = 0; ...)
{
    for(int x = 0; ...)
    {
        if(colors match...)
        {
            trainResults.Add(new double[] { x, y });
        }
        // etc...
    }
}

另外,我建议您创建一个新结构,而不是双数组,因此当您使用这些结果时,代码正在做什么更为明显:

class TrainResult
{
    TrainResult(int x = 0; int y = 0)
    {
        this.X = x;
        this.Y = y;
    }

    public int X;
    public int Y;
}

// ...

for(int y = 0; ...)
    for(int x = 0; ...)
        if(match ...)
            trainResults.Add(new TrainResult(x, y));

// ...

foreach(TrainResult result in trainResults)
{
    // Do something with result.X, result.Y.
    // This is more obvious than result[0], result[1]
}

答案 3 :(得分:1)

看起来您可以使用LINQ而不是for循环轻松完成您想要做的事情:

Bitmap objBitmap = new Bitmap("im.bmp");
var TrainPattern = (from y in Enumerable.Range(0, objBitmap.Height)
                    from x in Enumerable.Range(0, objBitmap.Width)
                    select new double[] { x, y }).ToArray();
var TrainResults = (from y in Enumerable.Range(0, objBitmap.Height)
                    from x in Enumerable.Range(0, objBitmap.Width)
                    let col = objBitmap.GetPixel(x, y)
                    select (col.R == 255 && col.G == 255 && col.B == 255) ?
                            new[] { 1.0 } : new[] { 0.0 }).ToArray();

请注意,这假设每个像素都是黑色或白色。

答案 4 :(得分:1)

除非您的数据结构受到不寻常的要求,否则我强烈建议将这些位存储在BitArray中:

Bitmap objBitmap = new Bitmap("im.bmp");
var white = new BitArray(objBitmap.Width*objBitmap.Height);
var black = new BitArray(objBitmap.Width*objBitmap.Height);
for (int y = 0, i = 0; y < objBitmap.Height; ++y)
{
    for (int x = 0; x < objBitmap.Width; ++x, ++i)
    {
        Color c = objBitmap.GetPixel(x, y);
        white[i] = c.R == 255 && c.G == 255 && c.B == 255;
        black[i] = c.R == 0 && c.G == 0 && c.B == 0;
    }
}

我不知道你更喜欢处理既不是黑色也不是白色的颜色,所以上面的代码计算两个位图,一个用于纯白色,另一个用于纯黑色。如果你想要中间位,你可以使用var middle = black[i].Clone().Not().And(white.Clone().Not())(我认为;我从未使用过这些方法)。

从这些位图访问位非常简单:

if (white[x + objBitmap.Width*y]) { /* The pixel at (x, y) is white. */ }