• Publicidad

Detectar número de figuras

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Notapor Zeokat » 2008-08-07 20:09 @881

Conseguí hacer lo siguiente...

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @x_no = (9); #Le doy valor 9 inicial, porq sino me lanza un warning undef, no se si hay otra forma de solucionarlo
for my $i ( 0 .. $width-1 ) {
    for my $j (0 .. $height-1) {
        my $index = $image->getPixel($i,$j);
        if ($index != 16777215 && $i != $x_no[$#x_no]) {
            push (@x_no, $i);
        }
    }
}

shift(@x_no); #quito el elemento q era basura

my @coordenadas;
push(@coordenadas, $x_no[0]); #pongo el principio de la primera figura
for my $i (0 ..  $#x_no) {
    if (defined($x_no[$i+1]) && $x_no[$i]+1 < $x_no[$i+1]) { #Comparando diferencias entre las coordenadas, si se "alejan" 1 o mas esque hay una linea blanca por el medio
        push(@coordenadas, $x_no[$i], $x_no[$i+1]);
    }
}
push(@coordenadas, $x_no[$#x_no]); #pongo el final del ultimo caracter

#Compruebo.
foreach my $elemento (@coordenadas) {
    print "$elemento\n";
}
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4


Bien tengo el array @coordenadas con la coordenada principio/fin de cada figura.
Ahora tendría que manejar los elementos del array de dos en dos (principio_carácter-fin_carácter), para crear nuevas imágenes en las qué pintar cada figura de forma individual. A ver si lo soluciono...
Zeokat
Perlero nuevo
Perlero nuevo
 
Mensajes: 125
Registrado: 2006-08-22 08:08 @380

Publicidad

Notapor explorer » 2008-08-08 12:09 @548

Hay unos errores en mi programa, y muy graves.

1.- la función trueColor() solo sirve para indicar que vamos a crear la imagen usando componentes de color, y no un sistema de paleta de colores. Pero en este caso no estamos creando una imagen, sino que la estamos leyendo. Así que esta función no nos sirve.

2.- la función getPixel() no devuelve el color (en sus componentes rojo, verde y azul), sino el índice dentro de la paleta de colores de a qué color pertenece ese pixel. Hay que usar la función rgb() para conocer sus componentes.

Analizando la imagen, resulta que las figuras (obviando los bordes) se componen del color número 0, que corresponde, en la paleta, a un nivel de rojo de 4, 2 de verde y 4 de azul (sería el color #040204).

Entonces, no vamos a usar la paleta de colores, sino que tenemos que analizar las componentes de color de cada píxel. Y consideraremos, en este caso, que los píxeles de las figuras serán aquellos que tengan componentes inferiores o iguales, numéricamente, a 4.

Entonces, el programa queda así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;

use GD;
use constant LIMITE_COLOR => 0x04;

my $fichero_imagen = $ARGV[0] or die "Uso: $0 <imagen a procesar>\n";

my $gd_imagen = GD::Image->new($fichero_imagen);
my ($ancho,$alto) = $gd_imagen->getBounds();
print "Dimensiones: $ancho x $alto\n";

## Leemos la imagen, aplanándola, a una lista, representando cada una de las columnas.
## Un '1' es que sí había píxeles negros (figura)
## Un '0' es que no había
my $columnas;

## Para todas las columnas
for my $i ( 0 .. $ancho -1 ) {

    my $hay_pixeles_de_figura;     # Hay o no hay

    ## Para todas las filas de esa columna
    for my $j (0 .. $alto -1) {

        my  $color_pixel_paleta = $gd_imagen->getPixel($i,$j);
        my ($color_pixel_rojo, $color_pixel_verde, $color_pixel_azul) = $gd_imagen->rgb($color_pixel_paleta);
        #my  $color_pixel = uc sprintf "%02x%02x%02x", $color_pixel_rojo, $color_pixel_verde, $color_pixel_azul;
        #print ">$i;$j: $color_pixel_paleta: ($color_pixel_rojo, $color_pixel_verde, $color_pixel_azul) $color_pixel\n";

        if (    $color_pixel_rojo  <= LIMITE_COLOR
            and $color_pixel_verde <= LIMITE_COLOR
            and $color_pixel_azul  <= LIMITE_COLOR
        ) {
            $hay_pixeles_de_figura = 1; # ponemos la bandera a 1
            last;                       # no necesitamos mirar más
        }
    }

    ## Guardamos el resultado de esa columna, como un dígito
    $columnas .= ($hay_pixeles_de_figura) ? 1 : 0;
}

print "$columnas\n";

$columnas .= 0;    # Para ayudar a la segunda regex, en caso de
                   # que exista una figura en la última columna

## Ayudas visuales
for my $x ( 0 .. length($columnas) -1) {
    print int $x++ / 10;
}
print "\n";
for my $x ( 0 .. length($columnas) -1) {
    print $x++ % 10;
}
print "\n";

## Ahora averiguamos cuántas figuras hay
my $numero_figuras = () = $columnas =~ /1+/g;   # Buscamos cuántos bloques de '1' hay
print "Hay $numero_figuras figuras\n";

## Y ahora hay que saber en qué posiciones empiezan y terminan
if ($numero_figuras) {

    ## Lo que hacemos es buscar la combinación '01' para saber el comienzo
    while ( $columnas =~ m/(^|0)1/g ) {
        print "Posición inicial: ";
        print pos($columnas)-1;
        print "\n";
    }

    ## y la combinación '10' para saber el final de cada figura
    while ( $columnas =~ m/10/g ) {
        print "Posición final: ";
        print pos($columnas)-2;
        print "\n";
    }
}

__END__
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
La salida es la misma que antes.

El porqué funcionaba antes es porque, por pura coincidencia, el color que obteníamos con getPixel() era el 0 (número de color 0 dentro de la paleta de colores) y ese valor se comparaba con lo que creíamos que eran los componentes de color de las figuras (NEGRO => 0x000000). Como numéricamente son iguales, pues entonces obteníamos la salida correcta. Pero era pura casualidad. No estaba asegurado que funcionara de la misma manera con otras imágenes.

Como ejemplo relacionado con tu código (que también está mal), estás mirando si el valor de getPixel() coincide con 0xFFFFFF. Bueno, pues resulta que la imagen del ejemplo, los píxeles de color blanco, en realidad, no son blancos, sino que tienen de valor 0xFCFEFC, correspondiente al color 34 de la paleta de colores, siendo ese número (34) el valor que te está devolviendo getPixel().

El ejercicio debería indicar si debemos mirar las componentes de color o la paleta de colores. Y qué color (o qué componentes) son las que definen a las figuras. Como mínimo, indicar la diferencia entre figura y fondo.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor explorer » 2008-08-09 07:23 @349

Esta es otra solución, parecida a la que intentas tu. Se trata de ir recordando en dónde nos encontramos en cada momento.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

use GD;

use strict;
use warnings;
use diagnostics;

## Inicialización
my $fichero_imagen = $ARGV[0] or die "Uso: $0 <imagen a procesar>\n";
my $gd_imagen = GD::Image->new($fichero_imagen);
my ($ancho,$alto) = $gd_imagen->getBounds();
print "Dimensiones: $ancho x $alto\n";

## Contadores e indicadores
my $numero_figuras;
my $estamos_en_figura;
my $hay_pixeles_de_figura;

## Proceso
$estamos_en_figura = 0;
for my $i (0 .. $ancho-1) {

    $hay_pixeles_de_figura = 0;
    for my $j (0 .. $alto -1) {

        if ($gd_imagen->getPixel($i,$j) == 0) {        # Si el pixel es el negro
            $hay_pixeles_de_figura++;
        }
    }

    if ($hay_pixeles_de_figura) {
        if (!$estamos_en_figura) {
            $estamos_en_figura = 1;
            print "Inicio: $i\n";
        }
    }
    else {
        if ($estamos_en_figura) {
            $estamos_en_figura = 0;
            print "Final : ", $i-1, "\n";
            $numero_figuras++;
        }
    }
}

if ($estamos_en_figura) {
    print "Final : ", $ancho-1, "\n";
    $numero_figuras++;
}

print "Hay $numero_figuras figuras\n";

__END__
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
La salida es:
Código: Seleccionar todo
Dimensiones: 90 x 25
Inicio: 6
Final : 19
Inicio: 37
Final : 51
Inicio: 67
Final : 80
Hay 3 figuras
Notar que estamos suponiendo que las figuras se componen de píxeles del color número 0 de la paleta de colores.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Anterior

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados