Hoy estuve leyendo una guia muy interesante sobre segmentación de color en matlab y me puse a pensar como hacer algo similar en python. La idea es simple: Cargo una imagen y le hago clic en cualquier lugar de ella y de esa manera obtengo los valores que contiene ese pixel que como ya sabemos, para una imagen a color, son tres. Algo muy importante que noté es que las imágenes RGB en opencv no son como uno esperaría. Me refíero a que si tengo una imagen RGB se entiende que el primer canal es el rojo, el segundo el verde y el tercero el azul. Pero resulta que no es así, ya que los canales de una imagen en opencv se organizan de la siguiente manera: BGR (azul, verde y rojo). La verdad no conozco la causa pero es muy importante saberlo y estar conciente de ello.
Voy a mostrar el codigo y el resultado con una imagen con colores exactos.
Codigo:
import cv
tol=30
# defino la función que se ejecuta cuando hago clic en algún lado
def evento_mouse(event,x,y,flags,param):
    if event==cv.CV_EVENT_LBUTTONDOWN:
        pixel=cv.Get2D(imagen,y,x) 
        #En pixel guardo los valores del pixel y luego los separo en las
        #variables azul, verde y rojo
        azul=pixel[0]
        verde=pixel[1]
        rojo=pixel[2]
        print azul,verde,rojo # las imprimo para saber sus valores
        cv.InRangeS(imagen,(azul-tol,verde-tol,rojo-tol),(azul+tol,verde+tol,rojo+tol),temporal)
        # La funcion InRangeS me permite umbralizar las imagenes dando un rango determinado
        # en este caso el rango es el valor de el pixel menos la tolerancia y el valor del pixel
        # mas la tolerancia. Si los resultados no son los esperados se debe modificar la tolerancia
        cv.ShowImage('Color',temporal)
        #Muestro la imagen resultante. La cual va a mostrar en blanco el color que seleccione
        #y en negro cualquier otro color
    
imagen=cv.LoadImage('C://prueba.png')
cv.ShowImage('Prueba',imagen)
temporal=cv.CreateImage(cv.GetSize(imagen),cv.IPL_DEPTH_8U,1)
cv.SetMouseCallback('Prueba',evento_mouse)
cv.waitKey(0)
Resultado:
Cuando le hago clic en uno de los circulos de la imagen a color, en la otra ventana el circulo que es de ese color se vuelve blanco y el resto queda negro. en este ejemplo el resultado es perfecto a causa de que el rojo es puro (solo tiene una tonalidad) voy a usar el mismo codigo pero con otra imagen.
Resultado:
|  | 
| En este seleccione el color piel | 
|  | 
| En esta seleccione el pelo | 
Codigo:
import cv
tol=30
# defino la función que se ejecuta cuando hago clic en algún lado
def evento_mouse(event,x,y,flags,param):
    if event==cv.CV_EVENT_LBUTTONDOWN:
        pixel=cv.Get2D(imagen,y,x)
        #En pixel guardo los valores del pixel y luego los separo en las
        #variables azul, verde y rojo
        azul=pixel[0]
        verde=pixel[1]
        rojo=pixel[2]
        print azul,verde,rojo # las imprimo para saber sus valores
        while True:
            imagen2=cv.QueryFrame(captura)
            cv.InRangeS(imagen,(azul-tol,verde-tol,rojo-tol),(azul+tol,verde+tol,rojo+tol),temporal)
            # La funcion InRangeS me permite umbralizar las imagenes dando un rango determinado
            # en este caso el rango es el valor de el pixel menos la tolerancia y el valor del pixel
            # mas la tolerancia. Si los resultados no son los esperados se debe modificar la tolerancia
            cv.ShowImage('Umbral',temporal)
            #Muestro la imagen resultante. La cual va a mostrar en blanco el color que seleccione
            #y en negro cualquier otro color
            if cv.WaitKey(30)==27:
                break
captura=cv.CaptureFromCAM(0)
while True:
    imagen=cv.QueryFrame(captura)
    temporal=cv.CreateImage(cv.GetSize(imagen),cv.IPL_DEPTH_8U,1)    
    cv.ShowImage('Color',imagen)
    cv.SetMouseCallback('Color',evento_mouse)
    if cv.WaitKey(30)==27:
        break Resultado:
 
 
 
Muy bueno, excelente para aprender python con opencv
ResponderEliminarMuchas gracias por poner todo esto de OpenCV y Python, me ayudó bastante este semestre para visión artificial.
ResponderEliminarMe escribiste en mi blog hace mucho rato, perdón por no responder, no ví el comentario ^^U
Binding: un enlace a una librería de forma dinámica, los reconoces porque casi siempre se "enlazan" usando lo .h o así.
Warpper: una envoltura, lo que hace es llamar aplicaciones(o métodos de estas) si necesidad de estar realmente enlazadas (como era el caso de MplayerCtrl).
Saludes :)
Me encanta tu blog!!!!
ResponderEliminarHace unas semanas que he empezado con python y OpenCV y me parece apasionante. Animo! Gracias a tu blog muchos vemos luz en el camino.
Excelente artículo, felicidades... comparto aquí otro link que tiene un ejemplo de clasificación de un objeto a partir de una imagen en matlab usando segmentación por color. Espero sea útil.
ResponderEliminarhttp://www.tecnohobby.net/ppal/index.php?option=com_content&view=article&id=29:uso-de-procesamiento-de-imagenes-en-rp&catid=41:pitopicosgenerales&Itemid=21
Saludos
Guay!
ResponderEliminarHola, alguien me podria decir porque cuando pego el codigo en opencv, no me sirve? ya le cambie la ubicacion de la imagen.
ResponderEliminar