Code Generation with Cell Detection

This example shows how to generate C code using MATLAB® Coder™ from MATLAB applications that use Image Processing Toolbox™ functions. The example describes how to setup your MATLAB environment, prepare your MATLAB code for code generation, and work around any issues that you might encounter in your MATLAB code that prevent code generation.

Setup Your Compiler

This example shows how to specify which C/C++ compiler you want to use with MATLAB Coder to generate code.

Use the mex function with the -setup option to specify the C/C++ compiler you want to use with MATLAB Coder.

mex -setup
MEX configured to use 'Microsoft Visual C++ 2010 (C)' for C language compilation.
Warning: The MATLAB C and Fortran API has changed to support MATLAB
	 variables with more than 2^32-1 elements. In the near future
	 you will be required to update your code to utilize the
	 new API. You can find more information about this at:
	 https://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html.

To choose a different C compiler, select one from the following:
Microsoft Visual C++ 2012 (C)  mex -setup:C:\matlab\bin\win64\mexopts\msvc2012.xml C
Intel C++ Composer XE 2013 with Microsoft Visual Studio 2012 (C)  mex -setup:C:\matlab\bin\win64\mexopts\intel_c_13_vs2012.xml C
Intel C++ Composer XE 2011 with Microsoft Visual Studio 2010 (C)  mex -setup:C:\mexopts\intel_c_12_vs2010.xml C
Intel C++ Composer XE 2013 with Microsoft Visual Studio 2010 (C)  mex -setup:C:\matlab\bin\win64\mexopts\intel_c_13_vs2010.xml C
Microsoft Visual C++ 2010 (C)  mex -setup:C:\MATLAB\R2015a\mex_C_win64.xml C

To choose a different language, select one from the following:
 mex -setup C++ 
 mex -setup FORTRAN mex -setup FORTRAN

Generate Code

This example shows how to generate C code from MATLAB code that includes Image Processing Toolbox functions using MATLAB Coder. To illustrate the process, the code used by this example includes some readiness issues and build issues that you must overcome before you can generate code.

Copy the following code into a file and save it, giving it the name cellDetectionMATLAB.m.

function BWfinal = cellDetectionMATLAB(I)
%cellDetectionMATLAB - detect cells using image segmentation.

[~, threshold] = edge(I, 'sobel');
fudgeFactor = .5;
BWs = edge(I,'sobel', threshold * fudgeFactor);
figure
imshow(BWs)
title('binary gradient mask');

se90 = strel('line', 3, 90);
se0 = strel('line', 3, 0);

BWsdil = imdilate(BWs, [se90 se0]);
figure
imshow(BWsdil)
title('dilated gradient mask');

BWdfill = imfill(BWsdil, 'holes');
figure
imshow(BWdfill);
title('binary image with filled holes');

BWnobord = imclearborder(BWdfill, 4);
figure
imshow(BWnobord)
title('cleared border image');

seD = strel('diamond',1);
BWfinal = imerode(BWnobord,seD);
BWfinal = imerode(BWfinal,seD);
figure
imshow(BWfinal)
title('segmented image');

Test the example code with a sample image. Use the cell.tif file, included with the Image Processing Toolbox (matlab\toolbox\images\imdata\cell.tif).

I = imread('cell.tif');

Iseg = cellDetectionMATLAB(I);

% Display the original image and the segmented image side-by-side.
imshowpair(I,Iseg,'montage')

Create a copy of your MATLAB code before generating C code. Since you modify this code for code generation, it is good to work with a copy.

copyfile('cellDetectionMATLAB.m','cellDetectionCodeGeneration.m');

Open the code generation version of the function in the MATLAB editor. As a first step, change the name of the function in the function signature to match the file name and add the MATLAB Coder compilation directive %#codegen at the end of the function signature. This directive instructs the MATLAB code analyzer to diagnose issues that would prohibit successful code generation.

function BWfinal = cellDetectionCodeGeneration(I) %#codegen
.
.
.

Open the MATLAB Coder app. In MATLAB, select the Apps tab, navigate to Code Generation and click the MATLAB Coder app. (Alternatively, you can enter coder at the MATLAB command prompt.)

Specify the name of your entry-point function, cellDetectionCodeGeneration, and press Enter.

Determine your code’s readiness for code generation. Click Next (at the bottom right of the coder window). MATLAB Coder identifies any issues that might prevent code generation. The example code contains five unsupported function calls.

Review the readiness issues. Click Review Issues. In the report, MATLAB Coder displays your code in an editing window with the readiness issues listed below, flagging uses of the imshow function which does not support code generation.

