我编写了一个应用程序,其中一些点在周围浮动,如果我为点分配一个点,它将在该位置移动。现在,我要加载图像,将其转换为单色图像(仅纯黑色或白色像素-没有灰色阴影),并使每个点浮动到代表黑色像素的位置。 我已经完成了以这种方式加载和转换图像并将像素作为一维字节[]的操作。我设法用以下代码遍历此数组:
int stride = width * 4;
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{
int index = y * stride + 4 * x;
// array[index] <- Red
// array[index + 1] <- Green
// array[index + 2] <- Blue
// array[index + 3] <- Alpha
}
字节数组保存每个具有4个字节(RGBA)的像素。因此,数组长度为ImageHeight * ImageWidth * 4个字节。像素是黑色(0、0、0、255)或白色(255、255、255、255)。
我现在的问题是,我仅用 n 个点就无法正确估计图像的黑色区域。在大多数情况下,与数组中的黑色像素相比,浮点要少得多。因此,我需要的是一种给我Point []的方法,该方法包含n个点,这些点将尽可能好地仅代表图像的黑色区域。有人可以帮我吗?
答案 0 :(得分:0)
遍历数组,找到红色,绿色和蓝色为0的点 得到黑点:
List<Point> blackPoints = new List<Points>()
for(int i=0; i<array.Length; i+=4)
if(array[i] == 0 && array[i+1] == 0 && array[i+2] ==0) //alpha is not important
{
int tmp = i / 4;
blackPoints.Add(new Point(tmp%width, tmp/width));
}
创建方法,以基于像素自身和邻居的颜色获取像素的权重,以及一种找到块的权重的方法:
public static class Exts
{
public static int Weight(this points ps, int x, int y, int width, int height)
{
int weight = 0;
for(int i=Math.Max(x - 1, 0); i<Math.Min(width, x+1))
for(int j= Math.Max(y-1, 0), j<Math.Min(height, y+1))
if(ps.Any(a => a.X == i && a.Y == j)) weight++;
return weight;
}
public static int BlockWeight(this Point[] ps, int x, int y)
{
return ps.Count(a => a.X <= x+2 && a.Y<= y+2);
}
}
现在遍历位图,使用9个像素的块(3x3),如果块的大小超过一半(在这种情况下大于或等于5),请在该块中选择权重最大的点,代表黑点:
List<Point> result = new List<Point>();
for(int i=0; i<width; i+=3)
for(int j=0; j< height; j+=3)
if(points.BlockWeight(i,j) >= 5)
result.Add(ps.Where(a => a.X <= x+2 && a.Y<= y+2).OrderByDescending(a => a.Weight(i, j, width, height)).First())