zoukankan      html  css  js  c++  java
  • 一种从纹理图片提取多边形的方法

    很久在这里写博客。很多时候匹配纹理图片和多边形匹配,手工设置往往非常繁琐,于是写了一段从纹理图片提取边缘多边形的代码。但这份代码只能提取“实心”的多边形,并且只支持了一个多边形。当然如果需要可以扩展使之能够提取多个多边形。基本思路如下:

    1、快速填充纹理中被设为透明的部分。并获得一个边缘种子。

    2、利用边缘种子快速检索边缘。

    3、简化边缘。

    到这里似乎问题解决了,但测试发现一个问题,由于快速边缘检索时将种子周围的点入栈而没有方向,导致最终闭合时一些点会不按顺时针或逆时针被添加到列表。为了解决这个问题,还需要进行边缘排序,而边缘排序之后,还需要再次简化:

    4、对简化的边缘排序。

    5、简化边缘。

    当然,如果边缘排序算法效率更高,可以得到检索的结果后进行排序并简化,这样简化边缘只需要运行一次。

    这里仅列出边缘简化和排序算法。其他代码在之前的文章中已经发过了。

     1     '简化边缘
     2     Private Function EdgeSimple(edge As List(Of Point)) As List(Of Point)
     3         Dim tmp As New List(Of Point)
     4         Dim result As New List(Of Point)
     5         '把前两点复制到结尾
     6         If edge.Count < 3 Then Return result
     7         tmp.AddRange(edge)
     8         tmp.Add(edge(0))
     9         tmp.Add(edge(1))
    10         '遍历整个数组,每三个点判定是否共线,若不共线则把中间点添加到返回值
    11         Dim v1, v2 As Vector2
    12         For i As Integer = 0 To edge.Count - 1
    13             v1 = New Vector2(tmp(i).X - tmp(i + 1).X, tmp(i).Y - tmp(i + 1).Y)
    14             v2 = New Vector2(tmp(i + 2).X - tmp(i + 1).X, tmp(i + 2).Y - tmp(i + 1).Y)
    15             v1.Normalize()
    16             v2.Normalize()
    17             If Vector2.Dot(v1, v2) + 1 > 0.00001F Then
    18                 result.Add(tmp(i + 1))
    19             End If
    20         Next
    21         Return result
    22     End Function
    23 
    24     '边缘排序
    25     Private Sub EdgeSort(edge As List(Of Point))
    26         Dim op As Point = GetOrigin(edge)
    27         Dim tmp As Point
    28         For i As Integer = 0 To edge.Count - 2
    29             For j As Integer = 0 To edge.Count - i - 2
    30                 If PointCmp(edge(j), edge(j + 1), op) Then
    31                     tmp = edge(j)
    32                     edge(j) = edge(j + 1)
    33                     edge(j + 1) = tmp
    34                 End If
    35             Next
    36         Next
    37     End Sub
    38 
    39 
    40 
    41     Private Function PointCmp(a As Point, b As Point, op As Point) As Boolean
    42         If a.X >= 0 AndAlso b.X < 0 Then Return True
    43         If a.X = 0 AndAlso b.X = 0 Then Return a.Y > b.Y
    44         Dim det As Integer = (a.X - op.X) * (b.Y - op.Y) - (b.X - op.X) * (a.Y - op.Y)
    45         If det = 0 Then
    46             Dim d1 As Double = (a.X - op.X) * (a.X - op.X) + (a.Y - op.Y) * (a.Y - op.Y)
    47             Dim d2 As Double = (b.X - op.X) * (b.X - op.Y) + (b.Y - op.Y) * (b.Y - op.Y)
    48             Return d1 > d2
    49         Else
    50             Return det < 0
    51         End If
    52     End Function
  • 相关阅读:
    numpy 学习
    小技巧:Python中,如何让语句输出在同一行的技巧:end=
    Python 循环简介
    Python中第一个if else逻辑判断小程序
    如何让Notepad++的Table转化成4个空格
    Python3.5.2中的变量介绍
    通过配置环境变量,直接运行python3.5.2
    Python3.5.2安装方法
    java 规范
    java数据类型
  • 原文地址:https://www.cnblogs.com/zcsor/p/5888930.html
Copyright © 2011-2022 走看看