コントラスト調整の高位合成コード生成
この例では、ピクセル値を線形的にスケーリングすることによりイメージのコントラストを調整する MATLAB® 設計から高位合成 (HLS) コードを生成する方法を示します。
アルゴリズム
コントラスト調整では、上限と下限の間でピクセル値を線形的にスケーリングすることにより、イメージのコントラストを調整します。この範囲を超える、または下回るピクセル値は、それぞれ上限値または下限値に飽和されます。

MATLAB 設計
design_name = 'mlhdlc_image_scale'; testbench_name = 'mlhdlc_image_scale_tb';
MATLAB 設計を確認します。
type(design_name);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% scale.m
%
% Adjust image contrast by linearly scaling pixel values.
%
% The input pixel value range has 14bits and output pixel value range is
% 8bits.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [x_out, y_out, pixel_out] = ...
mlhdlc_image_scale(x_in, y_in, pixel_in, ...
damping_factor_in, dynamic_range_in, ...
tail_size_in, max_gain_in, ...
width, height)
% Copyright 2011-2022 The MathWorks, Inc.
persistent histogram1 histogram2
persistent low_count
persistent high_count
persistent offset
persistent gain
persistent limits_done
persistent damping_done
persistent reset_hist_done
persistent scaling_done
persistent hist_ind
persistent tail_high
persistent min_hist_damped %Damped lower limit of populated histogram
persistent max_hist_damped %Damped upper limit of populated histogram
persistent found_high
persistent found_low
DR_PER_BIN = 8;
SF = 1./(1:(2^14/8)); % be nice to fix this
NR_OF_BINS = (2^14/DR_PER_BIN) - 1;
MAX_DF = 255;
if isempty(offset)
offset = 1;
gain = 1;
limits_done = 1;
damping_done = 1;
reset_hist_done = 1;
scaling_done = 1;
hist_ind = 1;
tail_high = NR_OF_BINS;
low_count = 0;
high_count = 0;
min_hist_damped = 0;
max_hist_damped = (2^14/DR_PER_BIN) - 1;
found_high = 0;
found_low = 0;
end
if isempty(histogram1)
histogram1 = zeros(1, NR_OF_BINS+1);
histogram2 = zeros(1, NR_OF_BINS+1);
end
if y_in < height
frame_valid = 1;
if x_in < width
line_valid = 1;
else
line_valid = 0;
end
else
frame_valid = 0;
line_valid = 0;
end
% initialize at beginning of frame
if x_in == 0 && y_in == 0
limits_done = 0;
damping_done = 0;
reset_hist_done = 0;
scaling_done = 0;
low_count = 0;
high_count = 0;
hist_ind = 1;
end
max_gain_frac = max_gain_in/2^4;
pix11 = floor(pixel_in/DR_PER_BIN);
pix_out_temp = pixel_in;
%**************************************************************************
%Check if valid part of frame. If pixel is valid remap pixel to desired
%output dynamic range (dynamic_range_in) by subtracting the damped offset
%(min_hist_damped) and applying the calculated gain calculated from the
%previous frame histogram statistics.
%**************************************************************************
% histogram read
histReadIndex1 = 1;
histReadIndex2 = 1;
if frame_valid && line_valid
histReadIndex1 = pix11+1;
histReadIndex2 = pix11+1;
elseif ~limits_done
histReadIndex1 = hist_ind;
histReadIndex2 = NR_OF_BINS - hist_ind;
end
histReadValue1 = histogram1(histReadIndex1);
histReadValue2 = histogram2(histReadIndex2);
histWriteIndex1 = NR_OF_BINS+1;
histWriteIndex2 = NR_OF_BINS+1;
histWriteValue1 = 0;
histWriteValue2 = 0;
if frame_valid
if line_valid
temp_sum = histReadValue1 + 1;
ind = min(pix11+1, NR_OF_BINS);
val = min(temp_sum, tail_size_in);
histWriteIndex1 = ind;
histWriteValue1 = val;
histWriteIndex2 = ind;
histWriteValue2 = val;
%Scale pixel
pix_out_offs_corr = pixel_in - min_hist_damped*DR_PER_BIN;
pix_out_scaled = pix_out_offs_corr * gain;
pix_out_clamp = max(min(dynamic_range_in, pix_out_scaled), 0);
pix_out_temp = pix_out_clamp;
end
else
%**********************************************************************
%Ignore tail_size_in pixels and find lower and upper limits of the
%histogram.
%**********************************************************************
if ~limits_done
if hist_ind == 1
tail_high = NR_OF_BINS-1;
offset = 1;
found_high = 0;
found_low = 0;
end
low_count = low_count + histReadValue1;
hist_ind_high = NR_OF_BINS - hist_ind;
high_count = high_count + histReadValue2;
%Found enough high outliers
if high_count > tail_size_in && ~found_high
tail_high = hist_ind_high;
found_high = 1;
end
%Found enough low outliers
if low_count > tail_size_in && ~found_low
offset = hist_ind;
found_low = 1;
end
hist_ind = hist_ind + 1;
%All bins checked so limits must already be found
if hist_ind >= NR_OF_BINS
hist_ind = 1;
limits_done = 1;
end
%**********************************************************************
%Damp the limit change to avoid image flickering. Code below equivalent
%to: max_hist_damped = damping_factor_in*max_hist_dampedOld +
%(1-damping_factor_in)*max_hist_dampedNew;
%**********************************************************************
elseif ~damping_done
min_hist_weighted_old = damping_factor_in*min_hist_damped;
min_hist_weighted_new = (MAX_DF-damping_factor_in+1)*offset;
min_hist_weighted = (min_hist_weighted_old + ...
min_hist_weighted_new)/256;
min_hist_damped = max(0, min_hist_weighted);
max_hist_weighted_old = damping_factor_in*max_hist_damped;
max_hist_weighted_new = (MAX_DF-damping_factor_in+1)*tail_high;
max_hist_weighted = (max_hist_weighted_old + ...
max_hist_weighted_new)/256;
max_hist_damped = min(NR_OF_BINS, max_hist_weighted);
damping_done = 1;
hist_ind = 1;
%**********************************************************************
%Reset all bins to zero. More than one bin can be reset per function
%call if blanking time is too short.
%**********************************************************************
elseif ~reset_hist_done
histWriteIndex1 = hist_ind;
histWriteValue1 = 0;
histWriteIndex2 = hist_ind;
histWriteValue2 = 0;
hist_ind = hist_ind+1;
if hist_ind == NR_OF_BINS
reset_hist_done = 1;
end
%**********************************************************************
%The gain factor is determined by comparing the measured damped actual
%dynamic range to the desired user specified dynamic range. Input
%dynamic range is measured in bins over DR_PER_BIN space.
%**********************************************************************
elseif ~scaling_done
dr_in = round(max_hist_damped - min_hist_damped);
gain_temp = dynamic_range_in*SF(dr_in);
gain_scaled = gain_temp/DR_PER_BIN;
gain = min(max_gain_frac, gain_scaled);
scaling_done = 1;
hist_ind = 1;
end
end
histogram1(histWriteIndex1) = histWriteValue1;
histogram2(histWriteIndex2) = histWriteValue2;
x_out = x_in;
y_out = y_in;
pixel_out = pix_out_temp;
type(testbench_name);
%Test bench for scaling, analogous to automatic gain control (AGC)
% Copyright 2011-2022 The MathWorks, Inc.
testFile = 'mlhdlc_img_peppers.png';
imgOrig = imread(testFile);
[height, width] = size(imgOrig);
imgOut = zeros(height,width);
hBlank = 20;
% make sure we have enough vertical blanking to filter the histogram
vBlank = ceil(2^14/(width+hBlank));
%df - Temporal damping factor of rescaling
%dr - Desired output dynamic range
df = 0;
dr = 255;
nrOfOutliers = 248;
maxGain = 2*2^4;
for frame = 1:2
disp(['frame: ', num2str(frame)]);
for y_in = 0:height+vBlank-1
%disp(['frame: ', num2str(frame), ' of 2, row: ', num2str(y_in)]);
for x_in = 0:width+hBlank-1
if x_in < width && y_in < height
pixel_in = double(imgOrig(y_in+1, x_in+1));
else
pixel_in = 0;
end
[x_out, y_out, pixel_out] = ...
mlhdlc_image_scale(x_in, y_in, pixel_in, df, dr, ...
nrOfOutliers, maxGain, width, height);
if x_out < width && y_out < height
imgOut(y_out+1,x_out+1) = pixel_out;
end
end
end
figure('Name', [mfilename, '_scale_plot']);
imgOut = round(255*imgOut/max(max(imgOut)));
subplot(2,2,1); imshow(imgOrig, []);
title('Original Image');
subplot(2,2,2); imshow(imgOut, []);
title('Scaled Image');
subplot(2,2,3); histogram(double(imgOrig(:)),2^14-1);
axis([0, 255, 0, 1500]);
title('Histogram of original Image');
subplot(2,2,4); histogram(double(imgOut(:)),2^14-1);
axis([0, 255, 0, 1500]);
title('Histogram of equalized Image');
end
設計のシミュレーション
コードの生成前にテスト ベンチを使用して設計のシミュレーションを実行し、実行時エラーが発生しないことを確認することをお勧めします。
mlhdlc_image_scale_tb
frame: 1 frame: 2


