2010-11-07 4 views
1

Ок, мне нужно создать два массива, как это:Как создать массив в цикле

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

Как я могу добавлять элементы в этих массивы динамически для цикла? Я знаю, что изображение имеет ширину 10 пикселей и высоту 10 пикселей, поэтому я знаю, что у массивов будет длина 100.

+2

Я просто задать несколько глупых вопросов. 1) Почему вы сохраняете каждую координату? Поскольку массив плотный, вы можете просто удерживать значения, причем их положение диктует координату. 2) Почему вы сохраняете каждый результат как одноэлементный 'double []'?Не могли бы вы просто использовать «двойник»? 3) Не могли бы вы использовать битмап в качестве структуры данных, используя GetPixel и SetPixel в качестве аксессуаров? 4) В качестве альтернативы вы могли бы сохранить весь битмап в виде двух длин (с достаточным пространством для 128 бит)? –

ответ

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

Как раз перед тем, как ваш for (int x = 0; x < objBitmap.Width; x++) создаст ваш массив двойников и вставьте в него в описанном цикле. Затем вправо после петли вставьте это в свой TrainPatterns, который вы создали до любого из циклов.

+0

Пример кода был бы очень полезен здесь ... –

+0

Вы хотите, чтобы я показал вам, как создать экземпляр массива двойников? –

+0

Не так. Где. «Делать это до этого» не так ясно, как образец кода. –

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

Обратите внимание, что это предполагает, что каждый пиксель будет белым или черным.

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. */ } 
Смежные вопросы