好的,我需要创建两个这样的数组:
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。
答案 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. */ }