algoritmo de brillo para VHDL [cerrado]

0

Hola, estoy trabajando en un proyecto de procesamiento de imágenes en el que trato de cambiar el brillo de un píxel. El código que escribí funciona, pero no de la forma en que quiero que sea. Aquí está el segmento de código que utilizo para cambiar el brillo del píxel. Lo que sucede aquí es que verifico los valores RGB de un píxel para determinar si esos valores están abiertos para cambiar. Para atenuar el píxel, resto 1 y para resaltar el píxel agrego 1 a los valores RGB. Sin embargo, este enfoque da resultados muy feos. ¿Cómo puedo modificar el algoritmo que estoy usando? Por cierto, acabo de compartir la parte utilizada para el brillo. Otra parte (Contraste) no está incluida aquí. Ese es el motivo por el que el código parece incompleto. No soy experto ni conocedor del procesamiento de imágenes.

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;

entity Brightness_Contrast is
generic (
PICTURE_WIDTH_HEIGHT : integer := 250;
COLOR_BIT : integer := 4);
port (
clk_in : in  std_logic := '0';
operation : in std_logic_vector(1 downto 0);
rst: in std_logic;
data_in: in std_logic_vector(11 downto 0);
output_of_operation: out std_logic_vector(11 downto 0);
mode: in std_logic
);
end Brightness_Contrast;

architecture Behavioral of Brightness_Contrast is

signal check : std_logic_vector(11 downto 0) := (others => '0');

begin

       BRIGHTNESS_CONTRAST: process(rst,data_in,clk_in,operation,mode) is

       begin

       check <= data_in;

       if rst = '1' then

       check <= (others => '0');

       elsif rising_edge(clk_in) then --clk

              if operation = "00" then              

              if mode = '0' then 

              if check(3*COLOR_BIT-1 downto 2*COLOR_BIT) < "1110" then
              check(3*COLOR_BIT-1 downto 2*COLOR_BIT) <= ((check(3*COLOR_BIT- 
1 downto 2*COLOR_BIT)) + "0010");
              end if;

              if check(2*COLOR_BIT-1 downto COLOR_BIT) < "1110" then
              check(2*COLOR_BIT-1 downto COLOR_BIT) <= ((check(2*COLOR_BIT-1 
downto COLOR_BIT)) + "0010");
              end if;

              if check(COLOR_BIT-1 downto 0) < "1110" then
              check(COLOR_BIT-1 downto 0) <= ((check(COLOR_BIT-1 downto 0)) + 
"0010");
              end if;

              elsif mode = '1' then 

              if  check(3*COLOR_BIT-1 downto 2*COLOR_BIT) > "0001" then
              check(3*COLOR_BIT-1 downto 2*COLOR_BIT) <= ((check(3*COLOR_BIT- 
1 downto 2*COLOR_BIT)) - "0010");
              end if;

              if  check(2*COLOR_BIT-1 downto COLOR_BIT) > "0001" then
             check(2*COLOR_BIT-1 downto COLOR_BIT) <= ((check(2*COLOR_BIT-1 
downto COLOR_BIT)) - "0010");
              end if;

              if check(COLOR_BIT-1 downto 0) > "0001" then
              check(COLOR_BIT-1 downto 0) <= ((check(COLOR_BIT-1 downto 0)) - 
"0010");
              end if;   
 elsif operation = "01" then   

          if mode = '0' then  

          if   check(3*COLOR_BIT-1 downto 2*COLOR_BIT) < "1000" and  
check(3*COLOR_BIT-1 downto 2*COLOR_BIT) > "0001" then

          check(3*COLOR_BIT-1 downto 2*COLOR_BIT) <=  ((check(3*COLOR_BIT-1 
downto 2*COLOR_BIT)) - "0010"); 

          elsif  check(3*COLOR_BIT-1 downto 2*COLOR_BIT) > "0111" and 
check(3*COLOR_BIT-1 downto 2*COLOR_BIT) < "1110" then

          check(3*COLOR_BIT-1 downto 2*COLOR_BIT) <=  ((check(3*COLOR_BIT-1 
downto 2*COLOR_BIT)) + "0010") ;
          end if;

          if   check(2*COLOR_BIT-1 downto COLOR_BIT) < "1000" and  
