Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Buenas a todos.
Estos últimos días he estado haciendo programillas de visión artificial en C#.
Estoy haciendo un programa que me filtre el color rojo y que solo se vea en la imagen un globo de color rojo.
Tengo dos problemas.
El primero es que el rendimiento del programa es nefasto, dibujo un fotograma cada 2 o 3 segundos. Me gustaria saber si hay alguna otra forma de filtrar un color. Yo lo hice pintando los pixels que no sean de color rojo de color negro.
namespace FiltroRGB
{
public partial class FFiltrar : Form
{
public FFiltrar()
{
InitializeComponent();
}
private void BEmpezar_Click(object sender, EventArgs e)
{
WebCam1.Start();
PMuestra.Image = WebCam1.Imagen;
}
private void BParar_Click(object sender, EventArgs e)
{
TMuestreo.Enabled = false;
WebCam1.Stop();
}
private void BFiltrar_Click(object sender, EventArgs e)
{
TMuestreo.Enabled = true;
}
private void TMuestreo_Tick(object sender, EventArgs e)
{
PMuestra.Image = WebCam1.Imagen;
Bitmap ImgOriginal = new Bitmap(PMuestra.Image);
Bitmap ImgFinal = new Bitmap(PMuestra.Image);
int red, green, blue;
int x, y;
for (y = 0; y < ImgOriginal.Height; y++)
{
for (x = 0; x <ImgOriginal> 150 && green < 80 && blue < 80)
{
ImgFinal.SetPixel(x, y, Color.Red);
}
else
{
ImgFinal.SetPixel(x, y, Color.Black);
}
}
}
PMuestra.Image = ImgFinal;
}
}
}
El segundo problema es la calibración de los colores. xD Me estoy volviendo loco para calibrar el rojo, hay alguna forma de poder hacerlo sin tener que poner los valors RGB que quieres filtrar?
(Según lo que he estado leyendo lo ideal sería utilizar punteros en C++, pero de momento prefiero utilizar C#, cuando el rendimiento me esté matando pues me pasaré a C++).
Por último decir que utilizo la libreria WebCAM.dll, hay alguna mejor?¿
Si me podeis ayudar a mejorar el rendimiento de los bucles, o alguna otra forma de hacerlo hos estaria agradecido. 😛
Saludos y gracias.
Wolfskin, lo que te propone jorcoval y Urriellu es el teorema de Nyquist aplicado a 2 dimensiones.
S2
Ranganok Schahzaman
Pues yo use punteros y me olvide de setpixel y getpixel.
Hice pruebas hace mas de dos años con punteros e imagenes y lo más rápido que encontré fue mapear directamente la memoria del Bitmap, tanto para leer como para escribir, con punteros y me olvidé de las funciones que llevan especificas para eso.
Te dejo la idea:
ptrGrafico=(BYTE*)pBitmap->ScanLine[287]; el puntero byte apunta al principio del grafico
HLScolores=RGBtoHLS(ptrGrafico[x+2],ptrGrafico[x+1],ptrGrafico[x]);
luego recorremos con el bucle x el grafico pasando a estructura HLS con la funcion RGBtoHLS.
Bueno esto es una manera de hacerlo que en su día me fue bastante bien.
No trabajé con la libreria WebCam.dll así que no tengo referencia.
Con respecto a trabajar con RGB y HLS primero trabajé el RGB con algoritmos sencillos de umbrales, B/N, bordes,(para aprender) etc y despues pase al HLS. Una de las ventajas que tiene es que más inmune a cambios de luminosidad, uno de los principales problemas con la cámara. El problema es que el algoritmo de conversion RGB->HLS HLS->RGB usa raices cuadradas y funciones de "peso". Aunque eso con los actuales procesadores no hay problema . Y si tienes memoria pues haciendo una matriz de 3*(256x256x256) bytes te ahorras el tiempo de conversion aunque esa rutina aún no la he implementado.(ni creo que la haga de momento).
Como referencia supongo que habrás visto el hilo de Mif de vision artificial. Todos los que hemos tocado algo de vision hemos terminado posteando en el hilo.
Por supuesto que usando punteros es más rápido, pero el código queda bastante más ofuscado y sobre todo te saltas un montón de comprobaciones que hacen el lenguaje tan seguro como es. Los punteros en C# están ahí y se pueden usar en determinadas ocasiones, pero como regla general y sobre todo si eres novato mejor no usarlos.
La verdad es que el C# para proyectos de tiempo real o que necesiten una gran cantidad de procesado no es la mejor opción. Sólo hay que ver que las librerías de procesado de imagen de intel están hechas en ensamblador directamente.
Yo usaria C++ o C.
S2
Ranganok Schahzaman