2009-12-20 198 views
4

我正在一個房地產網站上工作,我想寫一個程序, 可以找出(分類)如果圖像是平面圖或公司標誌。圖像分類 - 檢測平面圖

因爲我在php中寫作,我會更喜歡php解決方案,但任何c + +或opencv解決方案也會很好。

平面圖樣品:

alt text http://www.rentingtime.com/uploads/listing/l0050/0000050930/68614.jpg

alt text http://www.rentingtime.com/uploads/listing/l0031/0000031701/44199.jpg

標誌樣本:

alt text http://www.rentingtime.com/uploads/listing/l0091/0000091285/95205.jpg

+0

你可能會更適合在自由程序員的網站上尋找;這有點超出了單個問題的範圍。 – Amber 2009-12-20 08:32:34

+2

除非這些平面圖文檔易於表徵,否則您不需要自由程序員,因爲您需要一個充滿博士學位的研發部門。沒有人會在PHP中寫出這樣的想法。 – 2009-12-20 08:35:53

+3

http://www.townsvillefloorplans.com.au/images/logo.jpg既是...... – 2009-12-20 11:59:44

回答

6

一如既往,有一個built-in PHP function for this。只是在開玩笑。 =)

我見過的所有平面圖都非常單調,我認爲你可以用顏色和顏色飽和度來玩一個很好的猜測,就是圖像是一個標誌或一個平面圖。

如:is the image has less than 2 or 3 colors is a floor plan.

如:if the sum/average of the saturation is less than X it's a floor plan.

黑色和白色(以及在平面圖中使用其他類似的顏色)的飽和是零,或者非常接近於零,而標誌往往更具視覺吸引力,因此使用更飽和的顏色。

下面是一個簡單的函數來計算一個十六進制RGB顏色的飽和度:

function Saturation($color) 
{ 
    $color = array_map('hexdec', str_split($color, 2)); 

    if (max($color) > 0) 
    { 
     return (max($color) - min($color))/max($color); 
    } 

    return 0; 
} 

var_dump(Saturation('000000')); // black 0.0000000000000000 
var_dump(Saturation('FFFFFF')); // white 0.0000000000000000 
var_dump(Saturation('818185')); // grey  0.0300751879699249 
var_dump(Saturation('5B9058')); // green 0.3888888888888889 
var_dump(Saturation('DE1C5F')); // pink  0.8738738738738738 
var_dump(Saturation('FE7A15')); // orange 0.9173228346456692 
var_dump(Saturation('FF0000')); // red  1.0000000000000000 
var_dump(Saturation('80FF80')); // ---  0.4980392156862745 
var_dump(Saturation('000080')); // ---  1.0000000000000000 

使用imagecolorat()imagecolorsforindex()你可以實現一個簡單的函數,環槽的所有圖像和和的像素/計算飽和度的平均值。如果圖像的飽和度高於您定義的自定義閾值,則可以假定圖像是徽標。

有一件你不應該忘記的是,具有更高分辨率的圖像通常會有更多的飽和度(更多的像素進行求和),所以爲了這個算法以及爲了您的服務器性能,它會是明智地將所有圖像調整爲通用分辨率(比如100x100或50x50)來對它們進行分類,一旦分類,您可以使用原始(未調整大小)的圖像。

我與你提供的圖像一個簡單的測試,這裏是我使用的代碼:

$images = array('./44199.jpg', './68614.jpg', './95205.jpg', './logo.png', './logo.gif'); 

foreach ($images as $image) 
{ 
    $sat = 0; 
    $image = ImageCreateFromString(file_get_contents($image)); 

    for ($x = 0; $x < ImageSX($image); $x++) 
    { 
     for ($y = 0; $y < ImageSY($image); $y++) 
     { 
      $color = ImageColorsForIndex($image, ImageColorAt($image, $x, $y)); 

      if (is_array($color) === true) 
      { 
       $sat += Saturation(dechex($color['red']) . dechex($color['green']) . dechex($color['blue'])); 
      } 
     } 
    } 

    echo ($sat/(ImageSX($image) * ImageSY($image))); 
    echo '<hr />'; 
} 

