首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从BMP或SVG (C#)获取顶点/边

从BMP或SVG (C#)获取顶点/边
EN

Stack Overflow用户
提问于 2015-10-13 19:21:12
回答 1查看 2.6K关注 0票数 1

我有一个JPG、BMP或SVG图像(参见下面的示例),我需要一个算法来提取顶点(X,Y)坐标和egdes (即指示连接哪些顶点的列表)。对于每个顶点对,边可以是布尔值true/false的形式,也可以是连接的顶点对的列表。任何想法都欢迎。

例如,我想要一个函数(或一系列函数),它输入图像并输出两个列表:

顶点

顶点1: X= 1,Y=2

顶点2: X= 3,Y=5

顶点3: X= 3,Y=7

..。

边1:(顶点1,顶点3)

边2:(顶点1,顶点4)

边3:(顶点4,顶点10)

..。

顶点坐标系可以是任意坐标系(例如,基于SVG坐标的像素),也可以是用户定义的其他坐标系。

例如,我从示例图像(左)中提取了以下坐标(像素),并在Matlab (右)中绘制它们。

例如,我可以看出角点大致是:(10,10),(290,10),(290,190)和(10,190)。

但是我想要一个自动检测这些坐标的算法,并且告诉我,在左上角顶点(10,190)和右上顶点(290,190)之间有一个边缘,等等。我还需要识别内部块的每个顶点和边,等等。

同样,对于更复杂的图表,我也需要它的工作。例如,我能够提取必要的像素并生成以下Matlab绘图:

和以前一样,很清楚顶点“应该在哪里”,然而,由于线的厚度,有许多像素簇首先需要“平滑”,等等。我不知道如何做到这一点,并自动化识别顶点/边的过程。

注1:获取像素坐标的方法基本上是:

  • 转换为黑/白
  • 扫描每个像素,看看颜色是否<=阈值,保存(X,Y),如果它是“黑色”
  • Matlab中的绘图

我认为一个粗略的算法是:

  • 应用“平滑”来获得一行而不是像素簇
  • “循环”通过不同方向的像素,当发生显著的斜率变化时,将其识别为“顶点”。
  • 在识别所有顶点之后,求出每一对顶点之间的线,如果这条线大部分是黑色的,则将其识别为边缘。

上面的算法有很多问题,所以我希望其他人能有一些更好的想法或者类似的C#代码等等。

我希望这个过程尽可能自动化。

注2:我还可以将图像转换为SVG格式(已经实现)。据我的理解,SVG格式可能非常适合我的应用程序,因为它可以更容易地自动化流程;然而,我发现SVG结构相当混乱。

我在网上读过一些关于SVG格式的文献,我了解它是如何工作的,但我想知道是否有某种已经存在的库,或者某种东西,可以让我很容易地识别SVG文件中“路径”的顶点,等等。

例如,我从一个SVG文件中获得的“路径”之一是表单:

代码语言:javascript
复制
<path d="M70 1810 c0 -91 3 -110 15 -110 12 0 15 17 15 95 l0 95 1405 
0 1405 0 0 -410 0 -411 -87 3 -88 3 -1 35 c0 19 -1 124 -2 233 l-2 197 
-70 0 -70 0 0 -320 0 -320 153 0 c83 0 162 3 175 6 l22 6 0 504 0 504 
-1435 0 -1435 0 0 -110z m2647 -490 c1 -113 2 -217 2 -232 l1 -27 88 -3 
87 -3 0 -70 0 -70  145 0 -145 0 -3 295 c-1 162 0 301 3 308 3 9 21 12 
57 10 l53 -3 2 -205z"/>

我知道这是一个三次Bezier样条,但是我想知道是否有任何已经存在的算法来处理“路径”代码并提取相关的坐标等等。

谢谢你的帮助!!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-14 15:45:37

SVG路径解析并不难(除非您有复杂的SVG,这看起来不像实际情况)

  1. 查找路径 路径以<path标记开始,通常以/>结束,因此查找路径开始/结束,然后只使用内部的字符串。
  2. d=" 查找 这是路径字符串数据(所以您跳过格式化等.)它的结尾被标记为",因此同样只能使用内部的字符串。
  3. 处理路径字符串
代码语言:javascript
复制
1. read single character (skip spaces)
2. depending the character read the right count of numbers and add entity to your vector representation for example:
代码语言:javascript
复制
    - `M` means absolute move so `x,y` follows so `cursor = (x,y);`
    - `m` means relative move so `x,y` follows so `cursor+= (x,y);`
    - `L` means  absolute line so `x,y`follows so `add_line(cursor,(x,y)); cursor = (x,y);`
    - `l` means  relative line so `x,y`follows so `add_line(cursor,cursor+(x,y)); cursor += (x,y);`
    - `C` means absolute BEZIER cubic so `x1,y1,x2,y2,x3,y3` follows so `add_cubic_BEZIER(cursor,(x1,y1),(x2,y2),(x3,y3)); cursor=(x3,y3)`
    - etc ... the commands `m,M,l,L,h,H,v,V,c,C,s,S,q,Q,t,T` are different only in number of points and type of curve/line
    - `z` means just that you add line from `cursor` at the end to the start point

代码语言:javascript
复制
1. if next string is starting with number handle it as last command and goto **#2**
2. goto **#1**

这就是全部。所以,您所需要的只是简单的字符串解析,能够读取尾数/指数形式的数字,如-125.547e-99和跳过空格/制表符。您不需要解码整个SVG仅仅是路径。

因为每个SVG可以有很多路径,然后在解析完之后,<path找到另一个解析它.直到没有人留下。有时候,<path包含转换矩阵,甚至所有者tag通常是<g,所以可能会有一些转换,但是我认为如果没有这样的东西,导出是很简单的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33110913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档