6

我已經瀏覽了過去兩天的帖子和示例,並且我已經嘗試過並經過廣泛測試的所有代碼段已被證明是無用的,至少對於我的目的而言是無用的。矢量圖像的圖像比較(基於邊緣檢測)?

我想要做的是比較從牆上或紙上拍下的黑色矢量符號(質量類似於人們可能會說的嚴重掃描圖像),並將其與相同或相似符號的電子版本進行比較存儲在本地並與照片進行比較)。請看附件中的兩張圖片,第一張清晰的圖片(參考圖片)是符號的數據庫版本,第二張圖片是我在一張紙上製作的蹩腳圖片,然後我用iPad拍攝了這張圖片。

Reference Image

Test Image

我想去的程序如下:

  • 兩個圖像加載,然後使用這個微調算法我發現這裏的修改版本修剪:Trimming images with PIL 。我發現,50「閾值」的值和20(在鏈接的腳本參數)的「顯而易見」值給出這些圖像
  • 這些圖像隨後將被調整爲相同的尺寸和比較良好的結果

現在爲了比較,我嘗試了大量不同的建議方法,但迄今爲止結果很糟糕。實際上,我可以用比隨機圖像更好的比較結果。我已經嘗試RMS difference comparison基於實際的圖像,它們的邊緣(使用ImageFilter.CONTOUR或ImageFilter.FIND_EDGES的'過濾器'函數創建的),但到目前爲止,沒有任何我在網上找到(儘管我不停地搜索)或在這裏在StackOverflow中給了我體面的結果。

我相信問題出在測試圖像的嘈雜背景下,但我還沒有能夠證明它。有誰知道是否有辦法從這些圖像的邊緣獲取矢量輪廓,並將它們不僅僅作爲圖像而且作爲圖像矢量進行比較? 儘管我蹩腳的繪畫,我發現這兩個圖像是相當相似的,應該有可能得到一個很好的比較。

+0

基於矢量的方法存在問題,您如何處理錯誤的雜散標記或具有不同高寬比的繪製圖像?除了我的答案,如果你能得到規格化的圖像,使用特徵面的光柵化方法(參見wiki)在這裏可能很有用(儘管計算量很大並且需要一些線性代數)。 – Hooked

回答

4

爲了獲得更好的響應,您需要更好地限制應用程序的範圍。這可能會對你有所幫助。我認爲你的「蹩腳的繪畫」輸入總是與你提供的那個有着強烈邊緣的意義相似,並且其上的顏色是無關緊要的。爲了以簡單的方式解決問題(或者更好地接近解決方案),需要用尺度不變描述符描述兩幅圖像。我對此表示:二進制化圖像,統計兩個圖像中的連接組件(CC)的數量,丟棄不相關大小的CC(距離中值,平均值,與stddev相關的平均值等等,你決定)。您可能需要補充第二步,以更好地區分您的圖像和其他輸入,即您想要的方法越強大,您將需要的判別式描述符就越多。在某些時候,您可能還想考慮使用SVM或其他機器學習技術。

因此,二進制化步驟:執行形態學梯度並丟棄弱梯度。如果輸入與發佈的內容類似,這很容易。下面是我得到的強度60閾值(我也假設你的輸入範圍爲[0,255]):

enter image description here enter image description here

我迅速用的閾值範圍,直到90試驗,他們都爲這些圖像工作。裁剪這些是很容易的,你也可以淹沒填充背景和對象:

enter image description here enter image description here

現在你可以在白提取連接的部件,並做了分析,在他們身上。在這種情況下,最簡單的事情就是數它們。對於這些輸入,我們得到12個「完美」圖像和14個「壞」圖像。但是,在「壞」一箇中,我們有2個大小爲1的組件(每個組件中只有一個像素),這些組件都被平凡地消除。還有很多其他的方式來比較連接的組件,但我希望這可以讓你開始。如果你需要這些任務的代碼,我可以包含它。

+0

哇,你只是把我吹走了:)有些東西告訴我,這不是你第一次:P 你可以請包括你的測試代碼,所以我可以試驗它(你不必粘貼在這裏,附加的文件將是偉大的)? 非常感謝! – somada141

+0

這很好,我希望你能使用它。以下是兩個文件中的代碼分割:http://pastebin.com/SGhw0fMZ和http://pastebin.com/mRZ0mzVa,它非常簡單,可以通過多種方式進行改進。 – mmgp

0

我認爲,如果你想象的線作爲圖形邊緣,以及交叉口節點,即使一個是的fugly電腦應該能夠看到,他們是相同的符號。只需玩關卡就可以得到你的白人和黑人,然後嘗試分析連續的黑點。

+0

謝謝你對Voronoi的迴應,你有沒有可能知道如何去做你的建議?我無法找到任何與PIL – somada141

+0

矢量圖像信息http://codeboje.de/pysvg/是一個體面的SVG庫,你可以嘗試。你正在做的事情是非常困難的,所以最好的運氣。 – VoronoiPotato

+0

邊緣檢測我會尋找對比度提升後白色像素/灰色像素旁邊的黑色像素。可以這麼說,定義外部循環,找到內部邊緣,嘗試通過獲取一行像素並分析(白色,黑色,白色,黑色)來進行關聯 – VoronoiPotato

1

我不知道如何與PIL做到這一點特別,但是我可以指出你一些很好的工作實例來幫助你自我學習(這是圖像處理的不平凡的任務!)。

一個很好的工作示例是DeTeXify,這是一個將鼠標繪製的符號與大型已知符號庫(在這種情況下,可以在排版程序LaTeX中創建的符號)匹配的程序。前端和後端的源代碼都可用。

又如ShapeCatcher其中:

...使用所謂的「形狀上下文」到兩個形狀之間找到相似性。形狀上下文是一種描述形狀之間相似性概念的強大數學方法,它是Serge Belongie和Jitendra Malik首先提出的一種特徵描述符。

關於形狀環境的免費研究論文可以在他們的Berkeley site上找到。

+0

感謝您的建議Hooked,不幸的是我想這個代碼運行在Pythonista,iOS的Python環境不幸的是,它不允許安裝第三方庫,甚至不會使用numpy或scipy,所以我需要找到一種方法來使用標準Python庫進行上述工作。 我有點希望這是一個容易的任務與PIL,但我是愚弄自己:) – somada141

+1

@ somada141瞭解(雖然它會很高興知道問題的限制!)。我仍然認爲引用是有效的,因爲您可以看到生產級別實現中涉及的算法。 – Hooked

0

有一種方法叫做SIFT。 OpenCV使用它,並且在Python OpenCV中也有一個實現。 OpenCV中的實現是SURF,可以找到各種問題和示例,並且運行良好。在this問題中有一個例子。

(發佈這個答案作爲一個額外的參考)

0

我知道這已經回答了,但也許有人仍然會發現這一點。

不像公認的答案,我不會處理梯度來執行二進制化,而是會看Otsu's Thresholding。如果所有圖像只包含非常黑暗和非常亮的區域,則它應該很好,因爲它會在圖像直方圖中尋找兩個峯值(一個用於所有亮像素,一個用於所有暗像素),然後針對某個值兩峯之間。