check(2*COLOR_BIT-1 downto COLOR_BIT) > "0001" then

          check(2*COLOR_BIT-1 downto COLOR_BIT) <=  ((check(2*COLOR_BIT-1 
downto COLOR_BIT)) - "0010");

          elsif  check(2*COLOR_BIT-1 downto COLOR_BIT) > "0111" and  
check(2*COLOR_BIT-1 downto COLOR_BIT) < "1110" then

          check(2*COLOR_BIT-1 downto COLOR_BIT) <=  ((check(2*COLOR_BIT-1 
downto COLOR_BIT)) + "0010") ;
          end if;

          if   check(COLOR_BIT-1 downto 0) < "1000" and  check(COLOR_BIT-1 
downto 0) > "0001" then

          check(COLOR_BIT-1 downto 0) <=  ((check(COLOR_BIT-1 downto 0)) - 
"0010");

          elsif  check(COLOR_BIT-1 downto 0) > "0111" and  check(COLOR_BIT-1 
downto 0) < "1110" then

          check(COLOR_BIT-1 downto 0) <=  ((check(COLOR_BIT-1 downto 0)) + 
"0010") ;
          end if;                                      

          elsif mode = '1' then                    

          if  check(3*COLOR_BIT-1 downto 2*COLOR_BIT) < "1000" and 
check(3*COLOR_BIT-1 downto 2*COLOR_BIT) > "0010" then

          check(3*COLOR_BIT-1 downto 2*COLOR_BIT) <= ((check(3*COLOR_BIT-1 
downto 2*COLOR_BIT)) - "0011");

          elsif check(3*COLOR_BIT-1 downto 2*COLOR_BIT) > "0111" and 
check(3*COLOR_BIT-1 downto 2*COLOR_BIT) < "1101" then

          check(3*COLOR_BIT-1 downto 2*COLOR_BIT) <= ((check(3*COLOR_BIT-1 
downto 2*COLOR_BIT)) +"0011") ;
          end if;

          if  check(2*COLOR_BIT-1 downto COLOR_BIT) < "1000" and 
check(2*COLOR_BIT-1 downto COLOR_BIT) > "0010" then

          check(2*COLOR_BIT-1 downto COLOR_BIT) <= ((check(2*COLOR_BIT-1 
downto COLOR_BIT)) - "0011");

          elsif check(2*COLOR_BIT-1 downto COLOR_BIT) > "0111" and 
check(2*COLOR_BIT-1 downto COLOR_BIT) < "1101" then

          check(2*COLOR_BIT-1 downto COLOR_BIT) <= ((check(2*COLOR_BIT-1 
downto COLOR_BIT)) +"0011") ;
          end if;

          if  check(COLOR_BIT-1 downto 0) < "1000" and check(COLOR_BIT-1 
downto 0) > "0010" then

          check(COLOR_BIT-1 downto 0) <= ((check(COLOR_BIT-1 downto 0)) - 
"0011");

          elsif check(COLOR_BIT-1 downto 0) > "0111" and check(COLOR_BIT-1 
downto 0) < "1101" then

          check(COLOR_BIT-1 downto 0) <= ((check(COLOR_BIT-1 downto 0)) + 
"0011") ;
          end if;

          end if; --mode                      
          end if; --Operation                                                   
          end if; --CLK

          end process BRIGHTNESS_CONTRAST ;

          output_of_operation <= check;


 end Behavioral;
    
pregunta runo

4 respuestas

1

