2017-05-31 89 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