Convertir una imagen OpenCV a Blanco y Negro


¿Cómo convertir una imagen OpenCV en escala de grises a blanco y negro? Veo una pregunta similar ya se ha hecho, pero estoy usando OpenCV 2.3, y la solución propuesta ya no parece funcionar.

Estoy tratando de convertir una imagen en escala de grises a blanco y negro, para que todo lo que no sea absolutamente negro sea blanco, y usar esto como una máscara para surf.detect () , para ignorar los puntos de teclado que se encuentran en el borde del área de la máscara negra.

El siguiente Python me hace casi allí, pero el valor de umbral enviado a Threshold () no parece tener ningún efecto. Si lo establezco en 0 o 16 o 128 o 255, el resultado es el mismo, con todos los píxeles con un valor > 128 convirtiéndose en blanco, y todo lo demás convirtiéndose en negro.

¿Qué estoy haciendo mal?

import cv, cv2
fn = 'myfile.jpg'
im_gray = cv2.imread(fn, cv.CV_LOAD_IMAGE_GRAYSCALE)
im_gray_mat = cv.fromarray(im_gray)
im_bw = cv.CreateImage(cv.GetSize(im_gray_mat), cv.IPL_DEPTH_8U, 1);
im_bw_mat = cv.GetMat(im_bw)
threshold = 0 # 128#255# HAS NO EFFECT!?!?
cv.Threshold(im_gray_mat, im_bw_mat, threshold, 255, cv.CV_THRESH_BINARY | cv.CV_THRESH_OTSU);
cv2.imshow('', np.asarray(im_bw_mat))
cv2.waitKey()
Author: Community, 2011-10-02

6 answers

Respuesta paso a paso similar a la que se refiere, usando los nuevos enlaces cv2 Python:

1. Leer una imagen en escala de grises

import cv2
im_gray = cv2.imread('grayscale_image.png', cv2.IMREAD_GRAYSCALE)

2. Convertir imagen en escala de grises a binario

(thresh, im_bw) = cv2.threshold(im_gray, 128, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

Que determina el umbral automáticamente desde la imagen usando el método de Otsu, o si ya conoce el umbral puede usar:

thresh = 127
im_bw = cv2.threshold(im_gray, thresh, 255, cv2.THRESH_BINARY)[1]

3. Guardar en disco

cv2.imwrite('bw_image.png', im_bw)
 73
Author: tsh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-15 11:59:32

Al especificar CV_THRESH_OTSU se ignora el valor de umbral. De la documentación :

Además, el valor especial THRESH_OTSU puede combinarse con uno de los valores anteriores. En este caso, la función determina el valor de umbral óptimo utilizando el algoritmo de Otsu y lo utiliza en lugar de la trilla especificada . La función devuelve el valor de umbral calculado. Actualmente, el método de Otsu se implementa solo para imágenes de 8 bits.

Este código lee marcos desde la cámara y realiza el umbral binario en el valor 20.

#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;

int main(int argc, const char * argv[]) {

    VideoCapture cap; 
    if(argc > 1) 
        cap.open(string(argv[1])); 
    else 
        cap.open(0); 
    Mat frame; 
    namedWindow("video", 1); 
    for(;;) {
        cap >> frame; 
        if(!frame.data) 
            break; 
        cvtColor(frame, frame, CV_BGR2GRAY);
        threshold(frame, frame, 20, 255, THRESH_BINARY);
        imshow("video", frame); 
        if(waitKey(30) >= 0) 
            break;
    }

    return 0;
}
 8
Author: SSteve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-02 07:07:31

Simplemente puede escribir el siguiente fragmento de código para convertir una imagen OpenCV en una imagen de escala de grises

import cv2
image = cv2.imread('image.jpg',0)
cv2.imshow('grey scale image',image)

Observe que la imagen.jpg y el código deben guardarse en la misma carpeta.

Tenga en cuenta que:

  • ('image.jpg') da una imagen RGB
  • ('image.jpg',0) da una Imagen de Escala de Grises.
 4
Author: Ananth Reddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-24 07:02:10

Enfoque 1

Al convertir una imagen de escala de grises en una imagen binaria, generalmente usamos cv2.threshold() y establecemos un valor de umbral manualmente. A veces, para obtener un resultado decente, optamos por La binarización de Otsu.

Tengo un pequeño truco que me encontré mientras leía algunas publicaciones de blog.

  1. Convierta su imagen de color (RGB) a escala de grises.
  2. Obtenga la mediana de la imagen de escala de grises.
  3. Elija un valor umbral 33% por encima de la mediana

introduzca la descripción de la imagen aquí

¿Por qué 33%?

Esto es porque 33% funciona para la mayoría de las imágenes / conjunto de datos.

También puede trabajar en el mismo enfoque reemplazando median con el mean.

Enfoque 2

Otro enfoque sería tomar un x número de desviaciones estándar (std) de la media, ya sea en positivo o negativo; y establecer un umbral. Así que podría ser uno de los siguiente:

  • th1 = mean - (x * std)
  • th2 = mean + (x * std)

Nota: Antes de aplicar el umbral es aconsejable mejorar el contraste de la imagen de escala de grises localmente (Ver CLAHE).

 3
Author: Jeru Luke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-24 08:53:46

Preste atención, si utiliza cv.CV_THRESH_BINARY significa que cada píxel mayor que el umbral se convierte en el valor máximo (en su caso 255), de lo contrario el valor es 0. Obviamente si su umbral es 0 todo se convierte en blanco (MaxValue = 255) y si el valor es 255 todo se convierte en negro (es decir, 0).

Si no quieres calcular un umbral, puedes usar el método de Otsu. Pero este algoritmo solo funciona con imágenes de 8 bits en la implementación de OpenCV. Si tu imagen es de 8 bits usa el algoritmo como esto:

cv.Threshold(im_gray_mat, im_bw_mat, threshold, 255, cv.CV_THRESH_BINARY | cv.CV_THRESH_OTSU);

No importa el valor de umbral si tiene una imagen de 8 bits.

 1
Author: javier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-14 20:08:52

Aquí hay un código de dos líneas que encontré en línea que podría ser útil para un principiante

# Absolute value of the 32/64
abs_image_in32_64 = np.absolute(image_in32_64)

image_8U = np.uint8(abs_image_in32_64)
 1
Author: Santhosh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-29 12:13:06