como-usar-opencv-en-net-con-opencvsharp

Cómo usar OpenCV en .NET con OpenCVSharp

OpenCVSharp es un wrapper para .NET de la librería de visión artificial OpenCV que nos permite usarla de forma cómoda desde una aplicación de .NET en Windows, Linux, macOS o WASM.

Como sabemos OpenCV es la librería más popular para aplicaciones de visión artificial. Es Open Source bajo licencia BSD y multiplataforma, y está escrita en C++. Tenéis más información en la página del proyecto https://opencv.org/ y todo el código en Github.

Sin embargo, existen distintos wrapper y adaptaciones que nos permiten usar OpenCV desde otros lenguajes de programación, e integrarlos en nuestras aplicaciones. Estas sencillez de uso tiene un coste, en forma de penalización en rendimiento frente a emplear directamente las librerías de C++.

Probablemente wrapper más conocido es Opencv-python, un wrapper de OpenCV para Python, por la gran abundancia de tutoriales que existen sobre el mismo. Sin embargo, no es el único, ni necesariamente el mejor.

Hoy vamos a ver OpenCVSharp, que nos permite emplear OpenCV desde una aplicación de .NET de forma muy sencilla, tanto en instalación como en uso. Igualmente OpenCVSharp es un proyecto Open Source, distribuido bajo licencia Apache 2.0, y su código está disponible en https://github.com/shimat/opencvsharp.

Esto tiene la ventaja de poder usar un lenguaje potente como C# en nuestras aplicaciones de visión artificial, así como poder integrarlo fácilmente en nuestras aplicaciones de .NET. Imaginad lo que ello supone en cuanto a acceso de hardware, comunicación, escritura en bases de datos, gestión de archivos. Combinar OpenCV con “cualquier cosa” que podamos hacer en .NET (es decir, todo).

OpenCVSharp está disponible en todas las plataformas compatibles con .NET, es decir, puede ejecutarse tanto en Windows (WinForms, WPF y UWP), Linux (Ubuntu), macOS, LinuxARM (Raspberry Pi y similares) y WASM (web assembly).

La instalación es muy sencilla ya que se realiza a través de paquetes Nuget que incluyen todo lo necesario para ejecutar OpenCVSharp. Estos paquetes incluyen los binarios de OpenCV. Únicamente deberemos bajarnos el paquete Nuget adecuado a nuestra arquitectura. Podéis consultar la relación completa en la página del proyecto.

Por otro lado, para que el rendimiento sea el más cercano al uso directo de las librerías de C++, OpenCVSharp hace uso intensivo de unmanaged code. Esto tiene como consecuencia que deberemos ser especialmente cuidadosos al hacer ‘Dispose’ de los objetos creados para evitar fugas de memoria, como también explican en la documentación del proyecto.

Finalmente, existe este repositorio de ejemplos de uso de OpenCVSharp. Es muy recomendable echarle un vistazo, porque incluye ejemplos de casi todos los tutoriales y casos de uso habituales, incluidas aplicaciones que incluyen captura de cámara tanto en WinForms como WPF.

Proyecto de ejemplo en OpenCVSharp

Vamos a ver cómo usar OpenCVSharp en un proyecto sencillo, un “Hola Mundo” de visión artificial. Para ello usaremos la imagen de “Lena”, que por motivos históricos, es la imagen más empleada en pruebas y prototipos de aplicaciones de vision artificial.

lena

Os recomiendo descargar la imagen de internet a mejor calidad. Para el blog tengo que reducir las imágenes de calidad, para que pesen menos y no penalicen el tráfico.

En nuestro caso usaremos Windows y Visual Studio. En primer lugar, cogemos nuestra imagen “Lena.jpg” y la copiamos a una ubicación, por ejemplo “C:\temp”. A continuación, creamos una nueva solución para una aplicación de escritorio en WPF Core.

Para añadir OpenCVSharp a nuestra solución, únicamente tenemos que añadir el paquete Nuget adecuado a nuestra arquitectura. En nuestro caso, necesitamos únicamente el Nuget OpenCvSharp4.Windows, que incluye todo lo necesario para funcionar, sin necesidad de ningún paquete o fichero adicional.

csharp-opencvnet-nuget

Ahora, abrimos nuestro fichero window.cs, que es la ventana principal del proyecto que acabamos de crear, y sustitimos el código por este.

public partial class MainWindow : System.Windows.Window
{
  public MainWindow()
  {
    InitializeComponent();
    
    string imagePath = @"C:\temp\lena.jpg";
    using var src = new Mat(imagePath, ImreadModes.Grayscale);
    using var dst = new Mat();
    
    Cv2.Canny(src, dst, 50, 200);
    using (new OpenCvSharp.Window("src image", src))
    using (new OpenCvSharp.Window("dst image", dst))
    {
      Cv2.WaitKey();
    }
  }
}

En WPF las ventanas gráficas son de la clase Window. Igualmente, las ventanas gráficas de OpenCV también se llaman Window. Por este motivo ha habido que completar el nombre, respectivamente, a System.Window y OpenCVSharp.Window

Si en lugar de haber creado una aplicación de escritorio WPF Core hubiéramos creado una aplicación de consola .NET Core, el código hubiera sido el siguiente.

static void Main(string[] args)
{
  string imagePath = @"C:\temp\lena.jpg";
  Mat src = new Mat(imagePath, ImreadModes.Grayscale);

  Mat dst = new Mat();

  Cv2.Canny(src, dst, 50, 200);
  using (new OpenCvSharp.Window("src image", src))
  using (new OpenCvSharp.Window("dst image", dst))
  {
    Cv2.WaitKey();
  }
}

En este código de ejemplo, simplemente estamos cargando la imagen desde su ubicación, y cargándola en la imagen (Mat) ‘src’ en escala de grises. A continuación, aplicamos un filtro de Canny y la guardamos en una nueva imagen ‘dst’.

lena-grayscale

Ahora, ejecutamos el programa y veremos aparecer nuestras dos imágenes, Lena en escala de grises, y el resultado del filtro Canny, que es un detector de contornos sencillo (más información del filtro Canny en Wikipedia)

lena-canny

Así de sencillo, simplemente añadiendo un paquete Nuget, podemos usar OpenCV en una aplicación .NET en cualquier plataforma. Nuevamente os recomiendo mirar el repositorio de ejemplos, porque es la mejor forma de aprender a usar OpenCVSharp.