OpenCV inRange C++ y Filtro de color con QT – Visión Artificial

Visión artificial, filtro de color con OpenCV inRange. Está una función que permite filtrar una ventana de valores para pixeles en una imagen. Por ejemplo, está función se utilizaría en el procedimiento de crear un rastreador por color, para obtener como resultado una imagen binaria con el objeto detectado. Entonces en otras palabras, la función acepta como entrada una imagen de 1 o más dimensiones y da como resultado una imagen binaria. Para el resultado de la imagen en blanco y negro, el blanco representa a todos los pixeles que fueron validos para el rango filtrado. En este tutorial te indicaremos varios ejemplos para usar a la función y además como crear un proyecto para usar la función inRange de OpenCV con QT Creator en Ubuntu 16.04.

Sintaxis:

  • void inRange(MatrizOriginal, Scalar(ValorMinCanal-0, ValorMinCanal-1, ValorMinCanal-2), Scalar(ValorMaxCanal-0, ValorMaxCanal-1,ValorMaxCanal-2), MatrizBinariaDestino);

Parámetros de entrada:

  • MatrizOriginal. Es una matriz que contiene a una imagen.
  • MatrizBinariaDestino es la matriz donde se guardará el resultado del filtro de ventana.
  • ValorMinX representa un valor entero positivo que esta relacionado con los bits de la imagen, y que indica el valor mínimo del filtro de dos rangos para una ventana de valores.
  • ValorMaxX indica el numero entero positivo que relaciona al valor máximo del filtro doble de la imagen.

Ejemplo 1 – Filtrar todos los valores de 1 canal para una imagen RGB con OpenCV inrange

Para el ejemplo 1, le pasaremos el filtro inRange de OpenCV a una imagen de 3×3 pixeles. Entonces para el filtro se configurará para que sólo se deje pasar a todos los pixeles del canal 1. Es decir, todo los pixeles VERDES. El resultado será una matriz de 1 canal de color blanco y negro con todos los pixeles blancos que cumplan con estos valores del filtro de la ventana. Por ejemplo considere el resultado con la siguiente imagen:

  • inRange(ImagenRGB, Scalar(0,0,0), Scalar(0,255,0), Salida);

OPenCV inRange

 

Ejemplo 2 – Usar la función de OpenCV inRange para dejar pasar todo

Veamos el un caso donde podemos configurar al filtro ventana de cada uno de los canales para que pase todo. El resultado sera una matriz de puntos blancos para todos los pixeles.

  • inRange(ImagenRGB, Scalar(0,0,0), Scalar(255,255,255), resultado);

OpenCV inRange ejemplo 2

 

Ejercicio 1 para la función de OpenCV inRange

Considere la siguiente imagen, que valores binarios serán 1 o 0 si la imagen de entrada BGR tiene los siguientes valores:

OpenCV inRange ejercicio 1

 

Respuesta. Todos los pixeles serán 0, porque aunque puede que hay pixeles en los canales 1 y 2 que cumplan con el rango del filtro, el primer canal esta mal filtrado, al dejar pasar sólo a los pixeles que cumplan con la siguiente condición:    PixelBlanco si el pixel canal 0 es > 150 y < 0. Por lo tanto esta condición excluye al resto de los filtros.

 

Ejercicio 2

 

Resultado del Ejercicio – 2

Dado que el filtro deja pasar a todos los pixeles rojos y verdes (canal 1 y canal 2 respectivamente), el filtro en realidad esta dominado por la ventana del canal 0. Y solo dejara pasar a aquellos pixeles que estén dentro de 150 a 250. Esto solo corresponde a la columna central. Dado que los canales 1 y 2 no tienen componentes verdes estos se excluyen del filtraje. Por lo tanto las operaciones del filtro de OpenCV inrange que realiza entre filtro y filtro es una tipo de operación lógica AND.

OpenCVinrange resultado del ejercicio 2

 

Ejercicio 3

Cuál será el resultado de la siguiente instrucción:

OpenCV inrange ejercicio 3

 

Resultado del ejercicio 3

Para el ultimo resultado, el único pixel que cumple con las 3 condiciones de los 3 filtros ventana para cada canal, es:

OpenCV inRange resultado del ejercicio 3

 

Ejemplo para crear un filtro de color con OpenCV inRange y QT Creator en Ubuntu 16.04

Ahora integraremos a una función inRange en un proyecto de QT para crear un filtro de color. Para poder continuar requieres los siguientes conocimientos previos:

Requisitos para el siguiente ejemplo:

Procedimiento para configurar el proyecto

