[ Foro de C ]

Programa Troll

29-Jan-2023 12:15
Invitado (Daniel)
2 Respuestas

Hola buenas, necesito ayuda con un programa que aplica un efecto de ruido o de espejo (inversión horizontal a una imagen.pgm de 400x400 píxeles dependiendo del argumento que se le introduzca ("noisy" o "mirror"). El problema es que aplica los efectos con las palabras cambiadas, y sí, he comprobado que las palabras estén bien puestas. De hecho hasta las he intercambiado y así funciona bien, pero me mosquea el hecho de que del código se entienda una cosa y el programa haga la opuesta.

paso el código y la docu de la librería externa que utiliza:


/*
 * File: efectos_repaso.c
 *
 * Description: Aplica distintos efectos sobre las imagenes.
 *
 * Author:  Daniel Villalón <danivillalongarcia@gmail.com>
 * Version: 2023-01-28
 *
*/

#include <stdio.h>
#include <stdlib.h>
#include "easypgm.h"
#include "time.h"
#include "string.h"
#include "stdbool.h"

#define WHITE               255
#define NOISE               129
#define ARGUMENTO           1
#define EFECTOESPEJO        "mirror"    //Estas son las que
#define EFECTORUIDO         "noisy"     //dan problemas.
#define IMPUTFILE           "fantasma.pgm"
#define OUTPUTFILENOISE     "noisyghost.pgm"
#define OUTPUTFILEMIRROR    "mirrorghost.pgm"

/**
 * @brief Aplica el efecto de ruido a la imagen introducida.
 * @param input_img, output_img La imagen a editar y el array que contendrá la versión editada.
 */
void efecto_ruido (unsigned char input_img [IMG_SIZE][IMG_SIZE], unsigned char output_img [IMG_SIZE][IMG_SIZE]);

/**
 * @brief Aplica el efecto de espejo a la imagen introducida (reflejo horizontal).
 * @param input_img, output_img La imagen a editar y el array que contendrá la versión editada.
 */
void efecto_espejo (unsigned char input_img [IMG_SIZE][IMG_SIZE], unsigned char output_img [IMG_SIZE][IMG_SIZE]);

int main (int argc, char * argv[]) {
    //Variables
    unsigned char input_buffer [IMG_SIZE][IMG_SIZE];
    unsigned char output_buffer [IMG_SIZE][IMG_SIZE];
    int greenlight;
    int efecto;
    char * filename = IMPUTFILE;
    //Algoritmo
    greenlight = read_image (IMPUTFILE, input_buffer);
    if (greenlight == 0)
    {
        //Condicional de activación del efecto de ruido
        if (strcmp (argv [ARGUMENTO], EFECTORUIDO))
        {
            efecto_ruido (input_buffer, output_buffer);
            filename = OUTPUTFILENOISE;
            write_image (filename, output_buffer);
        }
        //Condicional de activación del efecto espejo
        else if (strcmp (argv [ARGUMENTO], EFECTOESPEJO))
        {
            efecto_espejo (input_buffer, output_buffer);
            filename = OUTPUTFILEMIRROR;
            write_image (filename, output_buffer);
        }
        //Condicional de activación de control manual
        else 
        {
            printf("Imagen leída correctamente.\n\n");
            printf("(1): APLICAR RUIDO\n(2): APLICAR ESPEJO\n");
            scanf("%i", &efecto);
            switch (efecto)
            {
                case 1:
                    efecto_ruido (input_buffer, output_buffer);
                    filename = OUTPUTFILENOISE;
                    write_image (filename, output_buffer);
                    break;
                case 2:
                    efecto_espejo (input_buffer, output_buffer);
                    filename = OUTPUTFILEMIRROR;
                    write_image (filename, output_buffer);
                    break;
            }
        }
    }
    else
    {
        printf("ERROR");
        return -1;
    }
    return 0;
}
void efecto_ruido (unsigned char input_img [IMG_SIZE][IMG_SIZE], unsigned char output_img [IMG_SIZE][IMG_SIZE])
{
    //Variables
    int ruido = rand() % NOISE;
    //Algoritmo
    for (int i = 0; i < IMG_SIZE; i++)
    {
        for (int u = 0; u < IMG_SIZE; u++)
        {
            ruido = rand() % NOISE;
                if (ruido > WHITE)
                {
                    ruido = WHITE;
                }
            output_img [i][u] = input_img [i][u] + ruido;
        }
    }
}
void efecto_espejo (unsigned char input_img [IMG_SIZE][IMG_SIZE], unsigned char output_img [IMG_SIZE][IMG_SIZE])
{
    //Algoritmo
    for (int i = 0; i < IMG_SIZE; i++)
    {
        for (int u = 0; u < IMG_SIZE; u++)
        {
            output_img [i][u] = input_img [i] [IMG_SIZE - u];
        }
    }
}


Librería externa (libeasypmg.h):


/**
 * @file
 * @brief Funciones de ayuda para gestionar imagenes con formato pgm.
 * Versión simplificada de la librería que gestiona la cabecera de las imágenes de forma automática.
 *
 * Limitaciones conocidas:
 *  - la librería solo soporta imagenes de tamaño fijo (400x400 píxeles).
 *  - la librería solo soporta imágenes pgm creadas con la herramienta convert de la suite ImageMagick.
 *
 * Author:  Intro_SW
 * Version: 1.0
 *
*/

#include "intro.h"
/**
 * @name Constantes de la librería
 * Indican el formato y el tamaño del identificador soportados por la librería
 * @{
 */


#define IMG_TYPE_SIZE     2     /**< Tamaño del identificador de la imagen pgm */
#define IMG_SIZE        400     /**< Tamaño de imagen soportada (IMG_SIZE * IMG_SIZE) */

/** @} */

/**
 * @name Códigos de error de la librería
 * @{
 */

#define ERR_FICHERO_NO_ENCONTRADO   -1  /**< El fichero pgm no se ha encontrado */
#define ERR_FICHERO_NO_VALIDO       -2  /**< El fichero pgm no es válido */
#define ERR_FICHERO_ESCRITURA       -3  /**< No se ha podido escribir un fichero pgm */

/** @} */

/**
 * @brief Lee una imagen del disco duro y almacena la información
 * en el buffer
 * @param filename Nombre del fichero con la imagen pgm
 * @param buffer Array donde se almacena la información de la imagen
 * @returns 0 si la imagen se ha leido correctamente,
 *          las constantes ERR_FICHERO_NO_ENCONTRADO o ERR_FICHERO_NO_VALIDO en caso de error
 */
int read_image (string filename,
                unsigned char buffer [IMG_SIZE][IMG_SIZE]);


/**
 * @brief Escribe una imagen pgm en el disco duro.
 * @param filename Nombre del fichero donde almacenar la imagen pgm
 * @param buffer Array con la información de la imagen
 * @returns 0 si la imagen se ha escrito correctamente en el disco duro,
 *          la constante ERR_FICHERO_ESCRITURA en caso de error
 *
 */
int write_image (string filename,
                 unsigned char buffer [IMG_SIZE][IMG_SIZE]);


 


30-Jan-2023 12:16
Nacho Cabanes (+83)

Es que tu lógica de comprobación es incorrecta. La función "strcmp" devuelve 0 cuando las cadenas son iguales, como puedes ver aquí:

https://www.aprendeaprogramar.com/referencia/view.php?f=strcmp&leng=C

De modo que deberías hacer


if (strcmp (argv [ARGUMENTO], EFECTORUIDO) == 0) 



en vez de


if (strcmp (argv [ARGUMENTO], EFECTORUIDO))



porque, de lo contrario, un valor 0 se toma como "falso" (es decir, se da por sentado que la condición no se cumple).


14-Mar-2023 21:40
Invitado (Alejandro Andrade)

¡Hola! Parece que tienes un programa un tanto travieso en tus manos.

El problema está en las condiciones del if y else if que verifican si el argumento introducido es "noisy" o "mirror". En ambos casos, la condición está mal formulada, lo que significa que el efecto aplicado será el contrario al que se espera.

En la condición del efecto de ruido, deberías cambiar la condición strcmp(argv[ARGUMENTO], EFECTORUIDO) a strcmp(argv[ARGUMENTO], EFECTOESPEJO), ya que actualmente está aplicando el efecto de ruido cuando se introduce "mirror".

Por otro lado, en la condición del efecto de espejo, deberías cambiar la condición strcmp(argv[ARGUMENTO], EFECTOESPEJO) a strcmp(argv[ARGUMENTO], EFECTORUIDO), ya que actualmente está aplicando el efecto de espejo cuando se introduce "noisy".

Aquí te dejo el código con las condiciones corregidas:

greenlight = read_image (IMPUTFILE, input_buffer);
if (greenlight == 0)
{
   //Condicional de activación del efecto de ruido
   if (strcmp (argv [ARGUMENTO], EFECTOESPEJO) == 0) // Condición corregida
   {
       efecto_ruido (input_buffer, output_buffer);
       filename = OUTPUTFILENOISE;
       write_image (filename, output_buffer);
   }
   //Condicional de activación del efecto espejo
   else if (strcmp (argv [ARGUMENTO], EFECTORUIDO) == 0) // Condición corregida
   {
       efecto_espejo (input_buffer, output_buffer);
       filename = OUTPUTFILEMIRROR;
       write_image (filename, output_buffer);
   }
   //Condicional de activación de control manual
   else
   {
       printf("Imagen leída correctamente.\n\n");
       printf("(1): APLICAR RUIDO\n(2): APLICAR ESPEJO\n");
       scanf("%i", &efecto);
       switch (efecto)
       {
           case 1:
               efecto_ruido (input_buffer, output_buffer);
               filename = OUTPUTFILENOISE;
               write_image (filename, output_buffer);
               break;
           case 2:
               efecto_espejo (input_buffer, output_buffer);
               filename = OUTPUTFILEMIRROR;
               write_image (filename, output_buffer);
               break;
       }
   }
}

¡Espero que esto solucione tu problema!






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)