1

Ok, I need to create two arrays like this:

        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 }
        };

But with 100 items each.

I am reading the values for arrays from an image (TrainPatterns contains x and y coordinates of a pixel, TrainResults contains the color of the pixel, 0 for black, 1 for white).

I am iterating through the image like this:

        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 
                }
            }
        }

How can I add items to those arrays dynamically in the for loop? I know that image has 10px width and 10px height so I know the arrays will both have 100 length.

1
  • 2
    I just have to ask some dumb questions. 1) Why do you store every coordinate? Since the array is dense, surely you can just hold the values, with their position dictating the coordinate. 2) Why do you store each result as a single-element double[]? Couldn't you just use a double? 3) Could you use the bitmap itself as the data structure, using GetPixel and SetPixel as the accessors? 4) Alternatively, could you store the entire bitmap as two longs (with space enough for 128 bits)? Commented Nov 7, 2010 at 21:37

5 Answers 5

2

You definitely want to allocate the array before you start looping, you'll want to use the results after you're done. And you ought to do something meaningful when the pixel isn't white or black. Something like this:

        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
        //...

Not sure about the lifetime of the bitmap, you ought to call objBitmap.Dispose() somewhere. Leverage the using statement.

Sign up to request clarification or add additional context in comments.

Comments

1

Just before your for (int x = 0; x < objBitmap.Width; x++) create your array of doubles and insert into that in the forementioned loop. Then righth after the loop insert that in your TrainPatterns which you have instantiated before any of the loops.

2 Comments

You want me to show you how to instantiate an array of doubles?
Not how. Where. "Do this before that" isn't nearly as clear as a code sample.
1

Use a List<double> rather than a double[]. These can change size after they are created, and arrays cannot.

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

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

Also, I recommend you make a new structure, rather than a double array, so it is more obvious what your code is doing when you use those results:

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]
}

Comments

1

It looks like what you want to do can be easily accomplished using LINQ instead of for loops:

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();

Note that this assumes that every pixel will be either black or white.

Comments

1

Unless your data structures are subject to unusual requirements, I strongly suggest storing the bits in a 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;
    }
}

I don't know how you prefer to deal with colors that are neither black nor white, so the above code computes two bitmaps, one for the pure whites and another for the pure blacks. If you want the in-between bits, you can use var middle = black[i].Clone().Not().And(white.Clone().Not()) (I think; I have never used these methods).

Accessing bits from these bitmaps is quite simple:

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.