【问题标题】:Hysteresis thresholding in visual basic视觉基础中的滞后阈值
【发布时间】:2017-05-31 16:18:19
【问题描述】:

我正在尝试在 Visual Basic 中进行迟滞阈值处理以进行精明的边缘检测。由于我是这个主题的新手和 vb 的新手(我主要使用 php),我阅读的许多参考资料都指出我需要这样做。由于图像已经是黑白的,我只得到一种强度的颜色。我已经在几秒钟内完成了高斯模糊、灰度、索贝尔蒙版和非最大值抑制。但是在滞后上,执行该功能的时间太长了。我不知道我哪里做错了。如果有帮助,图像是 640 x 480。我尝试将分辨率更改为更小的分辨率,它确实更快,但我想将分辨率保持在 640 x 480。我已经更改了代码,这是我的最终方法

  Dim bmp_thres As New Bitmap(pic_nonmaxima)


    Dim visited_maps As New List(Of String)

    Dim threshold_H As Integer = 100
    Dim threshold_L As Integer = 50
    Dim Ycount As Integer
    For Ycount = 1 To bmp_thres.Height - 2
        Dim Xcount As Integer
        For Xcount = 1 To bmp_thres.Width - 2


            'check current pointer 
            Dim currPointer As String = Xcount & "," & Ycount
            'find if coordinate visited already
            Dim find_array As String
            If visited_maps IsNot Nothing Then
                find_array = visited_maps.Contains(currPointer)
            Else
                find_array = "False"
            End If

            If find_array Then
                'if existed, do nothing
            Else
                'if not, do something
                Dim currThreshold As Integer
                Dim currColor As Color
                currColor = bmp_thres.GetPixel(Xcount, Ycount)
                currThreshold = currColor.R


                'add coordinate into visited maps
                Dim visited As String = Xcount & "" & Ycount
                visited_maps.Add(visited)

                If currThreshold > threshold_H Then
                    bmp_thres.SetPixel(Xcount, Ycount, Color.FromArgb(255, 255, 255))
                Else
                    bmp_thres.SetPixel(Xcount, Ycount, Color.FromArgb(0, 0, 0))
                    'check connectedness

                    Dim coord_N As String = Xcount & "," & Ycount + 1
                    Dim coord_E As String = Xcount + 1 & "," & Ycount
                    Dim coord_S As String = Xcount & "," & Ycount - 1
                    Dim coord_W As String = Xcount - 1 & "," & Ycount

                    Dim coord_NE As String = Xcount + 1 & "," & Ycount + 1
                    Dim coord_SE As String = Xcount + 1 & "," & Ycount - 1
                    Dim coord_SW As String = Xcount - 1 & "," & Ycount - 1
                    Dim coord_NW As String = Xcount - 1 & "," & Ycount + 1

                    Dim myCoord As New List(Of String)

                    myCoord.Add(coord_N)
                    myCoord.Add(coord_E)
                    myCoord.Add(coord_S)
                    myCoord.Add(coord_W)

                    myCoord.Add(coord_NE)
                    myCoord.Add(coord_SE)
                    myCoord.Add(coord_SW)
                    myCoord.Add(coord_NW)


                    For Each coord In myCoord
                        If Not visited_maps.Contains(coord) Then
                            'Split by ,
                            Dim split_Coord() As String = Split(coord, ",")
                            'check thres on coord
                            Dim coordColor As Color = bmp_thres.GetPixel(split_Coord(0), split_Coord(1))
                            Dim coordThres As Integer = coordColor.R

                            If coordThres > threshold_H Then
                                bmp_thres.SetPixel(split_Coord(0), split_Coord(1), Color.FromArgb(255, 255, 255))
                            Else
                                bmp_thres.SetPixel(split_Coord(0), split_Coord(1), Color.FromArgb(0, 0, 0))
                            End If

                        End If

                        visited_maps.Add(coord)
                    Next 'end if foreach

                End If ' end if checking current threshold
            End If 'end if find coord in visited maps

        Next 'end for xcount
    Next 'end for ycount

    Return bmp_thres

或者如果您发现我做的一些错误代码,请指出我。

如果我做对了,当我们做滞后阈值时,我们首先检查坐标是否已经访问过,如果已经访问过,我们检查下一个坐标。如果不是,我们将坐标添加到访问过的地图中,如果当前坐标大于阈值高,我们将像素值更改为白色,否则为黑色。然后我们检查连通性,如果它们通过阈值低,我们将像素值更改为白色,否则为黑色。然后我们将所有连通性添加到访问过的地图中。重复。

我可以做些什么来减少时间?或者请指出我的错误。任何帮助将不胜感激。如果你不明白,对不起英语。这将有助于我最后一年的项目T_T

【问题讨论】:

    标签: vb.net image-processing edge-detection


    【解决方案1】:

    我认为这可能是Code Review 的主题,因为它正在工作(尽管速度很慢)。但以防万一,我将把它留在这里作为部分答案。

    您的坐标搜索有一个小错误。不管它是否已经在visited_maps 中,您仍然添加它,这将在列表中增加很多额外的结果。

    If Not visited_maps.Contains(coord) Then
        ' YOUR CODE
    End If
    
    visited_maps.Add(coord)
    

    这一行:visited_maps.Add(coord) 需要在 If 内,这样您的列表就不会超出所需的重复值。一个 640 * 480 像素的图像会在您的列表中创建超过 300 000 个条目,并且由于这个坐标错误,它会拥有更多。


    List 可能也不是最合适的类型,HashSet 之类的更好,因为您不需要按索引访问。看看What is the difference between HashSet and List?


    当您调用Color.FromArgb(255, 255, 255) 时,您每次都在创建一个新的Color 对象。这将再次成为至少 300 000 个对象,此时您可以在顶部声明一个实例为黑色,另一个实例为白色,然后根据需要使用它们。


    我不确定在逗号分隔的字符串上使用 Point 结构会有什么性能差异,但它会节省大量拆分/连接,并且更易于阅读。

    Dim currPointer As String = Xcount & "," & Ycount

    Dim coord_N As String = Xcount & "," & Ycount + 1

    会变成

    Dim currPointer As Point = New Point(Xcount, Ycount)

    Dim coord_N as Point = New Point(currPointer.X, currPointer.Y + 1)


    还有更多的问题,但它们相当小,所以我暂时不考虑它们

    【讨论】:

    • 谢谢,我将visited_maps 移到if 块内并创建黑白实例。在此期间,我发现了一些错别字并修复了它们。点结构是否与在字符串中添加逗号并拆分它相同?喜欢称它为 split_coord(0) 或 split_coord(1) 吗?在此之后将查看哈希集。由于您的帮助,时间减少了,但我认为时间太长了,因为另一个只花了几秒钟,而这需要将近 4 分钟。正常吗?
    • split_coord(0) 将变为 coord.X,并且 1 -> Y
    • 谢谢,我明白了。并且哈希集和点结构工作完美。现在只需 38 秒即可完成所有操作。从高斯到滞后。你让我免于头痛:)
    猜你喜欢
    • 2014-08-21
    • 2013-04-02
    • 1970-01-01
    • 1970-01-01
    • 2012-12-22
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多