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.
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);
}
}
Ese código no compila. Si pretendes poner un for, no le metas un else después, y te falta el tercer parámetro (el incremento o decremento). Si pretendes que sea un if, te sobra el primer parámetro (la asignación).
Además, eso de "x <ImgOriginal> 150" no tiene sentido, ¿comparas números enteros con objetos? ¿haces dos comparaciones al mismo tiempo?
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?
Yo al menos no te entiendo muy bien. Intenta ser más específico.
(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++).
A no ser que dediques decenas o cientos de horas a optimizar todo el código, dudo mucho que notes mucha diferencia. Además en C++ seguramente tardes mucho más en encontrar librerías que te sirvan, implementarlo... y el código al final más que código parecerá una sopa de letras.
Por último decir que utilizo la libreria WebCAM.dll, hay alguna mejor?¿
No es que conozca muy bien todo esto, pero lo que puedes hacer es implementarlo todo desde cero (el otro día estuve mirando el código de esa librería y no es mucho) y hacerlo a tu gusto. Yo tuve que mirar el código porque quien haya implementado la librería metió todo el código dentro de un bloque try-catch que se come todas las excepciones y hace imposible depurar el programa.
Si me podeis ayudar a mejorar el rendimiento de los bucles, o alguna otra forma de hacerlo hos estaria agradecido. 😛
No te puedo dar una solución, pero lo que sí te puedo decir es que estoy casi seguro de que el problema de rendimiento es porque quieres procesar la imagen pixel a pixel, y eso es ejecutar tu código cientos de miles de veces en cada frame.
Otro problema habitual en estos casos (que no veo que tú tengas, pero por si acaso te lo digo) es instanciar objetos dentro de bucles que se ejecutan muchas veces y muy rápido, de manera que se generan miles de objetos por segundo y el rendimiento baja en picado.
ostias lo copié mal xDDD pera ahora pongo la versión k si compila.
(No se porqué pero no puedo pegar el código bueno, al poner vista previa o enviar se me come una parte del código).
Hay alguna forma de processar la imagen que no sea pixel a pixel?¿
Con calibrar el color me refiero a ese if que pongo aquí:
if (red > 200 && green > 20 && green <120> 20 && blue < 120)
Con ese if le digo al programa que color quiero que resalte. Mi pregunta era si habia alguna otra forma de hacerlo.
Muchas gracias.
Wolfskin, yo tiraría por una conversión del espacio de color... es decir en vez de usar las componentes RGB (red, green, blue) para definir un color puedes hacerlo en HSL (hue, saturation, luminance) con el que puedes definir colores mucho más facilmente (directamente en el hue) sin tener que preocuparte mucho de la saturación y de la luminosidad.
S2
Ranganok Schahzaman
Para procesar la imagen depende de lo que haga tu programa realmente y de la información que tengamos sobre el objeto a buscar.
Sin ninguna información, pensando que consiste en buscar el un objeto rojo de cualquier tamaño, puedes recorrer los píxeles cada 2 filas y cada 2 columnas en lugar de cada fila y columna (podría escaparse un objeto rojo de pixel x pixel pero captaría objetos más grandes), o incluso más filas o columnas si el objeto es más grande.