-2

I'm trying to apply an algorithm only to a specific region of an image. I tried imfreehand, but not able, at least for me, to do that using this function.

So, is there some way when running my code for the operations to be applied only to some specific region of an image in MATLAB?

Thanks.

Simplicity
  • 47,404
  • 98
  • 256
  • 385
  • Can you be more specific? Are you asking how to allow the user to select a rectangular region, like `imfreehand` does? Or are you asking how to extract a region from an image to process? Should the region be rectangular? – devrobf Aug 05 '13 at 06:57
  • It would be easier if you would provide an example (=code) of where you are running into trouble. – Buck Thorn Aug 05 '13 at 08:34
  • I added an example of erode to my answer – Buck Thorn Aug 05 '13 at 10:46

2 Answers2

2

Using a mask defined by any of the "imroi" functions - imfreehand and imellipse included, you can use roifilt2 to filter just the roi using a given filter or function.

First, define the area:

imshow(I); %display your image
h = imfreehand; % now pick the region
BW = createmask(h); %makes BW mask

Then, use roifilt2 in one of the following ways -

Define a filter and apply it:

H = fspecial('unsharp');
I2 = roifilt2(H,I,BW);`

Apply a given function to the roi:

I2 = roifilt2(I, BW, 'histeq');

Apply a given function to the roi, specifying parameters:

fh = @(I)(histeq(I,5)); %define function
I2 = roifilt2(I, BW, fh); 

The last is equivalent to calling I2 = hist(I,5); but only works on the defined roi.

ETA:

If you want to call multiple functions on the roi, it may be easiest to define your own function, which takes an image input (and optionally, other parameters), applies the appropriate filters/functions to the image, and outputs a final image - you would then call "myfunc" in the same way as "histeq" above.

nkjt
  • 7,825
  • 9
  • 22
  • 28
  • Thanks for the nice explanation. I have the following lines which I want to apply to the `ROI`. `se=strel('disk',3); erosion=imerode(img,se); result_image=imsubtract(img,erosion);` How can I apply `roifilt2` in this case? – Simplicity Aug 05 '13 at 10:17
  • See the last two lines, only define two functions - one using imerode and one using imsubtract and call roifilt2 twice. You can put variables in the function, e.g. n=5; fh = @(I)(histeq(I,n)); has the same effect as my last example above. – nkjt Aug 05 '13 at 10:39
  • Just a small note. `createmask` seems has to be `createMask` – Simplicity Aug 05 '13 at 11:54
0

You can try roipoly.

There is an example on SO here.

Here's an example:

img = imread('peppers.jpg');        % loads the image we want to use
[BW,xi,yi] = roipoly(img);          % create a polynomial surrounding region
BW = repmat(uint8(BW),[1,1,3]);     % create mask
selIMG = img.*BW;                   % apply mask to retain roi and set all else to 0
imview(selIMG)

se=strel('disk',3); 
erosion=imerode(selIMG,se); 
result_image=imsubtract(selIMG,erosion);
imview(result_image)

Edit

On erode: as the matlab doc explains, imerode picks the lowest value from the surrounding pixels (imdilate does the opposite). This means that the original treatment in my answer is inadequate for imerode, it would be better to set pixels outside the selection to max on the colorscale, and I provide an example here on how to do this "manually":

img = imread('peppers.jpg');                        % loads the image we want to use
[BW,xi,yi] = roipoly(img);                          % logical mask which contains pixels of interest
nBW = uint8(~BW);                                   % inverse of logical mask to pick surrounding pixels
surroundingMaxedOut = repmat(255*nBW,[1,1,3]);      % set surrounding pixels to max value
nBW = repmat(nBW,[1,1,3]);                          % make mask with 3 channels to pick surrounding pixels
BW = repmat(uint8(BW),[1,1,3]);                     % make mask with 3 channels to handle RGB
selIMG = img.*BW;                                   % pick the image region of interest
selIMG = selIMG + surroundingMaxedOut;              % final selection with surrounding pixels maxed out
imview(selIMG)                                      % inspect the selection


se=strel('disk',3); 
erosion=imerode(selIMG,se);                         % apply erosion 
finalIMG = img.*nBW + BW.*erosion;                  % insert eroded selection into the original image
imview(finalIMG)

As other answers show, matlab has routines that handle these operations implicitly and are more efficient not least in terms of memory management, however this example provides you with more control so you can see what is happening.

Community
  • 1
  • 1
Buck Thorn
  • 5,024
  • 2
  • 17
  • 27
  • Thanks for your reply. I think this will give me a shape. What I'm aiming at is while processing an image, only a specific region will be processed `without extracting` that region – Simplicity Aug 05 '13 at 09:32
  • Could you be more specific: clearly when you want to process a specific region you have to isolate those specific pixels, say in a new array (or indexing vector) for processing. You can use roipoly to generate a mask to pick those pixels and then selectively apply operations to those pixels, no? – Buck Thorn Aug 05 '13 at 09:45
  • Thanks for your reply. When I tried your solution, I got the following error: `Error using .* Integers can only be combined with integers of the same class, or scalar doubles.`. Any ideas? – Simplicity Aug 05 '13 at 11:32
  • This was solved by doing the following: `BW = repmat(double(BW),[1,1,3]); BWgray=rgb2gray(BW);` – Simplicity Aug 05 '13 at 11:45
  • So, does that apply the operations **only** on that specific region? – Simplicity Aug 05 '13 at 11:45
  • The error has to do with the encoding of your image when read in by imread, I believe it can end up as type double in which case the operations would not work as written. Start by checking what type `img` is, for instance b ytyping `whos img`. If it is type `double` you might try simply removing the `uint8` conversion. – Buck Thorn Aug 05 '13 at 13:46
  • Good now I read your fix. As for how imerode works, I am adding an explanation to my answer. – Buck Thorn Aug 05 '13 at 13:51