HDL Coder™ プロジェクトの作成
coder -hdlcoder -new mlhdlc_scale_prj
mlhdlc_image_scale.m ファイルを [MATLAB 関数] としてプロジェクトに追加し、mlhdlc_image_scale_tb.m を [MATLAB テスト ベンチ] として追加します。
詳細については、Get Started with MATLAB to High-Level Synthesis Workflow Using the Command Line InterfaceまたはHDL Coder アプリを使用した MATLAB から高位合成へのワークフロー入門を参照してください。
固定小数点変換と HLS コード生成の実行
MATLAB 設計から HLS コードを生成するには、次のようにします。
1. MATLAB コマンド ラインで、関数hdlsetuphlstoolpathを使用して HLS コード生成用のパスを設定します。
2. [ワークフロー アドバイザー] ボタンをクリックして、ワークフロー アドバイザーを開始します。
3. [HDL ワークフロー アドバイザー] で、[MATLAB から HLS] として [コード生成ワークフロー] を選択します。
4. [コード生成ターゲットを選択] の [合成ツール] として [Cadence Stratus HLS] を選択します。
5. [HLS コード生成] を右クリックして [選択したタスクまで実行] を選択し、最初から HLS コード生成までのすべての手順を実行します。
コード生成ログのウィンドウにあるハイパーリンクをクリックして、生成された HLS コードを調べます。