Fusion là thuật toán xử lý ảnh hữu ích và được ứng dụng nhiều trong thực tế. Trong đồ án tốt nghiệp, em đã xây dựng IP Core thực hiện hai phương pháp Fusion theo chuẩn vào ra Avalon Video Streaming Interface – giao thức thường được dùng trong các IP Core xử lý ảnh/video được cung cấp bởi Intel (Altera). Phương pháp Gaussian Pyramid Decomposition trên một vài tập dataset thử nghiệm có thể thấy khá nhiều nhiễu trong khi đó hướng tiếp cận với Saliency extraction và LEP filter có kết quả tốt hơn đáng kể. Em đã tìm hiểu và xây dựng hệ thống SoC, viết chương trình thực hiện các thử nghiệm thực tế trên môi trường Linux với tập dataset gồm rất nhiều ảnh liên tục có kích thước 640x480. Kết quả thử nghiệm trực tiếp được trên board tương tự kết quả mô phỏng trên sơ đồ khối Simulink đã xây dựng, và qua quan sát có thể thấy kết quả hình ảnh đầu ra khá tốt. Cuối cùng, một vài thông số về thời gian, năng lượng được so sánh khi thực hiện giữa CPU và FPGA nhằm mục đích tham khảo
AVALON INTERFACES
Giới thiệu Avalon Interfaces
Tài liệu Avalon Interface Specifications của Intel cung cấp thông tin chi tiết về 7 interface bao gồm:
- Avalon Streaming Interface (Avalon-ST): truyền dữ liệu theo một chiều, không quan tâm đến địa chỉ dữ liệu, thường là dữ liệu ảnh, video, các tín hiệu số…
- Avalon Memory Mapped Interface (Avalon-MM): đọc/ghi dữ liệu dựa trên địa chỉ, thường dùng để đọc ghi các thanh ghi điều khiển/trạng thái hoặc các vùng nhớ như RAM, ROM…
- Avalon Interrupt Interface: tín hiệu ngắt để điều khiển các module khác
- Avalon Clock Interface: tín hiệu clock
- Avalon Reset Interface: tín hiệu reset
- Avalon Conduit Interface: tín hiệu hoặc nhóm các tín hiệu không nằm trong các interface bên trên, thường là các tín hiệu riêng biệt dùng để ghép nối với các tín hiệu từ IP Core khác
- Avalon Tri-state Conduit Interface: tín hiệu kết nối tới các ngoại vi bên ngoài FPGA (input hoặc output).
Avalon Streaming/Video Streaming Interface
- Avalon Video Streaming là interface được sử dụng trong các IP Core xử lý dữ liệu ảnh/video được cung cấp sẵn bởi Intel Do vậy để sử dụng cũng như thiết kế các IP Core xử lý số cho FPGA Intel cần tìm hiểu rõ interface này
- Các tín hiệu được sử dụng trong Avalon Video Streaming Interface:
Hình 2: Avalon Video Streaming Interface
+ Dữ liệu truyền theo một chiều từ bên Source -> Sink
+ Không có bus thông tin địa chỉ (address), luồng dữ liệu được truyền một cách liên tục giữa 2 bên Source và Sink
- Ý nghĩa của các tín hiệu:
Tín hiệu Ý nghĩa startofpacket Báo hiệu bắt đầu của 1 packet (ví dụ với dữ liệu ảnh là pixel đầu tiên của 1 frame) endofpacket Báo hiệu kết thúc của 1 packet (ví dụ với dữ liệu ảnh là pixel cuối cùng của 1 frame) data Dữ liệu được truyền/nhận giữa 2 bên (ví dụ với dữ liệu ảnh là 8 bit grayscale tương ứng với 1 pixel của ảnh) empty Cho biết số lượng symbol trong gói dữ liệu đang truyền cuối cùng
(tương ứng với endofpacket) là không hợp lệ valid Báo hiệu dữ liệu đang truyền là hợp lệ ready Báo hiệu trạng thái có thể nhận dữ liệu hay không
Bảng 1: Avalon Video Streaming Interface Signals
- Ví dụ về quá trình truyền dữ liệu theo đặc tả Avalon Video Streaming:
Hình 3: Avalon Streaming Interface Signals Waveform
+ Tín hiệu startofpacket ở mức cao trong 1 chu kỳ duy nhất ứng với gói dữ liệu đầu tiên
+ Tín hiệu endofpacket ở mức cao trong 1 chu kỳ duy nhất ứng với gói dữ liệu cuối cùng
+ Tín hiệu valid ở mức cao trong khi bên gửi (Source) đang gửi ra dữ liệu
+ Tín hiệu ready ở mức cao trong khi bên nhận (Sink) có thể nhận dữ liệu, tín hiệu này có độ trễ là 1 chu kỳ, nên sau khi bên nhận (Sink) có ready ở mức cao, thì 1 chu kỳ sau tín hiệu valid từ bên gửi (Source) mới ở mức cao, tương tự khi bên nhận (Sink) chuyển trạng thái ready sang mức thấp
- Trong công cụ Qsys, khi tự tạo thêm các IP Core tự thiết kế, ta có thể sắp xếp, định nghĩa các interface tương ứng với ý nghĩa của nó:
Hình 4: Avalon Streaming Interface IP Design Example
- Với IP Core được thiết kế như trên, có thể thấy bao gồm các loại Avalon Interface sau đây:
+ Avalon Streaming Interface: data1_sink và data2_sink (tương ứng hai đầu vào) và data_source (đầu ra)
IP Core thực hiện xử lý tính toán với đầu vào là Avalon Video Streaming và đầu ra cũng là Avalon Video Streaming Ở mục 3 & 4 sẽ nói chi tiết về thuật toán nằm bên trong IP Core này.
BOARD DE2i-150 và DE1-SoC
DE2i-150
- DE2i-150 được xây dựng dựa trên kiến trúc nền tảng kết hợp giữa bộ xử lý Intel CPU N2600 với Altera Cyclone IV GX FPGA, được kết nối với nhau qua hai đường bus PCIe Gen1 x1 Kit được tích hợp FPGA với gần 150K phần tử logic và khả năng kết nối với rất nhiều ngoại vi bên ngoài: Video In/Out, Ethernet, TV Decoder, HSMC…
DE1-SoC
Hình 7: DE1-SoC Block Diagram
- DE1-SoC Development Kit được xây dựng trên nền tảng Altera System- on-Chip (SoC) FPGA Ngoài các phần từ logic khả cấu hình, Cyclone V còn được tích hợp sẵn ARM-based hard processor system (HPS) chứa bộ vi xử lý, các interface giao tiếp ngoại vi bên ngoài và memory… HPS và FPGA được kết nối với nhau qua các high-bandwidth interconnect backbone, do vậy tốc độ truyền dữ liệu qua lại rất cao Kit cũng chứa đầy đủ các thành phần từ bộ nhớ DDR3 high-speed, Video in/out, Ethernet, ADC…
So sánh
- So sánh tài nguyên trên FPGA giữa 2 board:
DE2i-150 (Cyclone IV EP4CGX150DF31)
DE1-SoC (Cyclone V SoC 5CSEMA5F31C6)
CPU Intel® Atom™ Dual Core
Dual-core ARM Cortex-A9 800 MHz
Bảng 2: So sánh tài nguyên FPGA trên DE2i-150 và DE1-SoC
THUẬT TOÁN FUSION
Thuật toán
- Convolution là thao tác được áp dụng chủ yếu trong hai thuật toán Fusion nói riêng cũng như rất nhiều phương pháp xử lý ảnh khác nói chung
- Các thao tác biến đổi trên ảnh hay dò tìm đặc trưng của ảnh được thực hiện thông qua việc lọc ảnh, bản chất chính là thực hiện các phép nhân chập (convolution) trên ảnh
- Khi đó, để thực hiện một phép biến đổi hay dò tìm đặc trưng trên ảnh, chúng ta chỉ cần tiến hành “nhân chập” ảnh đầu vào với một ma trận hay cửa sổ nhân chập gọi là
“kernel” Toàn bộ các pixel trên ảnh sẽ được tiến hành nhân chập với cửa sổ nhân chập (tâm của cửa sổ nhân chập sẽ được đặt trùng vào vị trí của pixel đang được tính nhân chập), làm thay đổi giá trị của pixel ban đầu
- Dưới đây là công thức tính nhân chập:
+ X(m,n) là ma trận ban đầu của ảnh kích thước mxn
+ H(k,l) là ma trận hạt nhân của phép nhân chập hay còn gọi là mặt nạ
+ Y(m,n) là ma trận đầu ra của phép nhân chập giữa X và H
- Trên FPGA, IP Core thực hiện convolution nhận vào các pixel lần lượt theo chiều từ trái sang phải, từ trên xuống dưới, do vậy cần line buffer đóng vai trò lưu trữ lại các pixel để thực hiện nhân chập, ví dụ: ảnh đầu vào có kích thước 640x480 và kernel có kích thước 3x3, đến khi pixel hàng 3 cột 3 được đưa vào thì phép nhân chập mới hoàn thành xong cho pixel đầu tiên ảnh đầu ra
- Ví dụ line buffer với ảnh đầu vào 5x5 như dưới đây:
- Với kernel kích thước 3x3, line buffer cần có kích thước như dưới đây:
*** Trạng thái line buffer lần lượt từ pixel đầu tiên:
(Pixel đầu vào đầu tiên) (Pixel đầu vào thứ hai)
(Tính xong pixel đầu ra đầu tiên) (Tính xong pixel đầu ra thứ hai)
Hình 13: Line buffer progress states
- Phương pháp dùng Gaussian Pyramid dựa trên ý tưởng biểu diễn ảnh dưới nhiều độ phân giải (multi-resolution) tương ứng với các tỷ lệ (scale) khác nhau, khái niệm pyramid ở đây bao gồm một chuỗi ảnh, trừ ảnh ở level 0 là ảnh gốc thì các ảnh phía sau có được bằng cách lấy ảnh ở mức trước đó down-sample một hệ số bằng 2 (hay kích thước mỗi chiều giảm đi một nửa) rồi áp dụng bộ lọc Gaussian (kích thước 5x5):
Trong đó k = 1, 2…N, 𝐺 = I là ảnh gốc, 𝜔 là filter kernel (Gaussian) Phép xử lý này thường được gọi là thao tác REDUCE:
- Laplacian Pyramid thu được bằng phép trừ ảnh trừ hai level liên tiếp của Gaussian Pyramid, vì ảnh ở hai level liên tiếp đó có kích thước khác nhau, nên để trừ được ta cần thực hiện up-sample lại để có sự tương đồng về mặt kích thước:
- Để thực hiện thuật toán Fusion với đầu vào là hai ảnh thu được từ camera thường và camera nhiệt, ta thực hiện tính toán Laplacian Pyramid trên ảnh nhiệt, expand lại nếu kích thước ảnh trên các level nhỏ hơn ảnh gốc về lại kích thước ban đầu rồi cộng với ảnh từ camera thường đầu vào
- Khi triển khai trên FPGA, thay vì việc xây dựng các IP Core để thực hiện các thao tác REDUCE, EXPAND, ta áp dụng thuật toán àtrous để đơn giản hóa các thao tác về phép nhân chập (convolution) thông thường nhưng với bộ lọc Gaussian được chèn vào các hàng, các cột có giá trị 0 Như vậy với level đầu tiên Gaussian kernel có kích thước gốc là 5x5, level tiếp theo có kích thước 9x9 (vì chèn thêm vào giữa các hàng, cột ban đầu một hàng, một cột chỉ chứa giá trị 0), tiếp theo nữa là 17x17… Thuật toán àtrous giúp tránh được việc down-sample với mỗi level trên Gaussian Pyramid trước khi thực hiện nhân chập, đồng thời vì ảnh đầu ra có kích thước giống với ảnh đầu vào nên thao tác up-sample khi kết hợp thông tin cũng có thể được bỏ qua
- Sau khi tính toán xong Laplacian Pyramid với ảnh nhiệt, thực hiện cộng các level với ảnh camera thường đầu vào, ta thu được ảnh Fusion đầu ra
1.2.1 Triển khai thuật toán trên MATLAB
- Dưới đây là mã nguồn cài đặt thử nghiệm thuật toán trên MATLAB:
% Thư mục dataset folder = '/home/tunglt/Fusion/TRI_A3/frames'; imagefiles = dir(fullfile(folder, '*.bmp'));
% Hiển thị ảnh kết quả trong quá trình tính toán figure;
% Lưu lại video đầu ra v = VideoWriter('ADWT_A3.avi'); open(v);
% Duyệt từng ảnh trong tập dataset for n = 1:length(imagefiles) currentfile = imagefiles(n).name;
% Đọc ảnh img = imread(fullfile(folder, currentfile));
% Ảnh thường vis = cast(img(:,:,1), 'double');
% Ảnh nhiệt ir = cast(img(:,:,3), 'double');
% Tạo Laplacian pyramid với 3 level level = 3; w = zeros([size(ir), level]); p = zeros([size(ir), level]);
% Khởi tạo ảnh đầu ra là ảnh thường imOut = vis; for i = 1:level
% Chèn 0 vào giữa các hàng, cột để mở rộng kích thước % bộ lọc từ 5x5 ra thành 9x9 và 17x17 a = zeros(2^(i-1)*(size(h)-1)+1); a(1:2^(i-1):end, 1:2^(i-1):end) = h;
% Nhân chập ảnh nhiệt với bộ lọc Gaussian p(:,:,i) = filter2(a, ir, 'same');
% Trừ ảnh đầu vào với ảnh đầu ra w(:,:,i) = ir - p(:,:,i);
% Ảnh sau nhân chập là đầu vào cho tính toán Laplacian % pyramid ở mức kế tiếp ir = p(:,:,i);
% Cộng hiệu số với ảnh thường để tạo ảnh fusion imOut = imOut + w(:,:,i); end
% Hiển thị ảnh đầu ra out = uint8(imOut); imshow(out);
% Lưu lại video writeVideo(v, out); end
1.2.2 Kết quả trên một vài tập dataset
- Dưới đây là kết quả khi chạy thử nghiệm mã nguồn đã trình bày trên MATLAB: Ảnh thường Ảnh nhiệt Ảnh Fusion
Hình 15: Kết quả thuật toán Gaussian pyramid decomposition trên MATLAB
1.3 LEP filter và Saliency extraction
- LEP Filter (local edge-preserving) có tác dụng làm trơn ảnh ngoại trừ các cạnh Ký hiệu I là ảnh đầu vào và B là ảnh được làm trơn B thu được từ I bằng cách tối ưu hóa công thức (5):
+ 𝜔 là vùng cửa sổ áp dụng bộ lọc LEP
+ |∇ | là hệ số cân bằng hai đại lượng
+ 𝛽 xác định độ nhạy (sensitivity) đối với gradient của ảnh
+ 𝛼 là tham số tự do
- Ý nghĩa: nếu giá trị gradient của I lớn (tại các cạnh), hệ số
|∇ | sẽ có giá trị nhỏ, và
B sẽ tương tự với I tại các vị trí đó, do vậy các cạnh sẽ được giữ lại Ngược lại, nếu giá trị gradient của I nhỏ, hệ số
|∇ | sẽ có giá trị lớn, đại lượng thứ hai trong công thức sẽ được tối ưu, tạo ra ảnh B được làm trơn Giả sử B được biểu diễn theo công thức (6):
- Với 𝑎 và 𝑏 là các hệ số hằng trong cửa sổ 𝜔 Thay thế B trong công thức (5) bởi công thức (6) và theo quy tắc đạo hàm hàm hợp ta có:
- Việc tối ưu công thức (7) được thực hiện bằng cách tính các đạo hàm riêng và đặt bằng 0 rồi giải tìm nghiệm tối ưu, từ đó ta có:
Trong đó 𝜎 là phương sai của I trong cửa sổ 𝜔 Mỗi cửa sổ chứa N điểm ảnh, vậy đầu ra của bộ lọc LEP là giá trị trung bình N giá trị của 𝐵:
Trong đó Ω là một vùng ảnh, 𝑎 là trung bình của 𝑎 trong cửa sổ lân cận, tương tự
- Saliency extraction dùng cho việc tính toán trọng số để kết hợp thông tin hai ảnh từ camera thường và camera nhiệt với ý nghĩa trên ảnh nhiệt, điểm ảnh có giá trị càng lớn thì có trọng số càng cao (áp dụng với ảnh nhiệt white-hot, có thể áp dụng tương tự với ảnh black-hot) Công thức tính toán trọng số cho điểm ảnh có giá trị 𝑎 của ảnh nhiệt như sau:
Trong đó 𝑓 là tần suất xuất hiện của điểm ảnh 𝑎 tương ứng, và:
- Các hệ số 𝑺(𝒂 𝒎 ) được chuẩn hóa để giá trị nằm trong đoạn [0; 1] Ảnh đầu ra được kết hợp dựa trên công thức:
+ 𝐵 ảnh nhiệt sau khi áp dụng LEP filter
+ 𝑆 trọng số của ảnh nhiệt
+ 𝐵 ảnh thường sau khi áp dụng LEP filter
1.3.1 Triển khai thuật toán trên MATLAB
- Dưới đây là mã nguồn cài đặt thử nghiệm thuật toán trên MATLAB: clearvars; close all; clc
% Infrared and visible image fusion via saliency analysis and local
% edge-preserving multi-scale decomposition
% Thư mục dataset folder = '/home/tunglt/Fusion/TRI_B4/frames'; imagefiles = dir(fullfile(folder, '*.bmp'));
% Hiển thị ảnh kết quả trong quá trình tính toán figure;
% Lưu lại video đầu ra v = VideoWriter('Saliency_v1.avi'); open(v);
% Duyệt từng ảnh trong dataset for n = 1:length(imagefiles) currentfile = imagefiles(n).name; img = imread(fullfile(folder, currentfile));
% Ảnh thường vis = cast(img(:,:,1), 'double');
% Ảnh nhiệt ir = cast(img(:,:,3), 'double');
% Loại bỏ viền đen của ảnh ir = ir(8:468, 11:631);
% Resize lại về kích thước 640x480 ban đầu ir = imresize(ir, [480 640]);
% Các hệ số LEP Filter filtSize = [3, 3]; alpha = 0.1; beta = 1;
% Áp dụng LEP Filter lên hai ảnh đầu vào
% Đầu ra là 𝐵 trong công thức (9)
[p_vis, ~] = localedgepreserve(vis, filtSize, alpha, beta); [p_ir, ~] = localedgepreserve(ir, filtSize, alpha, beta);
% Saliency extraction, tính các hệ số để kết hợp hai ảnh
% Tính histogram của ảnh nhiệt histo = imhist(uint8(ir))/numel(ir); graylevel = (0:255)'; weight_ir = zeros(size(ir));
% Tính các hệ số 𝑆(𝑎 ) theo công thức (10) và (11) for i = 1:length(histo) temp = graylevel(i) - graylevel; temp(temp < 0) = 0; weight_ir(uint8(ir) == graylevel(i)) = sum(histo.*temp); end
% Chuẩn hóa lại các hệ số trong khoảng từ 0 1 weight_ir = weight_ir/max(weight_ir(:));
% Tính ảnh kết hợp từ hai ảnh theo công thức (12) imOut = weight_ir.*p_ir + (1 - weight_ir).*p_vis; out = uint8(ir);
% Hiển thị ảnh kết quả imshow(out);
% Ghi lại vào video writeVideo(v, out); end
% Đóng tệp video close(v); function [B, meana, varI] = localedgepreserve(A, filtSize, alpha, beta)
% Tạo bộ lọc trung bình meanFilter = ones(filtSize)/prod(filtSize);
% Tính trung bình ảnh meanI = imfilter(A, meanFilter, 'replicate');
% Tính trung bình bình phương ảnh corrI = imfilter(A.*A, meanFilter, 'replicate');
% Tính gradient và trung bình gradient gradI = imgradient(A, 'Sobel'); meanG = imfilter(gradI.^(2 - beta), meanFilter, 'replicate');
% Tính phương sai ảnh varI = corrI - meanI.*meanI;
% Tính các hệ số a, b a = varI./(varI + alpha.*meanG + 1e-6); b = meanI - a.*meanI;
% Tính a trung bình, b trung bình meana = imfilter(a, meanFilter, 'replicate'); meanb = imfilter(b, meanFilter, 'replicate');
1.3.2 Kết quả trên một vài tập dataset
- Dưới đây là kết quả khi chạy thử nghiệm mã nguồn đã trình bày trên MATLAB: Ảnh thường Ảnh nhiệt Ảnh Fusion
Hình 16: Kết quả thuật toán LEP filter & Saliency extraction trên MATLAB
Phương pháp triển khai trên FPGA
- Các IP Core đều được xây dựng tương thích với chuẩn Avalon Video Streaming
Interface Việc xây dựng IP Core với chuẩn đầu vào/ra này có nhiều lợi ích như:
+ Đơn giản, dễ triển khai vì dữ liệu truyền theo một chiều từ Source -> Sink, không quan tâm đến địa chỉ dữ liệu
+ Intel (Altera) hỗ trợ sẵn rất nhiều IP Core xử lý ảnh/video, đọc ghi bộ nhớ RAM, hiển thị VGA… tương thích với chuẩn Avalon, ta có thể dùng trực tiếp những IP
Core đó trong hệ thống tổng thể triển khai trên board thực tế về sau
- IP Core thực hiện thuật toán Fusion sẽ bao gồm 2 đầu vào Avalon Video
Streaming Sink và 1 đầu ra Avalon Video Streaming Source
2.1 Sơ đồ khối Gaussian pyramid decomposition
- Dưới đây là sơ đồ theo thuật toán Gaussian pyramid decomposition tương ứng với mã nguồn đã trình bày trong phần 1.2.1 sẽ thiết kế trên FPGA:
Hình 17: Sơ đồ khối tổng quan Gaussian pyramid decomposition
- Các khối Gaussian 5x5, Gaussian 9x9, Gaussian 17x17 thực hiện nhân chập Gaussian với kích thước tương ứng
- Ảnh đầu ra của các khối nhân chập được trừ đi từ ảnh đầu vào, và cộng với ảnh thường để tạo ảnh fusion
- Các khối nhân chập hoạt động đồng thời, các pixel được đưa vào tuần tự và liên tục từ đầu vào tới đầu ra
2.2 Sơ đồ khối LEP filter & saliency extraction
- Dưới đây là sơ đồ theo thuật toán LEP filter và saliency extraction sẽ thiết kế:
Hình 18: Sơ đồ khối tổng quan LEP filter và saliency extraction
- Khối LEP filter bao gồm:
Hình 19: Sơ đồ tổng quan khối LEP filter
+ Ta tạo hai bộ nhớ RAM, mỗi cái gồm 256 ô nhớ (ảnh 8 bit tương đương 256 mức xám từ 0 đến 255) để tính toán histogram và tính các trọng số được chuẩn hóa về [0 1] dùng để tạo ảnh fusion về sau:
Hình 20: Sơ đồ tổng quan khối tính trọng số
+ Ảnh thường và ảnh nhiệt sau LEP filter được đưa vào khối kết hợp để tạo ảnh Fusion đầu ra dựa trên trọng số đã tính toán
Hình 21: Sơ đồ tổng quan khối combine
2.3 Sơ đồ khối tổng quan của hệ thống
- Dưới đây là sơ đồ ghép nối giữa IP Core Fusion và các module khác trên hệ thống hoàn chỉnh cuối cùng chạy trên board DE2i-150 để thử nghiệm Với board DE1- SoC hoàn toàn tương tự vì nhìn chung cả hai đều theo kiến trúc SoC, nhưng thay vì bus PCIe như DE2i-150, DE1-SoC có hệ thống bus high-bandwidth interconnect backbone tốc độ cao giữa FPGA và HPS
- Sơ đồ tổng quan hệ thống hoàn chỉnh:
Hình 22: Sơ đồ tổng quan hệ thống hoàn chỉnh
- IP Core IP Compiler PCIe thực hiện theo chuẩn giao thức PCIe để truyền dữ liệu qua lại giữa CPU và FPGA, các Base Address Register (BAR1, BAR2) được dùng để ghép nối với bus điều khiển của các IP Core khác và từ đó CPU có thể điều khiển các IP Core này bằng cách đọc/ghi giá trị các thanh ghi qua bus PCIe
- Hai ảnh đầu vào được gửi từ RAM (HPS/CPU) qua đường bus PCIe Gen1 x1 đến hai vùng nhớ khác nhau trên SDRAM, IP Core Scatter-Gather DMA trên FPGA nhận lệnh từ CPU để làm nhiệm vụ truyền dữ liệu này
- Các IP Core Video DMA có hai mode: Memory To Avalon-ST (mode 1) hoặc Avalon-ST To Memory (mode 2), để đọc dữ liệu từ SDRAM, ta cấu hình mode 1, dữ liệu sẽ được gửi ra theo đúng giao thức Avalon Video Streaming Source, ngược lại để ghi dữ liệu ra SDRAM, ta cấu hình mode 2
- IP Core Clipper làm nhiệm vụ padding ảnh đầu vào giá trị 0 xung quanh viền ảnh, ta thêm vào IP Core này vì trong quá trình thực hiện nhân chập kích thước ảnh sẽ bị giảm đi, ta cần giữ lại theo đúng chuẩn 640x480 để hiển thị ra VGA
- Khối hiển thị VGA bao gồm hai IP Core là Frame Reader và Clocked Video Output Frame Reader đọc ảnh từ SDRAM và gửi ra theo giao thức Avalon Video Streaming Source cho IP Core Clocked Video Output để tạo các tín hiệu đầu ra VGA theo đúng chuẩn, bao gồm các tín hiệu: R, G, B, HSync, VSync
- Ở phần sau, ta sẽ nói về cơ chế thêm vào một switch để chuyển đổi hình ảnh hiển thị đầu ra trên màn hình VGA theo cơ chế polling, cho phép người dùng lựa chọn hiển thị kết quả của hoặc thuật toán Fusion thứ nhất hoặc của thuật toán Fusion thứ hai.
TRIỂN KHAI THUẬT TOÁN TRÊN FPGA
Tổng quan về công cụ Altera DSP Builder
Hình 23: Công cụ Altera DSP Builder trên môi trường Simulink
- Công cụ Altera DSP Builder được tích hợp trực tiếp vào môi trường Simulink trên MATLAB, tạo ra khả năng triển khai thiết kế FPGA theo mô hình sơ đồ khối (block-diagram) Hơn nữa, việc kiểm thử thiết kế được thực hiện trực tiếp trong môi trường MATLAB, ta có thể viết chương trình trên MATLAB để tạo dữ liệu đầu vào và kiểm tra dữ liệu đầu ra, áp dụng các hàm được xây dựng sẵn trên MATLAB để xử lý và hiển thị dữ liệu, hoặc sử dụng module Scope trong Simulink
- Bên cạnh đó, công cụ cung cấp sẵn các phần tử và IP Core cơ bản được tối ưu riêng cho Altera FPGA, từ bộ mux, demux, delay, dịch bit, so sánh tới các phần tử phức tạp hơn như counter, multiplier, adder, RAM, ROM…
- Với từng IP Core, ta có thể cấu hình các tham số để tối ưu nhất với từng thiết kế và thuật toán cụ thể
- Công cụ cho phép thêm (import) các IP Core khác được xây dựng bằng ngôn ngữ HDL vào để sử dụng trong thiết kế
- Hiện tại, công cụ chỉ hỗ trợ generate ra mã nguồn VHDL hoặc SystemVerilog Các thông tin về tài nguyên, khả năng đáp ứng điều kiện timing của thiết kế cũng được đưa ra trong quá trình generate
Hình 24: Một vài IP Core sẵn có trên Altera DSP Builder
Hình 25: Cấu hình các tham số bộ nhân trên Altera DSP Builder
Triển khai
- IP Core với đầu vào là Avalon Video Streaming, nhận vào lần lượt từng điểm ảnh của mỗi frame theo thứ tự từ trái sang phải, từ trên xuống dưới
- Sơ đồ khối mức top của IP Core thực hiện nhân chập Gaussian 5x5 với đầu vào và đầu ra đều là Avalon Video Streaming:
Hình 26a: Sơ đồ mức top của GaussianFilter
- Bên trong khối GaussianFilter bao gồm các khối khác, LineBuffer thực hiện lưu trữ các pixel để thực hiện nhân chập, MultiplierAccumulator thực hiện nhân, cộng các pixel, GenerateSignals tạo các tín hiệu theo chuẩn Avalon Video Streaming:
Hình 26b: Sơ đồ bên trong của GaussianFilter
Hình 26c: Sơ đồ bên trong của LineBuffer
Hình 26d: Sơ đồ bên trong của Multiplier Accumulator
(Các hệ số trong Gaussian Kernel 5x5)
*** Với các phép nhân với số dạng 2 , ta thay thế bằng phép dịch trái, làm như vậy giúp tiết kiệm tài nguyên trên FPGA
Hình 26e: Sơ đồ bên trong của GenerateSignals
- Để generate ra mã VHDL, click đúp vào biểu tượng , lựa chọn dòng chip FPGA đang sử dụng, và nhấn Compile Sau đó chương trình sẽ chạy và hiển thị một vài thông số về timing:
Hình 27: Giao diện generate mã nguồn VHDL
2.2 IP Core Gaussian Pyramid Decomposition
- Sơ đồ khối mức top level của phương pháp Fusion thực hiện theo thuật toán Gaussian pyramid decomposition đã trình bày trong phần III, mục 1.2:
Hình 28a: Sơ đồ mức top thuật toán Fusion theo thuật toán 1
- Sơ đồ mức tiếp theo bên trong khối Fusion:
Hình 28b: Sơ đồ bên trong khối Fusion theo thuật toán 1
- Các khối Decomposition_1, Decomposition_2, Decomposition_3 trong sơ đồ tương tự nhau, thực hiện lần lượt nhân chập Gaussian với các bộ lọc kích thước 5x5, 9x9 và 17x17, do vậy chỉ khác ở phần line buffer
Hình 28c: Sơ đồ bên trong khối Decomposition_1
- Các khối bên trong tính toán nhân chập ảnh với Gaussian 5x5 và đưa ra kết quả ảnh đầu ra theo chuẩn Avalon Video Streaming Interface đã trình bày trong mục b
2.3 IP Core LEP filter & Saliency extraction
- Sơ đồ khối mức top level của phương pháp Fusion thực hiện theo thuật toán LEP filter và Saliency extraction đã trình bày trong phần III, mục 1.3:
Hình 29a: Sơ đồ mức top thuật toán Fusion theo thuật toán 2
Hình 29b: Sơ đồ bên trong khối Fusion theo thuật toán 2
- Mục tiêu đầu tiên là tính các hệ số 𝒂 𝝎 và 𝒃 𝝎 theo công thức (8), các khối Cal_Magnitude_1 được dùng để tính giá trị |𝛁𝑰 𝒊 | trong công thức (8) cho ảnh 1, tương tự Cal_Magnitude_2 tính cho ảnh 2:
- Bên trong khối Cal_Magnitude_1 (tính độ lớn gradient của ảnh bằng các bộ lọc
Sobel, tương tự với Cal_Magnitude_2):
Hình 29c: Sơ đồ bên trong khối Cal_Magnitude_1
- Lưu ý ở đây gradient được tính xấp xỉ theo công thức:
- Bộ lọc Sobel chứa các hệ số khá đặc biệt, để thực hiện chỉ cần các bộ dịch bit, bộ đảo dấu, khối cal_grad_x:
Hình 29d: Sơ đồ khối cal_grad_x
Hình 29đ: Sơ đồ khối cal_grad_y
- Các khối line_buffer và generate_signals có cấu trúc và mục đích tương tự như đã trình bày trước đó:
Hình 29e: Sơ đồ khối line_buffer trong khối tính gradient
Hình 29f: Sơ đồ khối generate_signals trong khối tính gradient
- Vẫn với mục đích tính các hệ số 𝒂 𝝎 và 𝒃 𝝎 từ công thức (8), khối Cal_A_B_1 và
Cal_A_B_2 chứa các khối con tính 𝝈 𝝎 𝟐 (phương sai ảnh) và 𝑰 𝒘 (trung bình ảnh)
Ngoài ra còn có các khối cộng, trừ, chia bổ sung để kết hợp các đại lượng tính toán cho ra giá trị 𝒂 𝝎 và 𝒃 𝝎 cuối cùng
Hình 29g: Sơ đồ bên trong khối Cal_A_B_1
- Lưu ý là 𝝈 𝝎 𝟐 = 𝑰 𝒘 𝟐 − 𝑰 𝒘 (14) Sơ đồ bên trong khối Cal_MeanI_VarI dùng để tính trung bình 𝑰 𝒘 và phương sai 𝝈 𝝎 𝟐 (dùng bộ lọc trung bình) của ảnh:
Hình 29h: Sơ đồ bên trong khối Cal_MeanI_VarI
- Sơ đồ bên trong khối CorrI (tính 𝑰 𝒘 𝟐 trong công thức (14)):
Hình 29i: Sơ đồ bên trong khối CorrI
- Sơ đồ khối line_buffer của khối CorrI:
Hình 29j: Sơ đồ khối line_buffer của CorrI
- Sơ đồ khối multiplier_accumulator của khối CorrI:
Hình 29k: Sơ đồ khối multiplier_accumulator của CorrI
- Sơ đồ bên trong khối MeanI (tính 𝑰 𝒘 trong công thức (14)):
Hình 29l: Sơ đồ bên trong khối MeanI
- Sơ đồ khối line_buffer của khối MeanI:
Hình 29m: Sơ đồ khối line_buffer của MeanI
- Sơ đồ khối multiplier_accumulator của khối MeanI:
Hình 29n: Sơ đồ khối multiplier_accumulator của MeanI
- Ngoài ra, giá trị |𝛁𝑰 𝒊 | trong công thức (8) cũng được áp bộ lọc trung bình để tính ra giá trị |𝛁𝑰 | trước khi tính ra 𝒂 𝝎 và 𝒃 𝝎 cuối cùng Sơ đồ bên trong khối tính trung bình gradient Cal_MeanG:
Hình 29o: Sơ đồ bên trong khối Cal_MeanG
- Sơ đồ khối line_buffer của khối Cal_MeanG:
Hình 29p: Sơ đồ khối line_buffer của Cal_MeanG
- Sơ đồ khối multiplier_accumulator của khối Cal_MeanG:
Hình 29q: Sơ đồ khối multiplier_accumulator của Cal_MeanG
- Sơ đồ khối generate_signals của khối Cal_A_B_1:
Hình 29r: Sơ đồ khối generate_signals của Cal_A_B_1
- Cuối cùng, khối Cal_Image_Out_1 làm nhiệm vụ tính toán các hệ số 𝒂, 𝒃 và ảnh đầu ra B trong công thức (9) cho ảnh 1, tương tự với Cal_Image_Out_2 cho ảnh 2):
Hình 29s: Sơ đồ bên trong khối Cal_Image_Out_1
- Sơ đồ bên trong khối MeanA (tính 𝒂 trong công thức (9)):
Hình 29t: Sơ đồ bên trong khối MeanA
- Sơ đồ khối line_buffer của khối MeanA:
Hình 29u: Sơ đồ khối line_buffer của MeanA
- Sơ đồ khối multiplier_accumulator của khối MeanA:
Hình 29v: Sơ đồ khối multiplier_accumulator của MeanA
- Sơ đồ bên trong khối MeanB (tính 𝒃 trong công thức (9)):
Hình 29w: Sơ đồ bên trong khối MeanB
- Sơ đồ khối line_buffer của khối MeanB:
Hình 29x: Sơ đồ khối line_buffer của MeanB
- Sơ đồ khối multiplier_accumulator của khối MeanB:
Hình 29y: Sơ đồ khối multiplier_accumulator của MeanB
- Để kết hợp thông tin từ hai ảnh đầu ra sau LEP filter, khối Cal_Weight tính toán trọng số từ histogram của ảnh nhiệt để kết hợp tạo ảnh đầu ra theo các công thức (10), (11) và (12):
Hình 29z: Sơ đồ khối Cal_Weight
Kiểm thử testbench
- DSP Builder cho phép kiểm thử trực tiếp thiết kế trên môi trường MATLAB/Simulink, ta chỉ cần viết mã nguồn tạo dữ liệu đầu vào phù hợp với yêu cầu trong thực tế, chạy mô phỏng với dữ liệu đó và viết mã kiểm tra dữ liệu đầu ra, có thể dùng các hàm vẽ biểu đồ, hiển thị hình ảnh để tăng tính trực quan
- Trong quá trình thiết kế, ta kiểm thử từng module nhỏ, rồi đến các module lớn hơn được kết hợp từ các module nhỏ đó, sau đó là cả hệ thống tổng thể cuối cùng Như vậy phần nào tính toán sai sẽ được phát hiện nhanh chóng để sửa đổi thay vì chờ đến cuối cùng, bởi thời gian chạy testbench trên cả hệ thống cuối cùng bao gồm nhiều khối tính toán sẽ lâu hơn
- Có thể thấy trong thuật toán Fusion áp dụng rất nhiều phép toán Convolution Testbench được viết trên MATLAB để kiểm tra thiết kế cho khối Convolution đã làm trong phần IV, mục 2.1 như sau, trước tiên là tạo dữ liệu đầu vào Simulink:
% anh tu camera thuong vis = I(:,:,1);
% anh tu camera nhiet ir = I(:,:,3);
% padding vien anh voi gia tri 0 vis = padarray(vis, [2 2], 0, 'both'); ir = padarray(ir, [2 2], 0, 'both');
[nrws ncls] = size(ir); offset = 100;
% khoi tao cac dau vao cho Simulink t = 1:ncls*nrws + offset; pixel_in.signals.values = (1:ncls*nrws+offset)'; valid_in.signals.values = (1:ncls*nrws+offset)'; sof_in.signals.values = (1:ncls*nrws+offset)'; eof_in.signals.values = (1:ncls*nrws+offset)'; pixel_in.time = t; valid_in.time = t; sof_in.time = t; eof_in.time = t; pixel_in.signals.values(1:end) = 0; valid_in.signals.values(1:end) = 0; sof_in.signals.values(1:end) = 0; eof_in.signals.values(1:end) = 0; for i=1:nrws for j=1:ncls pixel_in.signals.values((i-1)*ncls+j+1) = ir(i,j); valid_in.signals.values((i-1)*ncls+j+1) = 1; end end eof_in.signals.values(1) = 1; sof_in.signals.values(2) = 1; eof_in.signals.values(ncls*nrws+1) = 1; valid_in.signals.values(ncls*nrws+1:ncls*nrws+offset) =
% thong bao loi neu anh khong ton tai alt_dspbuilder_error('Unable to locate the image image_in.jpg'); disp([' > Unable to locate the image image_in.jpg']); end
- Click vào nút trên Simulink để chạy thử thiết kế với dữ liệu vừa tạo, sau khi chạy xong ta có thể chạy script dưới đây để kiểm tra đầu ra:
% vi tri dau frame anh dau ra start_index = find(sof_out==1); start_index = start_index(1);
% vi tri cuoi frame anh dau ra end_index = find(eof_out==1); end_index = end_index(2);
% cac pixel nam trong anh dau ra pixel_out = pixel_out(start_index:end_index); valid_out = valid_out(start_index:end_index); pixel_out = pixel_out(find(valid_out==1));
% thay doi anh ve dang ma tran 640x480 img_out = round(reshape(pixel_out, 640, 480)');
% hien thi anh dau ra figure, imshow(uint8(img_out));
- Kết quả ảnh đầu vào và ảnh đầu ra sau khi chạy mô phỏng trên Simulink:
Hình 30: Ảnh đầu vào và đầu ra sau khi nhân chập (chạy mô phỏng trên Simulink)
Một vài thông số cài đặt, cấu hình các khối tính toán
- Các khối sẵn có được cung cấp trong công cụ Altera DSP Builder giúp việc triển khai thiết kế được thực hiện nhanh chóng và linh hoạt, đồng thời được tối ưu riêng cho FPGA của hãng Dưới đây giới thiệu một số khối được sử dụng phổ biến trong hai thuật toán Fusion bên trên
- Khối Delay/Memory Delay: tạo trễ tín hiệu hoặc line buffer lưu trữ các pixel ảnh
Hình 31: Khối Delay/Memory Delay
+ Các tham số có thể cấu hình: số chu kỳ trễ, tín hiệu enable, clear port, giá trị khởi tạo khi reset, tham chiếu Embedded memory hay Logic elements
Hình 32: Các tham số cấu hình của khối Delay/Memory Delay
- Khối Multiplier/Product: dùng để tính toán phép nhân hai đầu vào a, b
Hình 33: Khối multiplier hai đầu vào a, b
+ Các tham số có thể cấu hình bao gồm: số bit của các giá trị đầu vào/đầu ra, phép nhân số có dấu/không dấu, số nguyên/fixed point, sử dụng các khối DSP hay Logic elements, số chu kỳ pipeline
Hình 34: Các tham số cấu hình của khối Multiplier/Product
+ Ngoài ra, có sẵn khối multiplier dùng cho việc nhân với một hằng số cố định, các tham số cấu hình hoàn toàn tương tự:
Hình 35: Khối Gain nhân đầu vào với một hằng số
Hình 36: Khối Parallel Adder/Subtractor
+ Khối tính toán phép cộng/trừ nhiều đầu vào pipeline, số chu kỳ pipeline là ceil(log2(number of inputs)), ví dụ có 25 giá trị đầu vào thì số chu kỳ phép cộng thực hiện xong là: ceil(log2(25)) = 5
+ Các tham số có thể tính toán bao gồm: số lượng giá trị đầu vào, pipeline, asynchronous clear port
Hình 38: Khối Dual-Port RAM
+ Các tham số có thể cấu hình bao gồm: số lượng word, kích thước mỗi word, giá trị khởi tạo, register output port, enable port
Hình 39: Các tham số khối Dual-Port RAM
Hình 40: Khối FIFO và các tham số cấu hình
Hình 43: Khối Counter và các tham số cấu hình
- Ngoài ra còn một số khối khác cũng được sử dụng trong thiết kế:
Hình 45: Khối Logical Bit Operator
- Bên cạnh đó, ta cũng có thể add thêm các khối từ ngôn ngữ HDL bằng cách dùng module HDL Import:
KẾT QUẢ THỬ NGHIỆM
Sơ đồ ghép nối hệ thống
- Sơ đồ ghép nối các IP Core trên DE2i-150:
Hình 51: Sơ đồ ghép nối IP Core trên DE2i-150
- Sơ đồ ghép nối các IP Core trên DE1-SoC:
Kết quả thử nghiệm
- Dữ liệu được sử dụng cho việc thử nghiệm lấy từ TNO Image Fusion Dataset: https://figshare.com/articles/TNO_Image_Fusion_Dataset/1008029
- Khi đọc ra từ vùng nhớ RAM trên FPGA, kết quả ảnh đầu ra thực hiện trên board của 2 thuật toán 1 – Gaussian Pyramid Decomposition (A1) và thuật toán 2 – LEP filter & Saliency extraction (A2):
Hình 53: Kết quả trên tập dataset TRI_A3 (TNO_Image_Fusion_Dataset/Triclobs_images/soldier_behind_smoke)
Hình 54: Kết quả trên tập dataset TRI_B1 (TNO_Image_Fusion_Dataset/Triclobs_images/Kaptein_1123)
Hình 55: Kết quả trên tập dataset TRI_B4 (TNO_Image_Fusion_Dataset/Triclobs_images/Kaptein_19)
- Các video thử nghiệm khác trên board DE2i-150:
Gaussian Pyramid Decomposition LEP filter & Saliency extraction Dataset 1 (1:46): https://youtu.be/GWo2iFoCmtk
Dataset 2 (1:26): https://youtu.be/tnaQxFX1HJU
Dataset 3 (2:26): https://youtu.be/PJwbkMVKhJ8
Dataset 1 (1:36): https://youtu.be/PcOjlAn6MA8 Dataset 2 (1:21): https://youtu.be/0jAWMN0wZTA Dataset 3 (2:11): https://youtu.be/HWrt2zzEvvs
Bảng 3: Video thử nghiệm hai thuật toán Fusion trên KIT DE2i-150
- Các kết quả trên board DE1-SoC đạt được tương tự:
Gaussian Pyramid Decomposition LEP filter & Saliency extraction Dataset 1 (1:36): https://youtu.be/k43FquqFHR4
Dataset 2 (1:50): https://youtu.be/8rOnPrHqoq0
Dataset 3 (2:50): https://youtu.be/fxnOrKcUmms
Dataset 1 (1:46): https://youtu.be/GbVvltj5t90 Dataset 2 (1:50): https://youtu.be/peGPU1K6xC0 Dataset 3 (2:50): https://youtu.be/kSq5JQQuJnk
Bảng 4: Video thử nghiệm hai thuật toán Fusion trên KIT DE1-SoC
- Để thuận tiện cho việc chạy thử nghiệm, cả hai IP Core Fusion thực hiện theo hai thuật toán khác nhau được đưa vào 1 project, ghép nối với các IP Core Video DMA, Clipper cùng hoạt động song song và kết quả đưa ra hai vùng nhớ khác nhau Ta dùng một switch trên board để lựa chọn đầu ra hiển thị qua cổng VGA, trạng thái của switch được nhận biết theo cơ chế polling (kiểm tra trạng thái mỗi 30-40 ms) Dưới đây là video demo thiết kế đã kết hợp hai thuật toán (1:20): https://www.youtube.com/watch?v=iMEFsiSaAMQ
- Phương pháp LEP filter & Saliency extraction được thực hiện theo bài báo
“Infrared and visible image fusion via saliency analysis and local-edge preserving mult-scale decomposition”, so với các thuật toán trước đó, hình ảnh của phương pháp được đề xuất cho kết quả tốt hơn đáng kể (phần so sánh các kết quả dưới đây trích trong bài báo):
Hình 56: So sánh kết quả các thuật toán Fusion khác nhau (a) ảnh thường, (b) ảnh nhiệt, (c) ảnh fusion theo phương pháp được đề xuất,
(d)-(n) ảnh fusion theo các phương pháp được thực hiện trước đó
- Thống kê lượng tài nguyên cần thiết để triển khai hai thuật toán Fusion trên FPGA DE1-SoC:
Bảng 5: So sánh tài nguyên sử dụng giữa hai thuật toán Fusion
- Bảng bên dưới đây so sánh một vài thông số của việc triển khai thuật toán Fusion giữa FPGA và CPU với mục đích tham khảo:
Cài đặt Phức tạp Đơn giản
~ 7 ms (50 MHz) (tính theo số chu kỳ trên thiết kế)
~ 211 ms (A2) (trung bình MATLAB) Công suất ~ 2,4 W (ARM 800 MHz & FPGA)
Bảng 6: So sánh thời gian tính toán, công suất giữa FPGA và CPU