Address the readiness issues. Remove the calls to imshow and related display code from your example. The display statements aren’t necessary for the segmentation operation. You can edit the example code in the MATLAB Coder. When you have removed the code, click Save to save your edits and rerun the readiness check. After rerunning the readiness check, MATLAB Coder displays the No issues found message.

Define the size and data type of the inputs to your function. Every input to your code must be specified to be of fixed size, variable size or a constant. There are several ways to specify the size of your input argument but the easiest way is by giving MATLAB Coder an example of calling your function. Enter a script that calls your function in the text entry field. For this example, enter the following code and press Enter.

I = imread('cell.tif'); 
Iseg = cellDetectionCodeGeneration(I);

For more information about defining inputs, see the MATLAB Coder documentation. After MATLAB Coder returns with the input type definition, click Next.

Check for run-time issues. Even though you performed the MATLAB Coder readiness checks, additional issues might arise during the build process that can prevent code generation. While the readiness checks look at function dependencies to determine readiness, the build process examines coding patterns. You can use the same code you entered to define input types (which is preloaded into the dialog box). Click Check for Issues.

This example contains a build issue: it passes an array of strel objects to imdilate and arrays of objects are not supported for code generation.

Address the build issues identified. For this example, you must modify the call to imdilate to avoid passing an array of strel objects. This is accomplished by replacing the single call to imdilate with two separate calls to imdilate where you pass one strel object with each call, highlighted in the following figure.

Rerun the test build to make sure your changes fixed the issue. Click Check for Issues. MATLAB Coder displays a message declaring that no issues were detected. You are now ready to generate code. Click Next.

Choose the type of code you want to generate and select the target platform. MATLAB Coder can generate C or C++ source code, a MEX file, a static library, a shared library, or a standalone executable. For Production Hardware, you can select from many choices including ARM and Intel processors. For this example, select Source Code and, for language, leave the C option selected, and select Generic for production hardware and MATLAB Host Computer for device type. When you choose MATLAB Host Computer, MATLAB Coder generates code that depends on a precompiled shared library. Image Processing Toolbox functions use a shared library to preserve performance optimizations. When you have made your selections, click Generate.

Generate code. When it is done,MATLAB Coder displays the generated code.

If you chose the C/C++ Dynamic Library option, MATLAB Coder generates the following interface. This interface can be used to integrate with an external application:

type codegen\dll\cellDetectionCodeGeneration\cellDetectionCodeGeneration.h
/*
 * cellDetectionCodeGeneration.h
 *
 * Code generation for function 'cellDetectionCodeGeneration'
 *
 */

#ifndef __CELLDETECTIONCODEGENERATION_H__
#define __CELLDETECTIONCODEGENERATION_H__
/* Include files */
#include <math.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>

#include "rtwtypes.h"
#include "cellDetectionCodeGeneration_types.h"

/* Function Declarations */
#ifdef __cplusplus
extern "C" {
#endif
extern void cellDetectionCodeGeneration(const unsigned char I[30369], boolean_T BWfinal[30369]);
#ifdef __cplusplus
}
#endif
#endif
/* End of code generation (cellDetectionCodeGeneration.h) */

The function signature exposed indicates there are two inputs. The first input I is expected to be an unsigned char with 30369 elements. This is used to pass the input image on which cell detection is to be performed. The type of the input image in MATLAB (uint8) is represented as an unsigned char. The size of the image is 159 x 191, i.e. 30369 elements. The number of elements is specified through the interface since the input was defined to be fixed size. The second input BWfinal is expected to be a boolean_T with 30369 elements. This is used to pass a pointer to the output image.

Note that there is a difference in the way MATLAB and C store arrays in memory. MATLAB stores arrays in column-major order and C stores arrays in row-major order. To illustrate, consider the following array:

[ 1  2
  3  4 ]

MATLAB stores the array in memory as [1 3 2 4 ] where C stores the elements as [1 2 3 4 ]. You must account for this difference when working with arrays.

You can also generate a standalone executable using the "C/C++ Executable" option. In this case a main function that invokes the generated code must be specified. Note that there are no ready-made utilities for importing data. For an example, refer to the Using Dynamic Memory Allocation for an "Atoms" Simulation in the MATLAB Coder documentation.

Click Next to complete the process. MATLAB Coder displays information about what it generated. By default, MATLAB Coder creates a codegen subfolder in your work folder that contains the generated output. For more information about generating code, see the MATLAB Coder documentation.

Related Topics