Steve on Image Processing with MATLAB

Image processing concepts, algorithms, and MATLAB

Generating code from Image Processing Toolbox functions

I'd like to welcome guest blogger Vignesh Krishnan for today's post. Vignesh is a developer on the Image Processing Toolbox team. -Steve

Let's try C code generation from Image Processing Toolbox™ functions. I am going to use an example to fill borders of a binary image from Steve Eddins' post.

In this post, the goal is to fill holes in an image and generate code using the Image Processing Toolbox and MATLAB Coder™. First, I create a MATLAB function with code adapted from the blog post mentioned earlier and name it fillborderholes.m

type fillborderholes.m
function bw_filled = fillborderholes(bw)
%#codegen

% Fill against the left and the top border. The following call to padarray 
% adds a column of white pixels on the left and a row of white pixels on 
% the top.
bw_a = padarray(bw,[1 1],1,'pre');
bw_a_filled = imfill(bw_a,'holes');
bw_a_filled_nopadding = bw_a_filled(2:end,2:end);

% Now fill against the top and the right border.
bw_b = padarray(padarray(bw,[1 0],1,'pre'),[0 1],1,'post');
bw_b_filled = imfill(bw_b,'holes');
bw_b_filled_nopadding = bw_b_filled(2:end,1:end-1);

% Next, fill against the right and bottom borders.
bw_c = padarray(bw,[1 1],1,'post');
bw_c_filled = imfill(bw_c,'holes');
bw_c_filled_nopadding = bw_c_filled(1:end-1,1:end-1);

% Finally, fill against the bottom and left borders. (I wouldn't expect 
% this to have any effect on this particular image.)
bw_d = padarray(padarray(bw,[1 0],1,'post'),[0 1],1,'pre');
bw_d_filled = imfill(bw_d,'holes');
bw_d_filled_nopadding = bw_d_filled(1:end-1,2:end);

% The last step is then to "logical OR" all these images together.
bw_filled = bw_a_filled_nopadding | bw_b_filled_nopadding | bw_c_filled_nopadding | bw_d_filled_nopadding;

Next, I have to create an example input to be used while generating code. C is a static typed language hence an example input is required to constrain the generated code to a particular input size and datatype.

url = 'https://blogs.mathworks.com/images/steve/2013/eye-heart-matlab.png';
bw = imread(url);
imshow(bw)

Now I am ready to generate C code from my function using the codegen command. The '-args' option provides the example input. The '-report' option creates a compilation report which provides links to the generated code. I setup the configuration parameters to turn off run-time checks to make the code run faster and improve its readability. For more details on run-time checks look here

cfg = coder.config('mex');
cfg.IntegrityChecks = false;
cfg.ResponsivenessChecks = false;
codegen fillborderholes -args {bw} -config cfg -report
Code generation successful: To view the report, open('/Volumes/inside_files_dev/ltc/imagemap/ipblog/published/2013/codegen/mex/fillborderholes/html/index.html').

Here's what the generated report looks like:

The default coder configuration setting creates a MEX file in the current directory named fillborderholes_mex. Ok! Let's run the executable

bw_filled_cg = fillborderholes_mex(bw);
imshow(bw_filled_cg);

By default, the code generated for the function is in the file, fillborderholes.c in the folder codegen/mex/fillborderholes/. Alternatively, you can click on the C-code tab in the report and look at the generated code. It includes function calls to imreconstruct which is the morphological reconstruction algorithm used by imfill. The code uses a precompiled platform-specific shared library to implement the algorithm.

Let me focus on a few excerpts of the generated code. Notice how the comments in my MATLAB code appeared in my generated code. The comments help correlate the generated code with the source code. The top-level function, fillborderholes.m for which we generated code takes an image, bw as input and returns bw_filled as output. The input image used in this example at compilation time is of boolean datatype and size 445 x 501 i.e. 222945 elements. As a result, the function declaration is as follows

void fillborderholes(const boolean_T bw[222945], emxArray_boolean_T *bw_filled)

The function expects the first input to be a boolean array of size 222945. A static array is used in the C interface because the input was defined to be fixed size during compilation. The output is dynamically allocated which is represented as a structure type called emxArray specialized for the particular datatype. For more details on emxArray look here

The first operation in fillborderholes.m is to pad the input image using padarray and then call imfill on it. As shown below, this translates to the function call ConstantPad() which pre-pads the input image, bw to create a padded image, bw_a. The call to imfill() creates a filled image, bw_b which is then copied over to bw_a_filled, since bw_b is reused later in the generated code.

The rest of the generated code is a series of calls to ConstantPad() to pad different borders of the image followed by calls to imfill() to fill the padded image.

In the last section, the generated code creates two for-loops to OR the filled results from the intermediate steps and store the final filled result in bw_filled.

As of R2013a, the Image Processing Toolbox using MATLAB Coder can generate code from the following functions: conndef, imcomplement, imfill, imhmax, imhmin, imreconstruct, imregionalmax, imregionalmin, iptcheckconn, and padarray. Which functions would you like to be able to generate code?




Published with MATLAB® R2013b

|
  • print

Comments

To leave a comment, please click here to sign in to your MathWorks Account or create a new one.