Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 找到给定一组点的区域_C#_Image Processing_Geometry - Fatal编程技术网

C# 找到给定一组点的区域

C# 找到给定一组点的区域,c#,image-processing,geometry,C#,Image Processing,Geometry,给定x、y坐标列表和已知的宽度和高度,如何确定封闭区域的数量(以C#为单位) 例如: 在该图中,定义了5个封闭区域: 面部(1) 眼睛(2) 鼻子(1) 面部右侧(1) x、y点列表可以是任何黑色像素,包括嘴巴。示例图像中有几个特殊情况。你必须决定如何对付他们 通常,首先将光栅图像转换为一系列多边形。那么,计算面积就相当简单了(见Servy的评论) 特殊情况是面部和口腔的侧面。两者都是开放形状,而不是闭合形状。你需要弄清楚如何关闭它们。我使用OpenCV取得了巨大成功。有一个名为.net的库

给定x、y坐标列表和已知的宽度和高度,如何确定封闭区域的数量(以C#为单位)

例如:

在该图中,定义了5个封闭区域:

  • 面部(1)
  • 眼睛(2)
  • 鼻子(1)
  • 面部右侧(1)

  • x、y点列表可以是任何黑色像素,包括嘴巴。

    示例图像中有几个特殊情况。你必须决定如何对付他们

    通常,首先将光栅图像转换为一系列多边形。那么,计算面积就相当简单了(见Servy的评论)


    特殊情况是面部和口腔的侧面。两者都是开放形状,而不是闭合形状。你需要弄清楚如何关闭它们。

    我使用OpenCV取得了巨大成功。有一个名为.net的库

    以下是一个关于Emgu CV替代品的问题:

    该库包含用于识别轮廓和查找轮廓特性的函数。您可以在该区域搜索以查找更多信息


    如果您正在寻找这个特定问题的快速解决方案,并且希望编写自己的代码,而不是重用其他代码,那么我没有一个算法可以实现这一点。抱歉。

    我认为这归结为计算每个区域中(非黑色)像素的数量。如果选择一个非黑色的像素,请将其添加到
    散列集
    ,查看所选像素上方、下方、左侧和右侧的像素是否也是非黑色的

    每次你发现新的非黑色像素(通过向上/向下/向左/向右)时,将它们添加到你的集合中。当你找到它们时,数一数

    区域的面积是
    count/(像素totaldrawing的宽度*像素totaldrawing的高度)
    乘以整个矩形的面积(取决于所需的单位)


    评论:我不认为这看起来像一个多边形。这就是为什么我想到了简单绘图软件的“用油漆填充”功能。

    你可以使用这个简单的算法,基于使用辅助位图进行洪水填充的想法:

    //backColor是开头填充点处颜色的整数表示形式。
    //生成封闭形状的像素。
    私有int GetFillSize(位图b,点填充点)
    {
    整数计数=0;
    p点;
    堆栈像素=新堆栈();
    var backColor=b.GetPixel(fillPoint.X,fillPoint.Y);
    像素。推(填充点);
    while(pixels.Count!=0)
    {
    计数++;
    p=(点)像素。Pop();
    b、 设置像素(p.X,p.Y,背景色);
    if(b.GetPixel(p.X-1,p.Y).ToArgb()==背景色)
    Push(新点(p.X-1,p.Y));
    if(b.GetPixel(p.X,p.Y-1).ToArgb()==背景色)
    像素。推(新点(p.X,p.Y-1));
    if(b.GetPixel(p.X+1,p.Y).ToArgb()==背景色)
    像素。推(新点(p.X+1,p.Y));
    if(b.GetPixel(p.X,p.Y+1).ToArgb()==背景色)
    像素。推(新点(p.X,p.Y+1));
    }
    返回计数;
    }
    
    更新

    上述代码仅适用于此四重链接的封闭区域。以下代码适用于八位链接的封闭区域

    //偏移点初始化。
    点[]偏移=新点[]
    {
    新点(-1,-1),
    新点(-0,-1),
    新点(+1,-1),
    新点(+1,-0),
    新点(+1,+1),
    新点(+0,+1),
    新点(-1,+1),
    新点(-1,+0),
    };
    ...
    专用整型填充(位图b,点填充点)
    {
    整数计数=0;
    p点;
    堆栈像素=新堆栈();
    var backColor=b.GetPixel(fillPoint.X,fillPoint.Y).ToArgb();
    像素。推(填充点);
    while(pixels.Count!=0)
    {
    计数++;
    p=(点)像素。Pop();
    b、 设置像素(p.X,p.Y,颜色来自argb(背景色));
    foreach(偏移量中的var偏移量)
    if(b.GetPixel(p.X+offset.X,p.Y+offset.Y).ToArgb()==背景色)
    像素推送(新点(p.X+offset.X,p.Y+offset.Y));
    }
    返回计数;
    }
    
    下面的图片清楚地说明了我的意思。还可以向偏移阵列添加更多的远点,以便能够用间隙填充区域


    将包围区域的像素想象成多边形,然后查看如何获取多边形区域抱歉,在转换过程中丢失了一些东西…我需要计算区域数(5)而不是区域面积。酷。这使我模糊的描述清晰明了。我喜欢。不错,对我正在研究的另一个区域很有用,但是你知道如何确定封闭区域的数量吗?你可以使用我的算法对每个非背景色(你的示例图像上的黑色)像素进行区域检测。每次填充后,该区域将不会被检测到(因为它们将被填充),并且您必须增加已查找区域的数量。当然,此方法适用于链接区域。因此,在另一种情况下,使用OpenCV,@Jason Hermann如何回答。@KvanTTT-这在像素宽度为2或更大的情况下非常有效,但是,如果像素宽度为1px,它总是返回为仅1个封闭区域。有没有办法修改上面的代码来处理这个问题?