{"id":1201,"date":"2015-06-24T10:36:01","date_gmt":"2015-06-24T15:36:01","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/?p=1201"},"modified":"2017-09-24T19:31:49","modified_gmt":"2017-09-25T00:31:49","slug":"how-do-you-modify-the-background-of-an-image","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2015\/06\/24\/how-do-you-modify-the-background-of-an-image\/","title":{"rendered":"How Do You Modify the Background of an Image?"},"content":{"rendered":"<div class=\"content\"><!--introduction--><p>Today I'd like to introduce guest blogger <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/845693-brett-shoelson\">Brett Shoelson<\/a>. Some of you may know Brett through <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/845693-brett-shoelson?utf8=%E2%9C%93&amp;detail=fileexchange\">his File Exchange submissions<\/a>, or through his involvement with the <a href=\"https:\/\/blogs.mathworks.com\/pick\/\">Pick of the Week<\/a> blog, or from occasional guest posts on <a href=\"https:\/\/blogs.mathworks.com\/steve\/\">Steve&#8217;s blog on image processing<\/a>.<\/p><!--\/introduction--><h3>Contents<\/h3><div><ul><li><a href=\"#c3ad10ac-c612-43d3-9f14-c88486171c14\">\"The visa problem\"<\/a><\/li><li><a href=\"#5216c703-7226-41cb-a175-7e2c5e1cfcf2\">The original photo<\/a><\/li><li><a href=\"#0e096a30-80d6-40f2-aed4-76996bf2fef1\">First question: how do we isolate the background?<\/a><\/li><li><a href=\"#b6efadc2-511f-4e87-87dc-3cdaa5b6eec0\">Is the effort of automation justified?<\/a><\/li><li><a href=\"#d3c10f42-fc65-47cf-bc48-a19d9a0cb861\">Improving the mask<\/a><\/li><li><a href=\"#e7838c7f-3f30-4f7c-a0be-220706904245\">Modifying the background<\/a><\/li><li><a href=\"#59a200b9-36eb-4a26-a25b-39f829c01b88\">Two problems remain...<\/a><\/li><li><a href=\"#af1a8fff-144e-4637-a96c-e78d63accc3b\">Planewise manipulations<\/a><\/li><li><a href=\"#3919b3c2-6ccb-4dd8-a4d5-3206d7659fca\">Fixing the interface<\/a><\/li><li><a href=\"#9fdd1903-8833-4b2f-81d1-4b8b0d1176ea\">A final note<\/a><\/li><\/ul><\/div><h4>\"The visa problem\"<a name=\"c3ad10ac-c612-43d3-9f14-c88486171c14\"><\/a><\/h4><p>Loren recently told me she had a pending international trip that requires a visa. She had a photograph taken against a background that was unsuitable for use in her visa document, and she asked: \"How would I go about changing the background to white?\"<\/p><h4>The original photo<a name=\"5216c703-7226-41cb-a175-7e2c5e1cfcf2\"><\/a><\/h4><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2015\/LorenVisaImage.png\" alt=\"\"> <\/p><h4>First question: how do we isolate the background?<a name=\"0e096a30-80d6-40f2-aed4-76996bf2fef1\"><\/a><\/h4><p>\"I wonder if this will entail creating a manual mask?\", Loren asked.<\/p><p>Great question! I can certainly come up with an automated approach to masking (or \"segmenting\") the region of interest (\"ROI\"). For instance:<\/p><pre class=\"language-matlab\">img = imread(<span class=\"string\">'LorenVisaImage.png'<\/span>);\r\ngray = rgb2gray(img);\r\nSE  = strel(<span class=\"string\">'Disk'<\/span>,1,4);\r\nmorphologicalGradient = imsubtract(imdilate(gray, SE),imerode(gray, SE));\r\nmask = im2bw(morphologicalGradient,0.03);\r\nSE  = strel(<span class=\"string\">'Disk'<\/span>,3,4);\r\nmask = imclose(mask, SE);\r\nmask = imfill(mask,<span class=\"string\">'holes'<\/span>);\r\nmask = bwareafilt(mask,1);\r\nnotMask = ~mask;\r\nmask = mask | bwpropfilt(notMask,<span class=\"string\">'Area'<\/span>,[-Inf, 5000 - eps(5000)]);\r\nshowMaskAsOverlay(0.5,mask,<span class=\"string\">'r'<\/span>);\r\n<\/pre><pre class=\"language-matlab\"><span class=\"comment\">%(showMaskAsOverlay is my helper function, available on the MATLAB Central File Exchange.)<\/span>\r\n<\/pre><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2015\/LorenMasked.png\" alt=\"\"> <\/p><p>However, that was complicated by the fact that border portions of Loren's jacket are almost exactly the same color as the background. If she had been standing against a green or blue screen instead, it would have been much easier to automate some <a href=\"https:\/\/en.wikipedia.org\/wiki\/Chroma_key\">chroma key compositing<\/a> to manipulate the background. Instead, I had to jump through some hoops to get there.<\/p><h4>Is the effort of automation justified?<a name=\"b6efadc2-511f-4e87-87dc-3cdaa5b6eec0\"><\/a><\/h4><p>Whenever you are faced with a task like this, it's worth thinking for a moment about the potential return on the investment that automating the task will require. If you need to process many similar images--if this were a frame of a video, for instance--you might indeed want to spend the effort required to automate the segmentation process. On the other hand, if the task is a one-off (as in this case), it might indeed be easier, faster, and potentially more accurate to do things manually. For that, the >createMask method of our <a title=\"https:\/\/www.mathworks.com\/help\/images\/ref\/imroi.html (link no longer works)\"><tt>imroi<\/tt><\/a> tools facilitates the process.<\/p><p>Creating the code snippet above took a bit of effort. Recreating it with <tt>impoly<\/tt> took a few minutes:<\/p><pre class=\"language-matlab\">h = impoly(imgca,<span class=\"string\">'closed'<\/span>,false);\r\n<\/pre><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2015\/LorenImpoly.png\" alt=\"\"> <\/p><p>I much prefer working with <tt>impoly<\/tt> to working with <tt>imfreehand<\/tt>, because the former is much easier to adjust after the fact. With <tt>imfreehand<\/tt>, I find myself tracing borders many times, trying to get it right. But with <tt>impoly<\/tt>, I can click along, and then adjust individual vertices. I can even delete or <a href=\"https:\/\/www.mathworks.com\/help\/images\/ref\/impoly.html\">add vertices<\/a> (by pressing the \"A\" key) as needed to follow difficult contours.<\/p><p>I also prefer working with <i>open<\/i> <tt>imroi<\/tt> regions for a couple reasons. First, the masks created by <tt>imroi.createMask<\/tt> are automatically closed by default anyway:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2015\/LorenMask1.png\" alt=\"\"> <\/p><h4>Improving the mask<a name=\"d3c10f42-fc65-47cf-bc48-a19d9a0cb861\"><\/a><\/h4><p>Hmmm. That doesn't <i>quite<\/i> get me the mask I want need. I'm going to modify the <tt>impoly<\/tt> object by constraining it to the image region:<\/p><pre class=\"language-matlab\">fcn = makeConstrainToRectFcn(<span class=\"string\">'impoly'<\/span>,get(imgca,<span class=\"string\">'XLim'<\/span>),get(imgca,<span class=\"string\">'YLim'<\/span>));\r\nsetPositionConstraintFcn(h,fcn);\r\n<\/pre><p>Then I'm going to add a couple of vertices, and bring them down to the bottom corners:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2015\/LorenImpoly2.png\" alt=\"\"> <\/p><p>Now the mask looks more appropriate for my task:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2015\/LorenMask2.png\" alt=\"\"> <\/p><p>(I added the red border just to clarify how the mask changed.)<\/p><h4>Modifying the background<a name=\"e7838c7f-3f30-4f7c-a0be-220706904245\"><\/a><\/h4><p>Now, of course, setting the background to white is relatively easy in MATLAB. For a <i>grayscale<\/i> image, we can just use the mask directly:<\/p><pre class=\"language-matlab\">gray = rgb2gray(img);\r\ngray(~mask) = 255;\r\nimshow(gray)\r\n<span class=\"comment\">%(The image is of class uint8; 255 is the value of \"white\" for uint8 images.)<\/span>\r\n<\/pre><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2015\/LorenGrayVisaImageWhiteBG.png\" alt=\"\"> <\/p><h4>Two problems remain...<a name=\"59a200b9-36eb-4a26-a25b-39f829c01b88\"><\/a><\/h4><p>First, Loren's image <i>isn't<\/i> grayscale. We'll need to apply that masking function planewise. Second, even for carefully drawn <tt>impoly<\/tt> regions, the interface between the region we want to keep (i.e., Loren) and the background is pretty blocky, and not very satisfying:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2015\/LorenHairInterface1.png\" alt=\"\"> <\/p><p>(Okay, maybe it's good enough for a 2\"x2\" visa picture. But for our purposes here, let's say we're not satisfied with that.)<\/p><h4>Planewise manipulations<a name=\"af1a8fff-144e-4637-a96c-e78d63accc3b\"><\/a><\/h4><p>For the first problem, we can readily break the image into its planewise components, apply the mask, and then reconstruct the color image:<\/p><pre class=\"language-matlab\"><span class=\"comment\">% Break down and mask the planes:<\/span>\r\nr = img(:,:,1);\r\ng = img(:,:,2);\r\nb = img(:,:,3);\r\nr(~mask) = 255;\r\ng(~mask) = 255;\r\nb(~mask) = 255;\r\n<span class=\"comment\">% Reconstruct the RGB image:<\/span>\r\nimg = cat(3,r,g,b);\r\nimshow(img)\r\n<\/pre><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2015\/LorenColorVisaImageWhiteBG.png\" alt=\"\"> <\/p><h4>Fixing the interface<a name=\"3919b3c2-6ccb-4dd8-a4d5-3206d7659fca\"><\/a><\/h4><p>To address the second problem (the blocky interface), I'm going to recall a <a href=\"https:\/\/blogs.mathworks.com\/pick\/2015\/05\/08\/how-do-you-create-a-mask-from-a-variable-thickness-open-freehand-curve\/\">recent discussion<\/a> I had on the <a href=\"https:\/\/blogs.mathworks.com\/pick\">Pick of the Week blog<\/a>. Capturing the code I discussed in that blog post as a function, and using the same <tt>impoly<\/tt> I created above, I can create a custom \"shell mask\" of the Loren-background interface:<\/p><pre class=\"language-matlab\">shellMask = createShellMask(h,<span class=\"string\">'thickness'<\/span>,3);\r\nimshow(shellMask);\r\n<\/pre><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2015\/LorenShellMask.png\" alt=\"\"> <\/p><p>So why would I do that? Because now I can use the excellent <a href=\"https:\/\/www.mathworks.com\/help\/images\/ref\/regionfill.html\"><tt>regionfill<\/tt><\/a> function of the <a href=\"https:\/\/www.mathworks.com\/help\/images\/index.html\">Image Processing Toolbox<\/a> to interpolate inwards using that mask:<\/p><pre class=\"language-matlab\">r = regionfill(r,shellMask);\r\ng = regionfill(g,shellMask);\r\nb = regionfill(b,shellMask);\r\nimg = cat(3,r,g,b);\r\nimshow(img)\r\n<\/pre><p>Et voila! We have successfully \"softened\" the interface and created a more natural-looking photograph:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2015\/LorenHairInterface2.png\" alt=\"\"> <\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2015\/LorenColorVisaImageWhiteBGInterpolated.png\" alt=\"\"> <\/p><h4>A final note<a name=\"9fdd1903-8833-4b2f-81d1-4b8b0d1176ea\"><\/a><\/h4><p>I am interested in hearing whether <tt>createShellMask<\/tt> is useful for others, and whether I should share it on the File Exchange. Also, the approach I took to the planewise analyses above (masking, and <tt>regionfill<\/tt>) is fairly generic, and easily converted into a function:<\/p><pre class=\"language-matlab\">imgout = planewise(fcnhandle,rgbimg,varargin)\r\n<\/pre><p>If that looks useful to you, let me know and I'll post that as well! Let me know <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=1201#respond\">here<\/a>.<\/p><p>Happy MATLABbing!<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_6c2d34d69ba74b0da1323f842b5bb451() {\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='6c2d34d69ba74b0da1323f842b5bb451 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 6c2d34d69ba74b0da1323f842b5bb451';\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 2015 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_6c2d34d69ba74b0da1323f842b5bb451()\"><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; R2015a<br><\/p><\/div><!--\r\n6c2d34d69ba74b0da1323f842b5bb451 ##### SOURCE BEGIN #####\r\n%% How Do You Modify the Background of an Image?\r\n% Today I'd like to introduce guest blogger\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/845693-brett-shoelson\r\n% Brett Shoelson>. Some of you may know Brett through\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/845693-brett-shoelson?utf8=%E2%9C%93&detail=fileexchange\r\n% his File Exchange submissions>, or through his involvement with the\r\n% <https:\/\/blogs.mathworks.com\/pick\/ Pick of the Week> blog, or from\r\n% occasional guest posts on <https:\/\/blogs.mathworks.com\/steve\/ Steve\u00e2\u20ac\u2122s blog\r\n% on image processing>.\r\n%% \"The visa problem\"\r\n% Loren recently told me she had a pending international trip that requires\r\n% a visa. She had a photograph taken against a background that was\r\n% unsuitable for use in her visa document, and she asked: \"How would I go\r\n% about changing the background to white?\"\r\n\r\n%% The original photo\r\n% \r\n% <<LorenVisaImage.png>>\r\n\r\n%% First question: how do we isolate the background?\r\n% \"I wonder if this will entail creating a manual mask?\", Loren asked.\r\n%\r\n% Great question! I can certainly come up with an automated approach to\r\n% masking (or \"segmenting\") the region of interest (\"ROI\"). For instance:\r\n%\r\n%%\r\n% \r\n%   img = imread('LorenVisaImage.png');\r\n%   gray = rgb2gray(img);\r\n%   SE  = strel('Disk',1,4);\r\n%   morphologicalGradient = imsubtract(imdilate(gray, SE),imerode(gray, SE));\r\n%   mask = im2bw(morphologicalGradient,0.03);\r\n%   SE  = strel('Disk',3,4);\r\n%   mask = imclose(mask, SE);\r\n%   mask = imfill(mask,'holes');\r\n%   mask = bwareafilt(mask,1);\r\n%   notMask = ~mask;\r\n%   mask = mask | bwpropfilt(notMask,'Area',[-Inf, 5000 - eps(5000)]);\r\n%   showMaskAsOverlay(0.5,mask,'r');\r\n%\r\n%   %(showMaskAsOverlay is my helper function, available on the MATLAB Central File Exchange.)\r\n\r\n%% \r\n% \r\n% <<LorenMasked.png>>\r\n\r\n%%\r\n% However, that was complicated by the fact that border portions of Loren's\r\n% jacket are almost exactly the same color as the background. If she had\r\n% been standing against a green or blue screen instead, it would have been\r\n% much easier to automate some\r\n% <https:\/\/en.wikipedia.org\/wiki\/Chroma_key chroma key compositing>\r\n% to manipulate the background. Instead, I had to jump through some hoops\r\n% to get there.\r\n\r\n%% Is the effort of automation justified?\r\n% Whenever you are faced with a task like this, it's worth thinking for a\r\n% moment about the potential return on the investment that automating the\r\n% task will require. If you need to process many similar imagesREPLACE_WITH_DASH_DASHif this\r\n% were a frame of a video, for instanceREPLACE_WITH_DASH_DASHyou might indeed want to spend the\r\n% effort required to automate the segmentation process. On the other hand,\r\n% if the task is a one-off (as in this case), it might indeed be easier,\r\n% faster, and potentially more accurate to do things manually. For that,\r\n% the <https:\/\/www.mathworks.com\/help\/images\/create-binary-mask-using-an-roi-object.html?searchHighlight=createMask createMask> method of our \r\n% <https:\/\/www.mathworks.com\/help\/images\/ref\/imroi.html |imroi|> tools\r\n% facilitates the process.\r\n%\r\n% Creating the code snippet above took a bit of effort. Recreating it with\r\n% |impoly| took a few minutes:\r\n\r\n%% \r\n%   h = impoly(imgca,'closed',false);\r\n%% \r\n% \r\n% <<LorenImpoly.png>>\r\n%%\r\n% I much prefer working with |impoly| to working with |imfreehand|,\r\n% because the former is much easier to adjust after the fact. With\r\n% |imfreehand|, I find myself tracing borders many times, trying to get it\r\n% right. But with |impoly|, I can click along, and then adjust individual\r\n% vertices. I can even delete or\r\n% <https:\/\/www.mathworks.com\/help\/images\/ref\/impoly.html add vertices> (by\r\n% pressing the \"A\" key) as needed to follow difficult contours.\r\n%\r\n% I also prefer working with _open_ |imroi| regions for a couple reasons.\r\n% First, the masks created by |imroi.createMask| are automatically closed\r\n% by default anyway:\r\n\r\n%% \r\n% \r\n% <<LorenMask1.png>>\r\n\r\n%% Improving the mask\r\n% Hmmm. That doesn't _quite_ get me the mask I want need. I'm going to\r\n% modify the |impoly| object by constraining it to the image region:\r\n\r\n%%\r\n%\r\n%   fcn = makeConstrainToRectFcn('impoly',get(imgca,'XLim'),get(imgca,'YLim'));\r\n%   setPositionConstraintFcn(h,fcn);\r\n\r\n%% \r\n% Then I'm going to add a couple of vertices, and bring them down to the\r\n% bottom corners:\r\n\r\n%% \r\n% \r\n% <<LorenImpoly2.png>>\r\n\r\n%%\r\n% Now the mask looks more appropriate for my task:\r\n\r\n%% \r\n% \r\n% <<LorenMask2.png>>\r\n\r\n%%\r\n% (I added the red border just to clarify how the mask changed.)\r\n\r\n%% Modifying the background\r\n% Now, of course, setting the background to white is relatively easy in\r\n% MATLAB. For a _grayscale_ image, we can just use the mask directly:\r\n\r\n%%\r\n%   gray = rgb2gray(img);\r\n%   gray(~mask) = 255;\r\n%   imshow(gray)\r\n%   %(The image is of class uint8; 255 is the value of \"white\" for uint8 images.) \r\n\r\n%% \r\n% \r\n% <<LorenGrayVisaImageWhiteBG.png>>\r\n\r\n%% Two problems remain...\r\n% First, Loren's image _isn't_ grayscale. We'll need to apply that masking\r\n% function planewise. Second, even for carefully drawn |impoly| regions,\r\n% the interface between the region we want to keep (i.e., Loren) and the\r\n% background is pretty blocky, and not very satisfying:\r\n\r\n%%\r\n% \r\n% <<LorenHairInterface1.png>>\r\n\r\n%%\r\n% (Okay, maybe it's good enough for a 2\"x2\" visa picture. But for our\r\n% purposes here, let's say we're not satisfied with that.)\r\n\r\n%% Planewise manipulations\r\n% For the first problem, we can readily break the image into its planewise\r\n% components, apply the mask, and then reconstruct the color image:\r\n\r\n%%\r\n% \r\n%   % Break down and mask the planes:\r\n%   r = img(:,:,1);\r\n%   g = img(:,:,2);\r\n%   b = img(:,:,3);\r\n%   r(~mask) = 255;\r\n%   g(~mask) = 255;\r\n%   b(~mask) = 255;\r\n%   % Reconstruct the RGB image:\r\n%   img = cat(3,r,g,b);\r\n%   imshow(img)\r\n\r\n%% \r\n% \r\n% <<LorenColorVisaImageWhiteBG.png>>\r\n\r\n%% Fixing the interface\r\n% To address the second problem (the blocky interface), I'm going to recall\r\n% a\r\n% <https:\/\/blogs.mathworks.com\/pick\/2015\/05\/08\/how-do-you-create-a-mask-from-a-variable-thickness-open-freehand-curve\/\r\n% recent discussion> I had on the <https:\/\/blogs.mathworks.com\/pick Pick of\r\n% the Week blog>. Capturing the code I discussed in that blog post as a\r\n% function, and using the same |impoly| I created above, I can create a\r\n% custom \"shell mask\" of the Loren-background interface:\r\n\r\n%% \r\n%\r\n%   shellMask = createShellMask(h,'thickness',3);\r\n%   imshow(shellMask);\r\n\r\n%% \r\n% \r\n% <<LorenShellMask.png>>\r\n\r\n%%\r\n% So why would I do that? Because now I can use the excellent \r\n% <https:\/\/www.mathworks.com\/help\/images\/ref\/regionfill.html |regionfill|>\r\n% function of the\r\n% <https:\/\/www.mathworks.com\/help\/images\/index.html?searchHighlight=image%20processing%20toolbox Image Processing Toolbox> \r\n% to interpolate inwards using that mask:\r\n\r\n%%\r\n%\r\n%   r = regionfill(r,shellMask);\r\n%   g = regionfill(g,shellMask);\r\n%   b = regionfill(b,shellMask);\r\n%   img = cat(3,r,g,b);\r\n%   imshow(img)\r\n\r\n%%\r\n% Et voila! We have successfully \"softened\" the interface and created a\r\n% more natural-looking photograph:\r\n\r\n%%\r\n% \r\n% <<LorenHairInterface2.png>>\r\n\r\n%% \r\n% \r\n% <<LorenColorVisaImageWhiteBGInterpolated.png>>\r\n\r\n%% A final note \r\n% I am interested in hearing whether |createShellMask| is useful for\r\n% others, and whether I should share it on the File Exchange. Also, the\r\n% approach I took to the planewise analyses above (masking, and |regionfill|)\r\n% is fairly generic, and easily converted into a function:\r\n\r\n%%\r\n%\r\n%   imgout = planewise(fcnhandle,rgbimg,varargin)\r\n\r\n%%\r\n% If that looks useful to you, let me know and I'll post that as well! Let\r\n% me know <https:\/\/blogs.mathworks.com\/loren\/?p=1201#respond here>.\r\n\r\n%%\r\n% Happy MATLABbing!\r\n##### SOURCE END ##### 6c2d34d69ba74b0da1323f842b5bb451\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/loren\/2015\/LorenHairInterface2.png\" onError=\"this.style.display ='none';\" \/><\/div><!--introduction--><p>Today I'd like to introduce guest blogger <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/845693-brett-shoelson\">Brett Shoelson<\/a>. Some of you may know Brett through <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/845693-brett-shoelson?utf8=%E2%9C%93&amp;detail=fileexchange\">his File Exchange submissions<\/a>, or through his involvement with the <a href=\"https:\/\/blogs.mathworks.com\/pick\/\">Pick of the Week<\/a> blog, or from occasional guest posts on <a href=\"https:\/\/blogs.mathworks.com\/steve\/\">Steve&#8217;s blog on image processing<\/a>.... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2015\/06\/24\/how-do-you-modify-the-background-of-an-image\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[27],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/1201"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=1201"}],"version-history":[{"count":3,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/1201\/revisions"}],"predecessor-version":[{"id":2446,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/1201\/revisions\/2446"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=1201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=1201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=1201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}