Primero comenzaremos por crear un proyecto nuevo.

  1. Configurar el proyecto para poder compilar las bibliotecas de OpenCV.
    1. En el archivo .pro se coloca el siguiente código:
      1. INCLUDEPATH += /usr/local/include/opencv2
      2. LIBS += -L/usr/local/lib -lopencv_core -lopencv_imgcodecs -lopencv_highgui -lopencv_videoio
      3. CONFIG += link_pkgconfig
      4. PKGCONFIG += opencv
    2. Se agrega al proyecto las bibliotecas de mat2qimage.cpp y mat2qimage.h.
    3. En el archivo de MainWIndow.cpp se agregan las siguientes bibliotecas.
      1. #include<opencv2/core/core.hpp>
      2. #include<opencv2/ml/ml.hpp>
      3. #include<opencv/cv.h>
      4. #include<opencv2/imgproc/imgproc.hpp>
      5. #include<opencv2/highgui/highgui.hpp>
      6. #include<opencv2/video/background_segm.hpp>
      7. #include<opencv2/videoio.hpp>
      8. #include<opencv2/imgcodecs.hpp>
      9. #include «mat2qimage.h» //Nota1
      10. #include <QFileDialog>
      11. #include <QTimer>
    4. Agregar el nombre de espacio para opencv.
      1. using namespace cv;
    5. Se agregarán las siguientes variables globales.
      1. Mat IMAGEN;   //Para guardar la imagen que se abrirá
      2. Mat IMAGENchica;    //Guardará la imagen pequeña
      3. Mat ImagenHSV;   //Aquí se guarda la imagen HSV
      4. Mat ImagenDesenfoque;  //Para la imagen con desenfoque
      5. Mat ImagenFiltrada;  //Para la imagen binaria que resulta de inRange

Procedimiento para crear la GUI en QT

  1. Se agregarán al proyecto los siguientes elementos de salida y entrada. Nota2.

QT creator filtro de color con OpenCV inRange

 

2. – Se nombrarán a las 4 etiquetas principales, las 6 barras de desplazamiento y los 6 lcdNumber, de la siguiente manera:

  1. barraCanal0Max,  barraCanal0Min,  barraCanal1Max, barraCanal1Min, barraCanal2Max, barraCanal2Min,.
  2. labelColor, labelGauss, labelHSV, labelInrange.
  3. lcdCanal0Max, lcdCanal0Min, lcdCanal1Max, lcdCanal1Min, lcdCanal2Max, lcdCanal2Min.

 

3.- Para cada una de las barras se creará la función sliderMoved(int) en esta función se modificará el valor de los lcdNumber. Por ejemplo, para la barraCanal0Max:

  • void MainWindow::on_barraCanal0Max_sliderMoved(int position){
  • ui->lcdCanal0Max->display(position);
  • }

Esto se tiene que hace para cada una de las 6 barras con su lcd correspondiente.

4.- Se creará la función click para el botón y se agregará el siguiente código: (Si estas viendo este tutorial en un celular, tienes que abrir el siguiente enlace:).

5.- Se creará un cronometro para que sea ejecutado cada 100ms. Entonces este proceso esta dividido en dos pasos.

  1. Crear, conectar e iniciar el cronometro. Por ejemplo, las siguientes líneas se colocan despues de la instrucción setupUi del archivo MainWindow.cpp.
    1. QTimer *cronometro = new QTimer(this);
    2. connect(cronometro,SIGNAL(timeout()),this,SLOT(ftimer()));
    3. cronometro->start(100);
  2. Se creará la función ftimer, tanto en el código cpp como en la cabecera .h.
    1. void MainWindow::ftimer(){   }

6.- En la función del timer se colocará el siguiente código.

  1. void MainWindow::ftimer(){
  2. //Paso # 1 – Procesar imagen anterior para filtro doble
  3. f(!ImagenHSV.empty()){
  4. int canal0Min = ui->barraCanal0Min->value();
  5. int canal0Max = ui->barraCanal0Max->value();
  6. int canal1Min = ui->barraCanal1Min->value();
  7. int canal1Max = ui->barraCanal1Max->value();
  8. int canal2Min = ui->barraCanal2Min->value();
  9. int canal2Max = ui->barraCanal2Max->value();
  10. nRange(IMAGENchica,Scalar(canal0Min,canal1Min,canal2Min),Scalar(canal0Max,canal1Max,canal2Max),ImagenFiltrada);
  11. Image qImage = Mat2QImage(ImagenFiltrada);
  12. QPixmap pixmap = QPixmap::fromImage(qImage);
  13. ui->labelInrange->clear();
  14. ui->labelInrange->setPixmap(pixmap);
  15. }
  16. }

 

Código de MainWindow.cpp

https://hetpro-store.com/TUTORIALES/EjemplosProgramas/QT-OpenCV-9-inRange.zip

 

 

Nota1. Es recomendable copiar el código desde el enlace de Github que tiene este tutorial, de otro modo puede que los caracteres no se copien correctamente. 

Nota2. Se deben de modificar los valores máximos para las barras horizontales, para que sea 255. (valor máximo para los pixeles de 8 bits). 

Autor: Dr. Rubén Estrada Marmolejo

 

 

Escríbenos tus dudas o comentarios

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Usamos Cookies en nuestro sitio WEB

Por favor confirma, si aceptas nuestras cookies de rastreo. También puedes negar el uso de cookies de rastreo y seguir navegando sin que ninguna información sea enviada a servicios de terceros.