2012-02-27 19 views
7

He estado tratando de utilizar la implementación de OpenCV del método de corte simultáneo a través de los enlaces de Python. He intentado usar la versión en cv y cv2, pero tengo problemas para encontrar los parámetros correctos que debo usar para que el método se ejecute correctamente. He intentado varias permutaciones de los parámetros y nada parece funcionar (básicamente, cada ejemplo que he visto en Github). Aquí hay un par de ejemplos que han tratado de seguir:Enlaces de OpenCV Python para el algoritmo de GrabCut

Example 1

Example 2

Y aquí está la documentación del método y un conocido informe de error:

Documentation

Known Grabcut Bug

Puedo obtener el código para ejecutarnos El ejemplo siguiente, pero devuelve una máscara de imagen en blanco (todo negro).

img = Image("pills.png") 
mask = img.getEmpty(1) 
bgModel = cv.CreateMat(1, 13*5, cv.CV_64FC1) 
fgModel = cv.CreateMat(1, 13*5, cv.CV_64FC1) 
for i in range(0, 13*5): 
    cv.SetReal2D(fgModel, 0, i, 0) 
    cv.SetReal2D(bgModel, 0, i, 0) 

rect = (150,70,170,220) 
tmp1 = np.zeros((1, 13 * 5)) 
tmp2 = np.zeros((1, 13 * 5)) 
cv.GrabCut(img.getBitmap(),mask,rect,tmp1,tmp2,5,cv.GC_INIT_WITH_RECT) 

Estoy usando SimpleCV para cargar las imágenes. El tipo de máscara y el tipo de retorno de img.getBitmap() son:

iplimage(nChannels=1 width=730 height=530 widthStep=732) 
iplimage(nChannels=3 width=730 height=530 widthStep=2192) 

Si alguien tiene un ejemplo práctico de este código me gustaría verlo. Por lo que vale, me estoy ejecutando en OSX Snow Leopard, y mi versión de OpenCV se instaló desde el repositorio SVN (desde hace algunas semanas). Como referencia, mi imagen de entrada es la siguiente: Input Image

He intentado cambiar los valores enum de la máscara de resultado por algo más visible. No son los valores de retorno los que son el problema. Esto devuelve una imagen completamente negra. Voy a probar un par de valores más.

img = Image("pills.png") 
mask = img.getEmpty(1) 
bgModel = cv.CreateMat(1, 13*5, cv.CV_64FC1) 
fgModel = cv.CreateMat(1, 13*5, cv.CV_64FC1) 
for i in range(0, 13*5): 
    cv.SetReal2D(fgModel, 0, i, 0) 
    cv.SetReal2D(bgModel, 0, i, 0) 

rect = (150,70,170,220) 
tmp1 = np.zeros((1, 13 * 5)) 
tmp2 = np.zeros((1, 13 * 5)) 
cv.GrabCut(img.getBitmap(), mask, rect, tmp1, tmp2, 5, cv.GC_INIT_WITH_MASK) 
mask[mask == cv.GC_BGD] = 0 
mask[mask == cv.GC_PR_BGD] = 0 
mask[mask == cv.GC_FGD] = 255 
mask[mask == cv.GC_PR_FGD] = 255 
result = Image(mask) 
result.show() 
result.save("result.png") 
+0

Ejemplo movido al hilo principal. – kscottz

Respuesta

5

Kat, esta versión de su código parece funcionar para mí.

import numpy as np 
import matplotlib.pyplot as plt 
import cv2 


filename = "pills.png" 
im = cv2.imread(filename) 

h,w = im.shape[:2] 

mask = np.zeros((h,w),dtype='uint8') 
rect = (150,70,170,220) 
tmp1 = np.zeros((1, 13 * 5)) 
tmp2 = np.zeros((1, 13 * 5)) 

cv2.grabCut(im,mask,rect,tmp1,tmp2,10,mode=cv2.GC_INIT_WITH_RECT) 

plt.figure() 
plt.imshow(mask) 
plt.colorbar() 
plt.show() 

Produce una figura como esta, con las etiquetas 0,2 y 3. enter image description here

1

Su máscara se llena con el following values:

  • GC_BGD define un evidente píxeles de fondo.
  • GC_FGD define un píxel en primer plano obvio (objeto).
  • GC_PR_BGD define un posible píxel de fondo.
  • GC_PR_FGD define un posible píxel de primer plano.

que son todos parte de un enum:

enum { GC_BGD = 0, // background 
     GC_FGD = 1, // foreground 
     GC_PR_BGD = 2, // most probably background 
     GC_PR_FGD = 3 // most probably foreground 
    }; 

que se traduce en los colores: completamente negro, muy negro, negro oscuro, y negro. Creo que usted encontrará que si se agrega el siguiente código (tomado de su example 1 y ligeramente modificado) su máscara se verá más bonito:

mask[mask == cv.GC_BGD] = 0 //certain background is black 
mask[mask == cv.GC_PR_BGD] = 63 //possible background is dark grey 
mask[mask == cv.GC_FGD] = 255 //foreground is white 
mask[mask == cv.GC_PR_FGD] = 192 //possible foreground is light grey 
+1

Así que noté esto cuando estaba tratando de hacer que esto funcionara. Acabo de ejecutar el siguiente fragmento: – kscottz

+0

Ver el fragmento que agregué arriba, esto tampoco funciona. Gracias por la ayuda. Si pudieras representar la imagen de ejemplo que usaste, te lo agradecería. – kscottz

+0

¿Qué sucede si prueba el código en el comentario de Jan Erik a continuación? –

Cuestiones relacionadas