而且這裏的結果:

green floor plant:  0.0151028053 
black floor plant:  0.0000278867 
black and white logo: 0.1245559912 
stackoverflow logo:  0.0399864136 
google logo:   0.1259357324 

只使用這些例子中,我會形象地說是地板廠如果平均飽和度小於0.03或0.035,你可以調整通過添加額外的例子它遠一點。

+0

除非是帶有公司徽標的平面圖:)但這也是我的方法。 +1 – 2009-12-20 17:11:12

+0

@Pekka:儘管如此,通過調整,該標誌將被幾乎忽略不計,並會以飽和貢獻只是一些無關緊要的點。如果不是這意味着它是一個帶有平面圖的徽標,而不是帶有徽標的平面圖。 =) – 2009-12-20 17:35:29

+0

@Pekka:另外,他可以用平均值來解釋這個小文物,而不是使用總和。 – 2009-12-20 17:36:19

1

我非常懷疑任何這樣的工具已經存在,並創造任何準確的將是非-不重要的。如果您需要整理一組現有的圖像(例如,您有一個未分類的目錄),那麼您可以編寫一個「足夠好」的工具並手動處理這些故障。如果您需要用新圖像動態地執行此操作,則可能是錯誤的方法。

如果我爲前一種情況嘗試此操作,我可能會尋找一些可以用作代理的細微差別。樓層平面圖通常比標識大很多(無論是文件大小還是圖像大小)?平面圖的顏色較少,然後是徽標?如果使用一些微不足道的東西,我可以獲得75%的準確率,那麼這可能是一條可行的路。

+0

+1 - 另一個簡單的指標是文件名中的關鍵字,如「logo」或「floor」:) – 2009-12-20 08:48:29

+0

感謝您的回答,但我試過這種方法很多標識與地板尺寸相同計劃。任何其他可以使用的指標?也請看到我的評論上述有關(使用房間的角落) – user235410 2009-12-20 18:34:16

+0

標誌往往不是高得較寬我想您可以將圖像的平面圖分類的方式嗎? – 2009-12-20 21:03:33

1

這樣的東西 - 圖像模式的識別 - 在時間上往往非常昂貴,極不可靠,並且不斷需要更新和修補以匹配新案例。

我可以問你爲什麼要這麼做?有沒有在您的網站的工作流程一個地步,可以手動確定的圖像是否是標誌或平面圖?編寫一個讓用戶確定上傳時哪個應用程序的應用程序會不會更容易?爲什麼首先有一組混合的數據?

+0

我從客戶端獲取數據作爲一批未排序的圖像。 因爲它含有當我顯示每個需要進行分類,如果可能的話自動(這樣我就可以在將來使用它),我已經寫了一部分(該樓盤的樓層平面圖及公司徽標)圖像的千以95%的準確度對屬性的照片進行分類,所以現在剩下的圖像中我留下了標識和平面圖。 – user235410 2009-12-20 18:42:46

+1

我明白了。這已經很令人印象深刻了。不過,我認爲手頭的任務確實更容易出錯率很高。我個人會選擇一個完全手動的程序,創建一個界面,可以很容易地指向和點擊什麼。但是,如果你自動化 - 也許使用這裏發佈的一個非常有趣的建議 - 我相信很多人(包括我)會有興趣瞭解它是如何實現的。 – 2009-12-20 18:53:13

1

儘管認爲這是需要人工干預的事情,但您可以做的一件事是檢查圖像的大小。

一個小的(無論是在MB和尺寸)圖像可能是一個標誌。

一個大的(在MB和維度方面)圖像可能是一個平面圖。

但是,這只是一個概率測量,絕不是萬無一失的。

該類型的圖像也是一個指標,但少一個。標誌是更可能是JPG,PNG或GIF,樓層平面圖都可能會成爲TIFF或其他無損格式 - 但不能保證。

0

正如其他人說,比如圖像識別通常是可怕的複雜。忘記PHP。

不過,看在你的樣品我看到一個標準的MIGHT工作得很好,如果它沒有和將是很容易實現:

通過良好的OCR運行圖像,看看有什麼字符串彈出。如果你發現一堆描述房間或這些功能的詞...

我想將圖像旋轉90度,然後再次嘗試捕捉垂直標籤。

編輯: 既然你說你試過了,它不起作用,也許你需要首先清理雜亂。基於空白切片圖像。運行OCR對付每個子圖像,以防萬一它試圖解析線條時會出現混亂。您可以使用圖像編輯器手動對其進行測試以對其進行分割。

+0

試過你會推薦哪些OCR工具?我試了tesseract,它無法找出文本 – user235410 2009-12-21 06:45:57

+0

對不起,但我不能幫助工具。我還沒有處理足夠的OCR知道可以做什麼。 – 2009-12-21 19:11:33

+0

我認爲識別公司標誌中的字符本身就是一項複雜的工作。 – 2009-12-22 07:44:16

2

想到的第一件事情之一是,平面圖往往會有比90度更多的線條,比任何一般的標誌都要多。

快速第一遍將是在圖像上運行Canny edge detection,並使用Hough transform和rho,Theta定義的線對角度進行投票。如果你看到一個非常強的對應於Theta =(0,90,180,270)的rho相加,你可以將圖像分類爲平面圖。

另一種選擇是走邊緣圖像坎尼步驟之後只從長的,連續的線段數票,去除噪聲。

+1

任何想法如何編寫這樣做的程序?或者,你能送我去,可以解釋這個東西,所以我可以寫我自己 – user235410 2009-12-23 06:32:49

0

使用兩種顏色飽和度圖像尺寸(無論是在以前的答案單獨提出)。使用人體分類數字的大量樣本,看看它們在二維空間(尺寸x飽和度)中是如何繪製的,然後決定在哪裏放置邊界。邊界不一定是一條直線,但不要試圖讓所有點都適合,否則你會以犧牲新數據爲代價來「記憶」樣本。最好找到一個適合大多數樣本的相對簡單的邊界,它應該適合大部分數據。

你必須容忍一定的錯誤。一個萬無一失的解決方案是不可能的。如果我選擇平面圖作爲我公司的標誌怎麼辦? (這不是一個笑話,它恰恰是搞笑)

1

一個簡單的沒有腦子的嘗試我第一次嘗試是使用SVM學習從樣本中獲得的SIFT關鍵點。但在你做這件事之前,你需要標記一小部分圖像,給它一個-1(平面圖)或1(一個圖標)。如果一幅圖像有更多關鍵點被分類爲平面圖,那麼它必須是一個平面佈置圖,如果它具有更多關鍵點歸類爲標識,那麼它必須是標識。在計算機視覺領域,這被稱爲特徵袋方法,也是最簡單的方法之一。更復雜的方法可能會產生更好的結果,但這是一個好的開始。

+1

不知道如何編寫一個程序,它是一個地方嗎? 或者你可以送我去,可以解釋這個東西的地方,所以我可以寫我自己 – user235410 2009-12-23 06:25:57

+0

@tomlei:也許你可以在這個題爲「關鍵點的包視覺分類」簽出紙由Gabriella Csurka等。 – 2009-12-29 10:41:20

3

將它外包給人類可能是最容易的。

如果你有預算,考慮Amazon's Mechanical Turk。請參閱維基百科瞭解general description

或者,您可以自己做外包。編寫一個PHP腳本來顯示你的一張圖片,並提示用戶將它排序爲「logo」我們的「平面圖」。一旦你在網絡服務器上運行了這個程序,就可以通過電子郵件發送你的整個辦公室,並要求每個人將20張圖像分類爲個人喜好。

更重要的是,使之成爲contest--誰排序最圖像將贏得一個iPod的人!

也許最簡單的,邀請大家你知道了比薩餅和啤酒,並設置了一堆的筆記本電腦,並讓每個人都花幾分鐘的時間排序。

有一些軟件方法可以完成你的任務,但是如果它是一次性活動,少於幾千幅圖片和至少幾百美元的預算,那麼比我認爲你的生活可能更容易使用人類。