Accelerating the pace of engineering and science

HDL Coder

High Dynamic Range Imaging

This example shows how to generate HDL code from a MATLAB® design that implements a high dynamic range imaging algorithm.

Algorithm

High Dynamic Range Imaging (HDRI or HDR) is a set of methods used in imaging and photography to allow a greater dynamic range between the lightest and darkest areas of an image than current standard digital imaging methods or photographic methods. HDR images can represent more accurately the range of intensity levels found in real scenes, from direct sunlight to faint starlight, and is often captured by way of a plurality of differently exposed pictures of the same subject matter.

MATLAB Design

design_name = 'mlhdlc_hdr';
testbench_name = 'mlhdlc_hdr_tb';

Let us take a look at the MATLAB design

dbtype(design_name);
1     function [valid_out, x_out, y_out, ...
2         HDR1, HDR2, HDR3] = mlhdlc_hdr(YShort1, YShort2, YShort3, ...
3         YLong1, YLong2, YLong3, ...
4         plot_y_short_in, plot_y_long_in, ... 
5         valid_in, x, y)
6     
7     %   Copyright 2013-2015 The MathWorks, Inc.
8     
9     % This design implements a high dynamic range imaging algorithm.
10    
11    plot_y_short = plot_y_short_in;
12    plot_y_long = plot_y_long_in;
13    
14    %% Apply Lum(Y) channels LUTs
15    y_short = plot_y_short(uint8(YShort1)+1);
16    y_long = plot_y_long(uint8(YLong1)+1);
17    
18    y_HDR = (y_short+y_long);
19    
20    %% Create HDR Chorm channels
21    % HDR per color
22    
23    HDR1 = y_HDR * 2^-8;
24    HDR2 = (YShort2+YLong2) * 2^-1;
25    HDR3 = (YShort3+YLong3) * 2^-1;
26    
27    %% Pass on valid signal and pixel location
28    
29    valid_out = valid_in;
30    x_out = x;
31    y_out = y;
32    
33    end
dbtype(testbench_name);
1     
2     %   Copyright 2013-2015 The MathWorks, Inc.
3     
4     % Clean screen and memory 
5     close all
6     clear mlhdlc_hdr
7     set(0,'DefaultFigureWindowStyle','docked')
8     
9     
10    %% Read the two exposued images
11    
12    short = imread('mlhdlc_hdr_short.tif');
13    long = imread('mlhdlc_hdr_long.tif');
14    
15    % define HDR output variable
16    HDR = zeros(size(short));
17    [height, width, color] = size(HDR);
18    
19    figure('Name', [mfilename, '_plot']);
20    subplot(1,3,1);
21    imshow(short, 'InitialMagnification','fit'), title('short');
22    
23    subplot(1,3,2);
24    imshow(long, 'InitialMagnification','fit'), title('long');
25    
26    
27    %% Create the Lum(Y) channels LUTs
28    % Pre-process
29    % Lumminance short LUT
30    ShortLut.x = [0    16    45    96   255];
31    ShortLut.y = [0    20    38    58   115];
32    
33    % Lumminance long LUT
34    LongLut.x = [ 0 255];
35    LongLut.y = [ 0  140];
36    
37    % Take the same points to plot the joined Lum LUT
38    plot_x = 0:1:255;
39    plot_y_short = interp1(ShortLut.x,ShortLut.y,plot_x); %LUT short
40    plot_y_long = interp1(LongLut.x,LongLut.y,plot_x); %LUT long
41    
42    %subplot(4,1,3);
43    %plot(plot_x, plot_y_short, plot_x, plot_y_long, plot_x, (plot_y_long+plot_y_short)), grid on;
44    
45    
46    %% Create the HDR Lum channel 
47    % The HDR algorithm
48    % read the Y channels 
49    
50    YIQ_short = rgb2ntsc(short);
51    YIQ_long = rgb2ntsc(long);
52    
53    %% Stream image through HDR algorithm
54    
55    for x=1:width
56        for y=1:height
57            YShort1 = round(YIQ_short(y,x,1)*255); %input short
58            YLong1 = round(YIQ_long(y,x,1)*255); %input long
59    
60            YShort2 = YIQ_short(y,x,2); %input short
61            YLong2 = YIQ_long(y,x,2); %input long
62    
63            YShort3 = YIQ_short(y,x,3); %input short
64            YLong3 = YIQ_long(y,x,3); %input long
65    
66            valid_in = 1;
67            
68            [valid_out, x_out, y_out, HDR1, HDR2, HDR3] = mlhdlc_hdr(YShort1, YShort2, YShort3, YLong1, YLong2, YLong3, plot_y_short, plot_y_long, valid_in, x, y);
69    
70            % use x and y to reconstruct image
71            if valid_out == 1
72                HDR(y_out,x_out,1) = HDR1;
73                HDR(y_out,x_out,2) = HDR2;
74                HDR(y_out,x_out,3) = HDR3;
75            end   
76        end
77    end
78    
79    %% plot HDR
80    HDR_rgb = ntsc2rgb(HDR);
81    subplot(1,3,3);
82    imshow(HDR_rgb, 'InitialMagnification','fit'), title('hdr ');

