来自字节数组的近似图像

时间:2018-11-11 18:56:26

标签: c# arrays image

我编写了一个应用程序,其中一些点在周围浮动,如果我为点分配一个点,它将在该位置移动。现在,我要加载图像,将其转换为单色图像(仅纯黑色或白色像素-没有灰色阴影),并使每个点浮动到代表黑色像素的位置。 我已经完成了以这种方式加载和转换图像并将像素作为一维字节[]的操作。我设法用以下代码遍历此数组:

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个点,这些点将尽可能好地仅代表图像的黑色区域。有人可以帮我吗?

1 个答案:

答案 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())