2012-06-22 17 views
6

Quiero segmentar imágenes (de revistas) en partes de texto e imágenes. Tengo varios histogramas para varios ROI en mi imagen. Yo uso opencv con python (cv2).Cómo reconocer histogramas con una forma específica en opencv/python

quiero reconocer histogramas que se ven así

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

ya que es una forma típica de una región de texto. ¿Cómo puedo hacer eso?

Editar: Gracias por su ayuda hasta ahora.

que compararon los histogramas que recibí de mis regiones de interés a un histograma muestra que proporcioné:

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) 

Suponiendo ROI 0, 1, 4 y 5 son las regiones de texto y el ROI es una región de la imagen, me sale una salida como esto:

  • ROI: 0, compareValue: 1,0
  • ROI: 1, compareValue: -0.000195522081574 < --- mal clasificado
  • ROI: 2, compareValue: 0,0612670248952
  • ROI: 3, compareValue: -0,000517370176887
  • ROI: 4, compareValue: 1.0
  • ROI: 5, compareValue: 1,0

¿Qué puedo hacer para evitar la clasificación errónea? Para algunas imágenes, la tasa de clasificación incorrecta es de aproximadamente 30%, que es demasiado alta.

(I trató también con CV_COMP_CHISQR, CV_COMP_INTERSECT, CV_COMP_BHATTACHARYY y (hist * samplehist) .sum() sino que también proporcionan compareValues ​​equivocadas)

Respuesta

3

Puede utilizar una métrica de correlación simple.

  • asegurarse de que el histograma a calcular y su referencia se normalizan (es decir, representan probapilities)

  • para cada uno de cómputo de histograma (dado que myRef y myHist son matrices numpy):

    metric = (myRef * myHist).sum()

  • esta métrica es una medida de cuánto parece el histograma de su referencia.

+0

esta es una idea realmente interesante. pero ¿qué quieres decir exactamente con 'myRef'? ¿es otro histograma o el mismo tamaño que 'myHist'? o es una matriz numpy arbitraria? – samkhan13

+0

@ samkhan13 sí, 'myRef' es el histograma que queremos comparar. – Simon

9

(Véase la edición en la parte final en caso de que no he entendido bien la pregunta):

Si usted está buscando para dibujar los histogramas, que había presentado una muestra de Python para OpenCV, y se puede obtener de aquí:

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

se utiliza para dibujar dos tipos de histogramas.El primero es aplicable a las imágenes en color y escala de grises como se muestra aquí: http://opencvpython.blogspot.in/2012/04/drawing-histogram-in-opencv-python.html

El segundo es exclusivo para la imagen en escala de grises que es igual que su imagen en la pregunta.

Mostraré el segundo y su modificación.

Considérese una imagen completa de la siguiente manera:

enter image description here

Tenemos que dibujar un histograma como se ha demostrado. Compruebe el código siguiente:

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) 

Y debajo está el histograma que conseguimos. Recuerde que es un histograma de imagen completa. Para eso, hemos dado None para la máscara.

enter image description here

Ahora quiero encontrar el histograma de una parte de la imagen. La función de histograma de OpenCV tiene una función de máscara para eso. Para un histograma normal, debe configurarlo None. De lo contrario, debe especificar la máscara.

La máscara es una imagen de 8 bits, donde el blanco indica que la región se debe usar para los cálculos del histograma, y ​​el negro significa que no.

Así que utilicé una máscara como la que se muestra a continuación (creada con pintura, debe crear su propia máscara para sus fines).

enter image description here

me cambió la última línea de código de la siguiente manera:

histogram = hist_lines(img,mask) 

Ahora ver la diferencia a continuación:

enter image description here

(Recuerde, los valores están normalizados, por lo que los valores que se muestran no son el recuento real de píxeles, normalizado a 255. Cámbielo según lo desee.)

EDIT:

Creo que no he entendido bien su pregunta. Necesita comparar histogramas, ¿verdad?

Si eso es lo que quería, puede usar la función cv2.compareHist.

Hay un tutorial oficial sobre this in C++. Puede encontrar su correspondiente Python code here.

+0

Tienes razón, necesito comparar histogramas. – soet

+0

@Abid Rahman K. ¿Cuál es exactamente el uso de la máscara? Vi una máscara definida por la función. ¿Es de algún tipo que podemos establecer el ROI de la imagen? – Mzk

+0

ya, normalmente roi es una región rectangular, pero con máscara, puede tomar cualquier forma. Verifique la sección de contornos en mi blog para más detalles. Opencvpython.blogspot.com –

Cuestiones relacionadas