Simulate the Design

It is always a good practice to simulate the design with the testbench prior to code generation to make sure there are no runtime errors.

mlhdlc_hdr_tb

Setup for the Example

Executing the following lines copies the necessary files into a temporary folder

mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos');
mlhdlc_temp_dir = [tempdir 'mlhdlc_hdr'];

% create a temporary folder and copy the MATLAB files
cd(tempdir);
[~, ~, ~] = rmdir(mlhdlc_temp_dir, 's');
mkdir(mlhdlc_temp_dir);
cd(mlhdlc_temp_dir);

% copy files to the temp dir
copyfile(fullfile(mlhdlc_demo_dir, [design_name,'.m*']), mlhdlc_temp_dir);
copyfile(fullfile(mlhdlc_demo_dir, [testbench_name,'.m*']), mlhdlc_temp_dir);
copyfile(fullfile(mlhdlc_demo_dir, 'mlhdlc_hdr_long.tif'), mlhdlc_temp_dir);
copyfile(fullfile(mlhdlc_demo_dir, 'mlhdlc_hdr_short.tif'), mlhdlc_temp_dir);

Create a New HDL Coder™ Project

coder -hdlcoder -new mlhdlc_hdr_prj

Next, add the file 'mlhdlc_hdr.m' to the project as the MATLAB Function and 'mlhdlc_hdr_tb.m' as the MATLAB Test Bench.

You can refer to Getting Started with MATLAB to HDL Workflow tutorial for a more complete tutorial on creating and populating MATLAB HDL Coder projects.

Creating constant parameter inputs

This example shows to use pass constant parameter inputs.

In this design the input parameters 'plot_y_short_in' and 'plot_y_long_in' are constant input parameters. You can define them accordingly by modifying the input types as 'constant(double(1x256))'

'plot_y_short_in' and 'plot_y_short_in' are LUT inputs. They are constant folded as double inputs to the design. You will not see port declarations for these two input parameters in the generated HDL code.

Note that inside the design 'mlhdlc_hdr.m' these variables are reassigned so that they get properly fixed-point converted. This is not necessary if these are purely used as constants for defining sizes of variables for example and not part of the logic.

Run Fixed-Point Conversion and HDL Code Generation

Launch HDL Advisor and right click on the 'Code Generation' step and choose the option 'Run to selected task' to run all the steps from the beginning through the HDL code generation.

Convert the design to fixed-point and generate HDL code

The following script converts the design to fixed-point, and generate HDL code with a test bench.

  exArgs = {0,0,0,0,0,0,coder.Constant(ones(1,256)),coder.Constant(ones(1,256)),0,0,0};
  fc = coder.config('fixpt');
  fc.TestBenchName = 'mlhdlc_hdr_tb';
  hc = coder.config('hdl');
  hc.GenerateHDLTestBench = true;
  hc.SimulationIterationLimit = 1000; % Limit number of testbench points
  codegen -float2fixed fc -config hc -args exArgs mlhdlc_hdr

Examine the generated HDL code by clicking on the hyperlinks in the Code Generation Log window.

Clean up the Generated Files

You can run the following commands to clean up the temporary project folder.

mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos');
mlhdlc_temp_dir = [tempdir 'mlhdlc_hdr'];
clear mex;
cd (mlhdlc_demo_dir);
rmdir(mlhdlc_temp_dir, 's');