的给定的X名单,y坐标和已知宽度&高度怎能NUMBER的封闭区域的(在C#)来确定的?查找区域给定一组点
例如:
在该图像5 封闭区域被定义:
- 工作面(1)
- 眼睛(2)
- 鼻(1)的脸的
- 权(1)
x的列表,Y点将在黑色的任何像素,包括嘴。
的给定的X名单,y坐标和已知宽度&高度怎能NUMBER的封闭区域的(在C#)来确定的?查找区域给定一组点
例如:
在该图像5 封闭区域被定义:
x的列表,Y点将在黑色的任何像素,包括嘴。
你可以使用这个简单的算法,基于洪水的想法充满了帮手位:
// backColor is an INT representation of color at fillPoint in the beginning.
// result in pixels of enclosed shape.
private int GetFillSize(Bitmap b, Point fillPoint)
{
int count = 0;
Point p;
Stack pixels = new Stack();
var backColor = b.GetPixel(fillPoint.X, fillPoint.Y);
pixels.Push(fillPoint);
while (pixels.Count != 0)
{
count++;
p = (Point)pixels.Pop();
b.SetPixel(p.X, p.Y, backColor);
if (b.GetPixel(p.X - 1, p.Y).ToArgb() == backColor)
pixels.Push(new Point(p.X - 1, p.Y));
if (b.GetPixel(p.X, p.Y - 1).ToArgb() == backColor)
pixels.Push(new Point(p.X, p.Y - 1));
if (b.GetPixel(p.X + 1, p.Y).ToArgb() == backColor)
pixels.Push(new Point(p.X + 1, p.Y));
if (b.GetPixel(p.X, p.Y + 1).ToArgb() == backColor)
pixels.Push(new Point(p.X, p.Y + 1));
}
return count;
}
UPDATE
上面的代码工作仅此四重联封闭区域。以下代码适用于八连式封闭区域。
// offset points initialization.
Point[] Offsets = new Point[]
{
new Point(-1, -1),
new Point(-0, -1),
new Point(+1, -1),
new Point(+1, -0),
new Point(+1, +1),
new Point(+0, +1),
new Point(-1, +1),
new Point(-1, +0),
};
...
private int Fill(Bitmap b, Point fillPoint)
{
int count = 0;
Point p;
Stack<Point> pixels = new Stack<Point>();
var backColor = b.GetPixel(fillPoint.X, fillPoint.Y).ToArgb();
pixels.Push(fillPoint);
while (pixels.Count != 0)
{
count++;
p = (Point)pixels.Pop();
b.SetPixel(p.X, p.Y, Color.FromArgb(backColor));
foreach (var offset in Offsets)
if (b.GetPixel(p.X + offset.X, p.Y + offset.Y).ToArgb() == backColor)
pixels.Push(new Point(p.X + offset.X, p.Y + offset.Y));
}
return count;
}
下面的图片清楚地说明了我的意思。也可以添加更多的远点来抵消阵列,以便能够填补空白区域。
很酷。这使我的模糊描述明确。我喜欢。 –
不错,对于我正在研究的另一个领域很有用,但是想知道如何确定封闭区域的数量? – user873432
您可以使用我的算法为每个非背景颜色(在您的示例图像上为黑色)像素区域检测。每次填充后,这些区域将不会被检测到(因为它们将被填满),您将不得不增加发现区域的数量。当然,这种方法适用于链接地区。因此,对于另一个案例使用OpenCV,@Jason Hermann如何回答。 –
样本图像中有几个特殊情况。你将不得不决定如何处理它们。
一般来说,你将通过光栅图像转换成一系列的多边形开始。然后,它是计算面积相当小事(见Servy的评论)
的特殊情况下,会在脸上和嘴角边。两者都是开放的形状,没有关闭。你需要弄清楚如何关闭它们。
我使用OpenCV取得了巨大的成功。有一个叫Emgu CV
这里.NET库涵盖替代Emgu CV一个问题:.Net (dotNet) wrappers for OpenCV?
这个库包含了功能识别轮廓和寻找关于他们的属性。您可以搜索cvContourArea以查找更多信息。
如果你正在寻找一个快速的解决这个特定的问题,并希望而不是重用他人编写自己的代码,我没有一个算法,我可以给那个做到这一点。抱歉。
我认为这归结为计算每个区域(非黑色)像素的数量。如果选择一个不是黑色的像素,请将其添加到HashSet<>
,查看所选像素左上方和右下方的像素是否也是非黑色。
每当您发现新的非黑色像素(通过上/下/左/右),将它们添加到您的设置。当你找到他们全部时,数一数。
您所在地区的区域count/(pixelWidthOfTotalDrawing * pixelHeightOfTotalDrawing)
乘以整个矩形(取决于你想要的单位)的区域。
评论:我不认为这看起来像一个多边形。这就是为什么我在我的脑海里充满了简单绘图软件的“充满油漆”功能。
[与式开始查找多边形的面积](http://en.wikipedia.org/wiki/Polygon#Area_and_centroid) – Servy
想到你的封闭区域为多边形的象素然后见http://stackoverflow.com/questions/2034540/calculating-area-of-irregular-polygon-in-c-sharp关于如何获得多边形区域 – m0s
对不起,有些东西在翻译中丢失了......我需要弄清楚区域数量(5)而不是它们的面积。 – user873432