2017-05-31 261 views
1

我想在视觉基础中为canny边缘检测做出滞后阈值。由于我是新进入这个主题和新的VB(我主要使用PHP),我读了很多参考文献,指出我需要这样做。由于图像已经是黑白的,我只能得到1种颜色的强度。我已经在几秒钟内完成了高斯模糊,灰度,索贝尔掩模和非极大值抑制。但是在滞后时间内,执行该功能的时间过长。我不知道我做错了什么。如果有帮助,图像在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

回答

0

我认为这可能是在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对象。这将会再次出现至少30万个对象,当您可以在顶部声明一个黑色实例并为另一个白色声明时,然后根据需要使用这些实例。


我不知道有什么用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)


还有更多的事情错了,但日ey是相当小的,所以我现在将它们关闭

+0

谢谢,我移动了if块中的visited_maps并创建了黑白实例。而在那里,我发现了一些错别字,并修复了它们。点结构与在字符串中添加逗号并将其拆分相同吗?像调用它split_coord(0)或split_coord(1)?将在此之后查看哈希集。由于你的帮助,时间减少了,但我认为时间太长了,因为对方只花了几秒钟,而这需要将近4分钟。这是正常的吗? – annonim

+0

'split_coord(0)'会变成'coord.X',并且1 - > Y –

+0

谢谢,我知道了。并且哈希集和点结构完美无缺地工作。现在只需要38秒就可以完成所有工作。从高斯到迟滞。你从头痛救了我:) – annonim