2011-10-11 69 views
0

我正在研究图形应用程序,用户可以在画布上绘制任意数量的线(从点A到点B有一定的粗细),矩形或椭圆。计算形状的绘制图像中的独特像素

完成后,我有一组形状数据表明每个形状和线条的位置,我需要确定它们作为研究项目的一部分着色了多少个独特像素。

我的幼稚算法是为每个形状实现bool shape.Contains(x,y),并针对图像中每个像素的每个绘制形状调用它以确定该像素是由直线,矩形还是椭圆绘制的。

以另一种方式工作,我可以创建void shape.SetPixels(bool [,] canvas),并将每个形状设置为true,它包含每个像素。这是我实际上实现的,并且对于大型数据集来说,它非常缓慢。

我有一种感觉,有一种更直接的方式去从原始形状数据到我需要的输出,而不需要检查每个像素。所以我的问题是,给定一组形状数据,是否有一个O(n)函数bool [,] IsColored(int x,int y){},它可以比任何一个更直接地生成彩色像素的真/假的矩阵我给出的想法?

+2

如果你画它呢?由此产生的位图本质上就是这样一个矩阵 – harold

+0

O(n)是什么意思?实现shape.Contains(x,y)并为每个形状调用一次是O(n),其中n是形状的数量。 – jwd

+0

为什么不能形状只返回它包含的像素集? – Magnus

回答

1

你说的两种方法通常是你的两个主要选项。根据需要检查每个像素,或者预先为快速查找构建某种数据结构。如果你有一个大的画布,但只有几个形状(因此,相对较少的“开”像素),那么最好记录任何形状的任何像素,例如散列。

HashSet<KeyValuePair<int,int>> listOfPixelsHitByAnyShape = new HashSet() 

foreach(Shape s in allShapes) 
{ 
    s.Draw(listOfPixelsHitByAnyShape); // will update listOfPixelsHitByAnyShape 
} 

// Now we can easily query if a pixel is set 
bool isSet = listOfPixelsHitByAnyShape.Contains(new KeyValuePair(10,99)) 

这应该是快速查找,代价是内存和构建HashSet的时间。

但它不会像你的SetPixels(bool[,] canvas)版本一样快,也不会使用更多的内存(在我们所讨论的稀少情况下)。

0

如果你不使用图形库,请,请!


如果它是一个图形应用程序,假设您已经绘制了用户输入的内容。你难道不能查询吗?您总是可以绘制2个不同的目标,一个用于漂亮的用户版本,另一个用于查询(每个对象都是独特的颜色)。

你想如何处理重叠?


我们说的数据集有多大?渲染应该是“免费的”,因为可以在用户在应用程序中绘制时构建位图。

如果你所做的事情真的很慢,你可以考虑使用GPU绘制和查询(可能使用奇特的着色器)。

2

避免使用Bitmap.GetPixel方法。这是很慢很慢。如果可能,您可以使用LockBits或类似技术对位图数据进行低级访问。

在我的项目之一,我用:

public void LoadFromBitmap(Bitmap bmp) 
    { 
     if (bmp.Width != Width || bmp.Height != Height) 
      throw new ArgumentException("Size missmatch"); 
     unsafe 
     { 
      BitmapData bmpData = null; 
      try 
      { 
       bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); 

       for (int y = 0; y < bmpData.Height; y++) 
       { 
        uint* p = (uint*)((byte*)bmpData.Scan0 + y * bmpData.Stride); 
        for (int x = 0; x < bmpData.Width; x++) 
        { 
         this[x, y] = RawColor.FromARGB(*p); 
         p++; 
        } 
       } 
      } 
      finally 
      { 
       if (bmpData != null) 
        bmp.UnlockBits(bmpData); 
      } 
     } 
    } 

https://github.com/CodesInChaos/ChaosUtil/blob/master/Chaos.Image/Pixels.cs

另一种优化正在实施包含阵列的像素池。在我的经验中,经常在大对象堆上分配对象强调gc。