Esto no es una respuesta per se , pero no pude publicar comentarios, así que, un par de preguntas / comentarios para ti ... No he pasado mucho tiempo pensando esto, así que toma este FWIW y aplícalo como mejor te parezca:

  • ¿Estás simulando esto, o vas directamente a HW? Supongo que HW, ya que dijo "feo" ... usted realmente necesita simular su diseño para ver qué está sucediendo. No tienes visibilidad en HW.

  • Cada vez que se desplaza un bit, o se multiplica por 2 (SHL) o se divide por 2 (SHR) ... este es un detalle de implementación, pero un concepto fundamental en el diseño digital ... podría escribir tan fácilmente (newValue = value * 2 for SHL)

  • Recomiendo, antes de escribir HDL, dibuje esto en HW primero (puertas, FF, FSM, memorias, etc.) y asegúrese de que su diseño se vea correcto antes de escribir HDL. Escribir un código centrado en SW para HDL puede causarle problemas ... a veces puede salirse con la suya, pero, si en una clase de diseño digital, su profesor no se sienta impresionado ... bueno, de todos modos, no. / p>

  • Tal vez redúzcalo ... comente los 8 bits superiores, y simplemente opere en los 4 inferiores ... deshágase de todos los genéricos y escriba algo muy simple, codificado y más fácil de ver lo que está haciendo para tener confianza con lo que está haciendo

  • Tiene una condición de límite con la que no ha lidiado ... es posible desbordar sus valores de 4 bits cuando los agrega (y, por lo tanto, termina con un delta grande en el resultado cuando trunca el bits superiores por su asignación de 4 bits). (por ejemplo, 0xff + 0x2 = 0x101 = 0x01 para usted ... lo que significa que pasó de "blanco" a "negro") Además, está utilizando un entero de tipo que es un valor de 32 bits, por lo que tal vez obtenga valores negativos (?) puede usar std_logic_vectors e ignorar los bits de desbordamiento, o colocar un rango para su variable que use tipo entero (por ejemplo, rango = 1 a 4)

  • como parte de la viñeta anterior, ¿realmente necesita las 3 bibliotecas de matemáticas? Tal vez solo use std_logic_unsigned para evitar cualquier cosa negativa (?) usted ha señalado: use IEEE.NUMERIC_STD.all; use IEEE.std_logic_unsigned.all; use IEEE.std_logic_arith.all;

respondido por el CapnJJ
1

Para aumentar el brillo de un píxel, un método simple es multiplicar R, G, B de un píxel por una constante. Del mismo modo para disminuir el brillo, dividir por una constante.

Ya que estamos trabajando en VHDL, es conveniente elegir la constante para ser una potencia de 2.

\ $ C = 2 ^ n \ $

De modo que la multiplicación y la división sean simplemente operaciones de desplazamiento hacia la izquierda o hacia la derecha en n lugares.

    
respondido por el MITU RAJ
1

Tenga en cuenta que siempre se asigna una señal al final de un proceso y a la última declaración del proceso. Esto significa que en su caso check <= data_in solo se asignará si operation != 00 , de lo contrario, una de las otras asignaciones será la última en el proceso. Además, dice que operation y mode se controlan desde conmutadores externos. Tenga en cuenta que el proceso que tiene está cronometrado a varios MHz, significa que si presiona el botón durante 100 ms (lo que ya es súper rápido), el proceso se ha ejecutado miles de veces. Lo que necesitas es una detección de borde en la entrada de tu botón. ¿Puedes mostrar de dónde viene operation ?

Con respecto a las asignaciones de señal:

proc : process(rst, clk)
begin
  if (rst) then
    a <= '0';
    b <= '0';
  elsif rising_edge(clk) then
    a <= '1';
    b <= '1';
    b <= 'a';
  end if;
end process;

Entonces, si tiene un proceso como el anterior, las señales a y b se asignan al final del proceso, esto no se ejecuta secuencialmente como, por ejemplo, en java Esto significa que la asignación b <= '1' siempre se ignorará ya que la última asignación es b <= 'a' .

    
respondido por el Humpawumpa
0

Para alguien que no sabe absolutamente nada sobre el diseño de hardware o el procesamiento de imágenes, ciertamente ha saltado directamente al extremo profundo con un proyecto VHDL para procesar video en tiempo real.

El formato de pregunta y respuesta utilizado aquí en SE simplemente no es capaz de brindarle la educación que necesita para tener éxito. Debe tomar cursos y / o leer libros sobre los siguientes temas:

  • diseño de lógica digital
  • programación HDL
  • procesamiento de imágenes

... después de lo cual, podrías ser capaz de hacer preguntas específicas y específicas que realmente podríamos manejar aquí.

Recomendaría comenzar con el tema del procesamiento de imágenes y aprender a realizar las manipulaciones que desea utilizar con el software antes de intentar implementarlas en el hardware. Es posible que no necesite tener hardware personalizado en absoluto.

Ya que eres programador de Java (?), es posible que desees consultar ImageJ . Es un conjunto de herramientas basadas en Java para la manipulación de imágenes. También puede utilizar una herramienta más general, como Gnu Octave , que podría brindarle más información sobre cómo funciona el nivel bajo. Las operaciones están codificadas.

    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas