1. Title
Display Image file Using VGA Port in Basys-3
2. Category
"Video Processing"
3. Key Concepts
이미지에서 RGB 값을 추출하고, 이를 이용하여 Lenna 이미지를 Display한다.
4. Setup
Video Processing 분야에서 가장 자주 등장하는 Lenna 이미지다. 이번 글에서는 Lenna 이미지를 VGA로 출력하는 방법을 단계별로 정리해본다.
- Lenna 이미지를 VGA 해상도(320x240)에 맞게 변환
- 이미지를 BMP 포맷으로 저장후, 각 픽셀의 값을 확보
- ROM에 이미지를 저장하고, VGA 컨트롤러를 통해 화면에 출력
Basys-3 보드는 RGB 4-4-4 포맷을 지원한다. 이는 5-6-5 포맷에서 상위 4비트를 추출하면 비슷한 색상 값을 얻을 수 있기에, 우선 bmp 이미지를 5-6-5 포맷으로 변환한다.
변환된 이미지 파일은 아래와 같이 행렬로 나타나게 된다.
각 픽셀에 대한 R,G,B 값을 5비트 6비트 5비트씩 가지고 있는 행렬맵이다. 이를 추출하게 되면
assign image_444 = {image_565[15:12], image_565[10:7], image_565[4:1]}; // red, green, blue
5. Code Review
module vga_test (
input logic clk,
input logic reset,
input logic [1:0] sw_mode,
input logic [3:0] sw_red,
input logic [3:0] sw_green,
input logic [3:0] sw_blue,
output logic h_sync,
output logic v_sync,
output logic [3:0] red_port,
output logic [3:0] green_port,
output logic [3:0] blue_port
);
logic [9:0] x_pixel;
logic [9:0] y_pixel;
logic display_enable;
logic [11:0] sw_rgb_port, pattern_rgb_port;
logic [15:0] image_565;
logic [11:0] image_444;
vga_controller U_VGA_Controller (.*);
vga_sw_rgb U_VGA_SW_RGB (
.*,
.red_port (sw_rgb_port[3:0]),
.green_port(sw_rgb_port[7:4]),
.blue_port (sw_rgb_port[11:8])
);
vga_test_pattern U_VGA_Pattern (
.*,
.red_port (pattern_rgb_port[3:0]),
.green_port(pattern_rgb_port[7:4]),
.blue_port (pattern_rgb_port[11:8])
);
image_rom U_IMAGE_ROM(
.addr(y_pixel * 320 + x_pixel),
.data(image_565)
);
assign image_444 = {image_565[15:12], image_565[10:7], image_565[4:1]}; // red, green, blue
always_comb begin
case (sw_mode)
2'b00: {blue_port, green_port, red_port} = sw_rgb_port;
2'b01: {blue_port, green_port, red_port} = pattern_rgb_port;
2'b10: {blue_port, green_port, red_port} = {image_444[3:0], image_444[7:4], image_444[11:8]};
endcase
end
endmodule
VGA는 640x480 해상도이고, 출력하려는 이미지 사이즈는 QVGA(320x240) 이미지이기 때문에 여러 개의 이미지가 출력되는 문제가 나타난다.
VGA 해상도인 640x480에서 QVGA 이미지를 출력하려면, VGA 타이밍과 해상도에 맞게 이미지의 배치를 조정해야 한다.
always_comb begin
case (sw_mode)
2'b00: {blue_port, green_port, red_port} = sw_rgb_port;
2'b01: {blue_port, green_port, red_port} = pattern_rgb_port;
2'b10: begin
if(x_pixel >320 | y_pixel > 240)
{blue_port, green_port, red_port} = 0;
else
{blue_port, green_port, red_port} = {image_444[3:0], image_444[7:4], image_444[11:8]};
end
endcase
end
endmodule
이제 Color 이미지를 Gray Scale로 변환하는 방식을 알아보자. Gray Scale로 변환하는 공식은 다음과 같다.
하드웨어 상에서 실수형의 연산은 어렵다. 이를 구현하기 위해서는 R,G,B 에 곱해지는 실수에 255를 곱하여 양자화를 시킨다.
assign image_444 = {image_565[15:12], image_565[10:7], image_565[4:1]}; // red, green, blue
assign image_444_gray_scale_accum = {image_444[11:8] * 'h4d + image_444[7:4] * 'h96 + image_444[3:0] * 'h1d};
- Red에 0.21을 곱하고, 이를 255로 양자화하여 0.21 * 255 = 53.55 → 정수로 변환하면 0x4D
- Green에 0.72을 곱하고, 이를 255로 양자화하여 0.72 * 255 = 183.6 → 정수로 변환하면 0x96
- Blue에 0.07을 곱하고, 이를 255로 양자화하여 0.07 * 255 = 17.85 → 정수로 변환하면 0x1D
assign image_444_gray_scale = {image_444_gray_scale_accum[11:8], image_444_gray_scale_accum[11:8], image_444_gray_scale_accum[11:8]};
이후, Gray Scale 값을 각 채널에 동일하게 적용하여 출력한다. Basys-3는 4비트의 출력방식을 사용하기 때문에 최상위 비트 4비트만을 R,G,B에 적용시켜준다.
'AI SOC COURSE > 영상 처리' 카테고리의 다른 글
Video Course Review - 05. CDC (Clock Domain Crossing) (0) | 2025.03.28 |
---|---|
Video Course Review - 04. OV7670 SCCB (0) | 2025.03.20 |
Video Course Review - 03. Up Scaling, OV7670 (0) | 2025.03.19 |
Video Course Review - 01. VGA Port (0) | 2025.03.17 |