2012-06-22 24 views
6

Voglio segmentare le immagini (dalle riviste) in parti di testo e immagini. Ho diversi istogrammi per diverse ROI nella mia foto. Io uso opencv con python (cv2).Come riconoscere gli istogrammi con una forma specifica in opencv/python

voglio riconoscere istogrammi che assomigliano a questo

http://matplotlib.sourceforge.net/users/image_tutorial-6.png

in quanto è una forma tipica per una regione di testo. Come lo posso fare?

Modifica: Grazie per il vostro aiuto finora.

confronto questi istogrammi ho ricevuto dai ROI ad un istogramma di esempio I purché:

hist = cv2.calcHist(roi,[0,1], None, [180,256],ranges) 
compareValue = cv2.compareHist(hist, samplehist, cv.CV_COMP_CORREL) 
print "ROI: {0}, compareValue: {1}".format(i,compareValue) 

Supponendo ROI 0, 1, 4 e 5 sono aree di testo e ROI è un'area di immagine, ottengo output come questo:

  • ROI: 0, compareValue: 1.0
  • ROI: 1, compareValue: -0,000195522081574 < --- sbagliato classificato
  • ROI: 2, compareValue: 0,0612670248952
  • ROI: 3, compareValue: -0,000517370176887
  • ROI: 4, compareValue: 1.0
  • ROI: 5, compareValue: 1,0

Cosa posso fare per evitare l'errata classificazione? Per alcune immagini, il tasso di errata classificazione è di circa il 30%, che è troppo alto.

(ho provato anche con CV_COMP_CHISQR, CV_COMP_INTERSECT, CV_COMP_BHATTACHARYY e (cron * samplehist) .sum() ma forniscono anche compareValues ​​sbagliate)

risposta

3

È possibile utilizzare una semplice correlazione metrica.

  • fare in modo che l'istogramma di calcolare e il vostro riferimento sono normalizzati (ossia rappresentano probapilities)

  • per ogni calcolo istogramma (dato che mio_rif e myHist sono array NumPy):

    metric = (myRef * myHist).sum()

  • questa metrica è una misura di quanto l'istogramma assomiglia al vostro riferimento.

+0

questa è un'idea davvero interessante. ma cosa intendi per 'myRef'? è un altro istogramma o le stesse dimensioni di 'myHist'? o è una matrice numpy arbitraria? – samkhan13

+0

@ samkhan13 sì, 'myRef' è l'istogramma che vogliamo confrontare. – Simon

9

(Cfr EDIT alla fine nel caso in cui ho capito male la domanda):

Se stai cercando di attirare gli istogrammi, avevo presentato un campione di pitone a OpenCV, e si può ottenere da qui:

http://code.opencv.org/projects/opencv/repository/entry/trunk/opencv/samples/python2/hist.py

E 'utilizzato per disegnare due tipi di istogrammi.Il primo è applicabile alle immagini a colori e in scala di grigi come mostrato qui: http://opencvpython.blogspot.in/2012/04/drawing-histogram-in-opencv-python.html

Il secondo è esclusivo per l'immagine in scala di grigi che è uguale all'immagine nella domanda.

Mostrerò il secondo e la sua modifica.

consideri un'immagine completa, come di seguito:

enter image description here

Abbiamo bisogno di disegnare un istogramma come avete dimostrato. Controlla il codice seguente:

import cv2 
import numpy as np 

img = cv2.imread('messi5.jpg') 
mask = cv2.imread('mask.png',0) 
ret,mask = cv2.threshold(mask,127,255,0) 

def hist_lines(im,mask): 
    h = np.zeros((300,256,3)) 
    if len(im.shape)!=2: 
     print "hist_lines applicable only for grayscale images" 
     #print "so converting image to grayscale for representation" 
     im = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) 
    hist_item = cv2.calcHist([im],[0],mask,[256],[0,255]) 
    cv2.normalize(hist_item,hist_item,0,255,cv2.NORM_MINMAX) 
    hist=np.int32(np.around(hist_item)) 
    for x,y in enumerate(hist): 
     cv2.line(h,(x,0),(x,y),(255,255,255)) 
    y = np.flipud(h) 
    return y 

histogram = hist_lines(img,None) 

E di seguito è l'istogramma che abbiamo ottenuto. Ricorda che è un istogramma dell'immagine completa. Per questo, abbiamo dato None per la maschera.

enter image description here

Ora voglio trovare l'istogramma di una certa parte dell'immagine. La funzione istogramma OpenCV ha una funzione di maschera per questo. Per l'istogramma normale, è necessario impostarlo su None. Altrimenti devi specificare la maschera.

La maschera è un'immagine a 8 bit, dove il bianco indica che la regione deve essere utilizzata per i calcoli dell'istogramma e il nero significa che non dovrebbe.

Quindi ho usato una maschera come di seguito (creata usando la pittura, devi creare la tua maschera per i tuoi scopi).

enter image description here

ho cambiato l'ultima riga di codice, come di seguito:

histogram = hist_lines(img,mask) 

ora vedere la differenza di seguito:

enter image description here

(Ricordate, i valori sono normalizzati, quindi i valori mostrato non è il numero effettivo di pixel, normalizzato a 255. Cambialo come preferisci.)

EDIT:

Credo che ho frainteso la tua domanda. Hai bisogno di confrontare gli istogrammi, giusto?

Se è ciò che si desidera, è possibile utilizzare la funzione cv2.compareHist.

Esiste un tutorial ufficiale su this in C++. Potete trovare il corrispondente Python code here.

+0

Hai ragione, ho bisogno di confrontare gli istogrammi. – soet

+0

@Abid Rahman K. Che cosa è esattamente l'uso della maschera? Ho visto alcune maschere di funzioni dichiarate. È un qualche tipo che possiamo impostare il ROI dell'immagine? – Mzk

+0

ya, normalmente il ROI è un'area rettangolare, ma con la maschera puoi prendere qualsiasi forma. Controlla la sezione dei contorni nel mio blog per maggiori dettagli. Opencvpython.blogspot.com –

Problemi correlati