{"id":922,"date":"2013-11-26T13:51:28","date_gmt":"2013-11-26T18:51:28","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=922"},"modified":"2019-11-01T09:36:52","modified_gmt":"2019-11-01T13:36:52","slug":"generating-code-from-image-processing-toolbox-functions","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2013\/11\/26\/generating-code-from-image-processing-toolbox-functions\/","title":{"rendered":"Generating code from Image Processing Toolbox functions"},"content":{"rendered":"\r\n<div class=\"content\"><!--introduction--><p><i>I'd like to welcome guest blogger Vignesh Krishnan for today's post. Vignesh is a developer on the Image Processing Toolbox team. -Steve<\/i><\/p><!--\/introduction--><p>Let's try C code generation from Image Processing Toolbox&#8482; functions. I am going to use an example to fill borders of a binary image from Steve Eddins' <a href=\"https:\/\/blogs.mathworks.com\/steve\/2013\/09\/05\/defining-and-filling-holes-on-the-border-of-an-image\">post<\/a>.<\/p><p>In this post, the goal is to fill holes in an image and generate code using the Image Processing Toolbox and MATLAB Coder&#8482;. First, I create a MATLAB function with code adapted from the blog post mentioned earlier and name it <tt>fillborderholes.m<\/tt><\/p><pre class=\"codeinput\">type <span class=\"string\">fillborderholes.m<\/span>\r\n<\/pre><pre class=\"codeoutput\">\r\nfunction bw_filled = fillborderholes(bw)\r\n%#codegen\r\n\r\n% Fill against the left and the top border. The following call to padarray \r\n% adds a column of white pixels on the left and a row of white pixels on \r\n% the top.\r\nbw_a = padarray(bw,[1 1],1,'pre');\r\nbw_a_filled = imfill(bw_a,'holes');\r\nbw_a_filled_nopadding = bw_a_filled(2:end,2:end);\r\n\r\n% Now fill against the top and the right border.\r\nbw_b = padarray(padarray(bw,[1 0],1,'pre'),[0 1],1,'post');\r\nbw_b_filled = imfill(bw_b,'holes');\r\nbw_b_filled_nopadding = bw_b_filled(2:end,1:end-1);\r\n\r\n% Next, fill against the right and bottom borders.\r\nbw_c = padarray(bw,[1 1],1,'post');\r\nbw_c_filled = imfill(bw_c,'holes');\r\nbw_c_filled_nopadding = bw_c_filled(1:end-1,1:end-1);\r\n\r\n% Finally, fill against the bottom and left borders. (I wouldn't expect \r\n% this to have any effect on this particular image.)\r\nbw_d = padarray(padarray(bw,[1 0],1,'post'),[0 1],1,'pre');\r\nbw_d_filled = imfill(bw_d,'holes');\r\nbw_d_filled_nopadding = bw_d_filled(1:end-1,2:end);\r\n\r\n% The last step is then to \"logical OR\" all these images together.\r\nbw_filled = bw_a_filled_nopadding | bw_b_filled_nopadding | bw_c_filled_nopadding | bw_d_filled_nopadding;\r\n<\/pre><p>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.<\/p><pre class=\"codeinput\">url = <span class=\"string\">'https:\/\/blogs.mathworks.com\/images\/steve\/2013\/eye-heart-matlab.png'<\/span>;\r\nbw = imread(url);\r\nimshow(bw)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2013\/codegenBlogPost_01.png\" alt=\"\"> <p>Now I am ready to generate C code from my function using the <a href=\"https:\/\/www.mathworks.com\/help\/coder\/ref\/codegen.html\">codegen<\/a> 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 <a href=\"https:\/\/www.mathworks.com\/help\/fixedpoint\/ug\/controlling-run-time-checks.html\">here<\/a><\/p><pre class=\"codeinput\">cfg = coder.config(<span class=\"string\">'mex'<\/span>);\r\ncfg.IntegrityChecks = false;\r\ncfg.ResponsivenessChecks = false;\r\ncodegen <span class=\"string\">fillborderholes<\/span> <span class=\"string\">-args<\/span> <span class=\"string\">{bw}<\/span> <span class=\"string\">-config<\/span> <span class=\"string\">cfg<\/span> <span class=\"string\">-report<\/span>\r\n<\/pre><pre class=\"codeoutput\">Code generation successful: To view the report, open('\/Volumes\/inside_files_dev\/ltc\/imagemap\/ipblog\/published\/2013\/codegen\/mex\/fillborderholes\/html\/index.html').\r\n<\/pre><p>Here's what the generated report looks like:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2013\/codegen-report-screen-shot.png\" alt=\"\"> <\/p><p>The default coder configuration setting creates a MEX file in the current directory named <tt>fillborderholes_mex<\/tt>. Ok! Let's run the executable<\/p><pre class=\"codeinput\">bw_filled_cg = fillborderholes_mex(bw);\r\nimshow(bw_filled_cg);\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2013\/codegenBlogPost_02.png\" alt=\"\"> <p>By default, the code generated for the function is in the file, <tt>fillborderholes.c<\/tt> in the folder <tt>codegen\/mex\/fillborderholes\/<\/tt>. Alternatively, you can click on the C-code tab in the report and look at the generated code. It includes function calls to <a href=\"https:\/\/www.mathworks.com\/help\/images\/ref\/imreconstruct.html\">imreconstruct<\/a> which is the morphological reconstruction algorithm used by <a href=\"https:\/\/www.mathworks.com\/help\/images\/ref\/imfill.html\">imfill<\/a>. The code uses a precompiled platform-specific shared library to implement the algorithm.<\/p><p>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, <tt>fillborderholes.m<\/tt> for which we generated code takes an image, <tt>bw<\/tt> as input and returns <tt>bw_filled<\/tt> 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<\/p><pre>void fillborderholes(const boolean_T bw[222945], emxArray_boolean_T *bw_filled)<\/pre><p>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 <a href=\"https:\/\/www.mathworks.com\/help\/fixedpoint\/ug\/c-code-interface-for-unbounded-arrays-and-structure-fields.html\">here<\/a><\/p><p>The first operation in <tt>fillborderholes.m<\/tt> is to pad the input image using <a href=\"https:\/\/www.mathworks.com\/help\/images\/ref\/padarray.html\">padarray<\/a> and then call <a href=\"https:\/\/www.mathworks.com\/help\/images\/ref\/imfill.html\">imfill<\/a> on it. As shown below, this translates to the function call <tt>ConstantPad()<\/tt> which pre-pads the input image, <tt>bw<\/tt> to create a padded image, <tt>bw_a<\/tt>. The call to <tt>imfill()<\/tt> creates a filled image, <tt>bw_b<\/tt> which is then copied over to <tt>bw_a_filled<\/tt>, since <tt>bw_b<\/tt> is reused later in the generated code.<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2013\/fillborderholes_code_excerpt1.png\" alt=\"\"> <\/p><p>The rest of the generated code is a series of calls to <tt>ConstantPad()<\/tt> to pad different borders of the image followed by calls to <tt>imfill()<\/tt> to fill the padded image.<\/p><p>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 <tt>bw_filled<\/tt>.<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2013\/fillborderholes_code_excerpt2.png\" alt=\"\"> <\/p><p>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?<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_8f9fad17a8f146af9bb58fe7186c2631() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='8f9fad17a8f146af9bb58fe7186c2631 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 8f9fad17a8f146af9bb58fe7186c2631';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2013 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_8f9fad17a8f146af9bb58fe7186c2631()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2013b<br><\/p><p class=\"footer\"><br>\r\n      Published with MATLAB&reg; R2013b<br><\/p><\/div><!--\r\n8f9fad17a8f146af9bb58fe7186c2631 ##### SOURCE BEGIN #####\r\n%%\r\n% _I'd like to welcome guest blogger Vignesh Krishnan for today's post.\r\n% Vignesh is a developer on the Image Processing Toolbox team. -Steve_\r\n\r\n%%  \r\n% Let's try C code generation from Image Processing Toolbox(TM) functions.\r\n% I am going to use an example to fill borders of a binary image from \r\n% Steve Eddins'  \r\n% <https:\/\/blogs.mathworks.com\/steve\/2013\/09\/05\/defining-and-filling-holes-on-the-border-of-an-image post>. \r\n%% \r\n% In this post, the goal is to fill holes in an image and generate code \r\n% using the Image Processing Toolbox and MATLAB Coder(TM). \r\n% First, I create a MATLAB function with code adapted from the blog post \r\n% mentioned earlier and name it |fillborderholes.m|\r\n%% \r\ntype fillborderholes.m\r\n%% \r\n% Next, I have to create an example input to be used while generating code.\r\n% C is a static typed language hence an example input is required to \r\n% constrain the generated code to a particular input size and datatype.\r\nurl = 'https:\/\/blogs.mathworks.com\/images\/steve\/2013\/eye-heart-matlab.png';\r\nbw = imread(url);\r\nimshow(bw)\r\n%% \r\n% Now I am ready to generate C code from my function using the \r\n% <https:\/\/www.mathworks.com\/help\/coder\/ref\/codegen.html codegen>\r\n% command. The '-args' option provides the example input. The '-report' \r\n% option creates a compilation report which provides links to the generated\r\n% code. I setup the configuration parameters to turn off run-time checks to \r\n% make the code run faster and improve its readability. For more details on\r\n% run-time checks look\r\n% <https:\/\/www.mathworks.com\/help\/fixedpoint\/ug\/controlling-run-time-checks.html\r\n% here>\r\ncfg = coder.config('mex');\r\ncfg.IntegrityChecks = false;\r\ncfg.ResponsivenessChecks = false;\r\ncodegen fillborderholes -args {bw} -config cfg -report\r\n\r\n%%\r\n% Here's what the generated report looks like:\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/images\/steve\/2013\/codegen-report-screen-shot.png>>\r\n\r\n%%\r\n% The default coder configuration setting creates a MEX file in the current \r\n% directory named |fillborderholes_mex|. Ok! Let's run the executable \r\nbw_filled_cg = fillborderholes_mex(bw);\r\nimshow(bw_filled_cg);\r\n\r\n%%\r\n% By default, the code generated for the function is in the file, \r\n% |fillborderholes.c| in the folder |codegen\/mex\/fillborderholes\/|. \r\n% Alternatively, you can click on the C-code tab in the report and look at \r\n% the generated code. It includes function calls to \r\n% <https:\/\/www.mathworks.com\/help\/images\/ref\/imreconstruct.html imreconstruct>\r\n% which is the morphological reconstruction algorithm used by \r\n% <https:\/\/www.mathworks.com\/help\/images\/ref\/imfill.html imfill>.\r\n% The code uses a precompiled platform-specific shared library to implement\r\n% the algorithm. \r\n%\r\n% Let me focus on a few excerpts of the generated code. Notice how the \r\n% comments in my MATLAB code appeared in my generated code. The comments \r\n% help correlate the generated code with the source code. The top-level \r\n% function, |fillborderholes.m| for which we generated code takes an image, \r\n% |bw| as input and returns |bw_filled| as output. The input image used in \r\n% this example at compilation time is of boolean datatype and size 445 x 501 \r\n% i.e. 222945 elements. As a result, the function declaration is as follows \r\n% \r\n%  void fillborderholes(const boolean_T bw[222945], emxArray_boolean_T *bw_filled)\r\n% \r\n% The function expects the first input to be a boolean array of size 222945.\r\n% A static array is used in the C interface because the input was defined \r\n% to be fixed size during compilation. The output is dynamically allocated \r\n% which is represented as a structure type called emxArray specialized for \r\n% the particular datatype. For more details on emxArray look \r\n% <https:\/\/www.mathworks.com\/help\/fixedpoint\/ug\/c-code-interface-for-unbounded-arrays-and-structure-fields.html here>\r\n%\r\n% The first operation in |fillborderholes.m| is to pad the input image using \r\n% <https:\/\/www.mathworks.com\/help\/images\/ref\/padarray.html padarray> and then \r\n% call <https:\/\/www.mathworks.com\/help\/images\/ref\/imfill.html imfill> on it. \r\n% As shown below, this translates to the function call |ConstantPad()| \r\n% which pre-pads the input image, |bw| to create a padded image, |bw_a|. \r\n% The call to |imfill()| creates a filled image, |bw_b| which is then \r\n% copied over to |bw_a_filled|, since |bw_b| is reused later in the \r\n% generated code.\r\n% \r\n% <<https:\/\/blogs.mathworks.com\/images\/steve\/2013\/fillborderholes_code_excerpt1.png>>\r\n%\r\n% The rest of the generated code is a series of calls to |ConstantPad()| to \r\n% pad different borders of the image followed by calls to |imfill()| to \r\n% fill the padded image.\r\n%\r\n% In the last section, the generated code creates two for-loops to OR the \r\n% filled results from the intermediate steps and store the final filled result\r\n% in |bw_filled|.\r\n% \r\n% <<https:\/\/blogs.mathworks.com\/images\/steve\/2013\/fillborderholes_code_excerpt2.png>>\r\n% \r\n% As of R2013a, the Image Processing Toolbox using MATLAB Coder can \r\n% generate code from the following functions:\r\n% conndef, imcomplement, imfill, imhmax, imhmin, imreconstruct, \r\n% imregionalmax, imregionalmin, iptcheckconn, and padarray. \r\n% Which functions would you like to be able to generate code?\r\n\r\n##### SOURCE END ##### 8f9fad17a8f146af9bb58fe7186c2631\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/steve\/2013\/codegenBlogPost_02.png\" onError=\"this.style.display ='none';\" \/><\/div><!--introduction--><p><i>I'd like to welcome guest blogger Vignesh Krishnan for today's post. Vignesh is a developer on the Image Processing Toolbox team. -Steve<\/i>... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2013\/11\/26\/generating-code-from-image-processing-toolbox-functions\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[1039,1011,146,136,448,450,76,438,364,366,36,1041,344],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/922"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=922"}],"version-history":[{"count":3,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/922\/revisions"}],"predecessor-version":[{"id":925,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/922\/revisions\/925"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=922"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=922"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=922"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}