Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.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_Vector_Polygons - Fatal编程技术网

C# 将像素转换为多边形

C# 将像素转换为多边形,c#,image,vector,polygons,C#,Image,Vector,Polygons,我有一张卫星图像,我想得到所有的绿色区域。 在实践中,我需要从bmp加载图像,选择一种颜色和公差,并获得许多多边形,它们是照片中的绿色区域。 我怎么能在C语言中做到这一点?飞行模拟需要这个嗯,第一步是确定给定像素是否在该区域内。我认为这很简单。然后可以创建“开”或“关”的像素区域 然后需要将像素转换为多边形。如何做到这一点取决于所需的粒度。如果需要高精度,可以使用从区域中获取多边形。如果需要简单的多边形,则需要更高级的方法来追踪边界。好的,第一步是确定给定像素是否在该区域内。我认为这很简单。然后

我有一张卫星图像,我想得到所有的绿色区域。 在实践中,我需要从bmp加载图像,选择一种颜色和公差,并获得许多多边形,它们是照片中的绿色区域。
我怎么能在C语言中做到这一点?飞行模拟需要这个

嗯,第一步是确定给定像素是否在该区域内。我认为这很简单。然后可以创建“开”或“关”的像素区域


然后需要将像素转换为多边形。如何做到这一点取决于所需的粒度。如果需要高精度,可以使用从区域中获取多边形。如果需要简单的多边形,则需要更高级的方法来追踪边界。

好的,第一步是确定给定像素是否在该区域内。我认为这很简单。然后可以创建“开”或“关”的像素区域


然后需要将像素转换为多边形。如何做到这一点取决于所需的粒度。如果需要高精度,可以使用从区域中获取多边形。如果你需要简单的多边形,你将需要一种更高级的方法来追踪边界。

Hmm。听起来像是PhotoShop/PSP控件中使用该名称的魔杖算法,允许你点击一个像素来选择特定颜色阈值内的所有相邻像素

因此,第一步是在位图上选择一个标识为绿色的像素,该像素应该是多边形的一部分。然后,您可以递归地从该点向左、向右、向上和向下移动,并测试该点的像素是否在您根据原始像素颜色设置的阈值范围内。将点添加到集合中(如果该点在阈值范围内但不在集合中),并保持遍历;如果点不够绿,或已映射,则返回。有一些方法可以通过限制后续递归调用可以穿越的方向来限制回溯。例如,假设我们打了四个电话,向上、向下、向左和向右移动。从原点向左移动的呼叫只能从该点继续向左或向上移动

现在有了一组像素,大致对应于一组几何点。然后,必须识别定义多边形边界的这些点的子集。这被称为计算这些点的凸包,Wikipedia有许多可以用C实现的算法

最容易理解的可能是:将所有点排列在一个列表中,从第一点a开始,画一条到第二点B的线,然后确定从B到第三点C的线是否构成从a到B方向的左转或右转。如果是左转,通过从B到C画一条线来转弯,然后像前面一样将该线与从C到D的线进行比较。如果是右转,则忽略B作为凸包的可能顶点,从a到C绘制,然后检查线C到D是否为左转。每当看到右转时,忽略定义线的三个点的当前中点,而是在其他两个点之间绘制一条线。继续,将列表从最后一个点环绕回A,直到这些点定义了一系列线,这些线都从最后一条线的方向左转。这是点集的凸包,可以在NlogN时间内对任何点列表执行


了解凸面外壳正是如此;你永远无法从中得到像星星一样的凹形。如果这很重要,您需要调整算法,以允许一些右转弯,但不允许任何线段交叉。

Hmm。听起来像是PhotoShop/PSP控件中使用该名称的魔杖算法,允许您单击一个像素以选择特定颜色阈值内的所有相邻像素

因此,第一步是在位图上选择一个标识为绿色的像素,该像素应该是多边形的一部分。然后,您可以递归地从该点向左、向右、向上和向下移动,并测试该点的像素是否在您根据原始像素颜色设置的阈值范围内。将点添加到集合中(如果该点在阈值范围内但不在集合中),并保持遍历;如果点不够绿,或已映射,则返回。有一些方法可以通过限制后续递归调用可以穿越的方向来限制回溯。例如,假设我们打了四个电话,向上、向下、向左和向右移动。从原点向左移动的呼叫只能从该点继续向左或向上移动

现在有了一组像素,大致对应于一组几何点。然后,必须识别定义多边形边界的这些点的子集。这被称为计算这些点的凸包,维基百科有很多算法 可以在C中实现的thms:

最容易理解的可能是:将所有点排列在一个列表中,从第一点a开始,画一条到第二点B的线,然后确定从B到第三点C的线是否构成从a到B方向的左转或右转。如果是左转,通过从B到C画一条线来转弯,然后像前面一样将该线与从C到D的线进行比较。如果是右转,则忽略B作为凸包的可能顶点,从a到C绘制,然后检查线C到D是否为左转。每当看到右转时,忽略定义线的三个点的当前中点,而是在其他两个点之间绘制一条线。继续,将列表从最后一个点环绕回A,直到这些点定义了一系列线,这些线都从最后一条线的方向左转。这是点集的凸包,可以在NlogN时间内对任何点列表执行


了解凸面外壳正是如此;你永远无法从中得到像星星一样的凹形。如果这很重要,您需要对算法进行调整,以允许一些右转弯,但不允许任何线段交叉。

使用锁位并根据像素格式迭代每个字节-索引图像使用调色板,因此您需要首先查询,以获得公差范围内的调色板索引-对于非索引和非索引图像1bpp/16ppgreyscale您可以直接访问颜色通道-请参阅此处的帮助。
您范围内的每个彩色像素都可以直接写入另一个图像,即,只有您想要的像素-其余像素用不可见像素-Alpha 0-填充,或者写入一个集合。就我个人而言,我会先做前者。这是非常快的,如果你使用锁具。然后,如果您愿意,可以使用像素行走算法的边缘检测来计算不规则多边形的碎片。RGE库在这方面可能会对您有所帮助。

根据像素格式,使用锁位并迭代每个字节-索引图像使用调色板,因此您需要首先查询,以获得公差范围内的调色板索引-对于非索引和非1bpp/16ppgreyscale,您可以直接访问颜色通道-请参阅这里需要帮助。
您范围内的每个彩色像素都可以直接写入另一个图像,即,只有您想要的像素-其余像素用不可见像素-Alpha 0-填充,或者写入一个集合。就我个人而言,我会先做前者。这是非常快的,如果你使用锁具。然后,如果您愿意,可以使用像素行走算法的边缘检测来计算不规则多边形的碎片。在这方面,一个大型库可能会对您有所帮助。

您可能需要一个for循环,使用Bitmap.GetPixel获取每个像素。每当我想到get/SetPixel,我都会想到等待。。。在慢代码中…您可能需要一个for循环,使用Bitmap.GetPixel获取每个像素。每当我想到get/SetPixel,我就会想到等待。。。关于慢代码…非常感谢!但对于凸壳,我只得到一个多边形。如何获得更多多边形?选择位于该多边形外部的更多像素并重复整个过程。如果绿色区域不代表凸区域,则基于凸包算法的拟议矢量化将失败。另外,基于限制后续递归调用可以穿越的方向的魔杖算法在非凸区域也会失败。非常感谢!但对于凸壳,我只得到一个多边形。如何获得更多多边形?选择位于该多边形外部的更多像素并重复整个过程。如果绿色区域不代表凸区域,则基于凸包算法的拟议矢量化将失败。另外,基于限制后续递归调用可以穿越的方向的魔棒算法也在非凸区域失败。