Find the edges of image and crop it in MATLAB - image

I have a RGB image. I have scanned the image. So the image occupies a small portion of an A4 size sheet.
I want to find the border of the image and crop it. I could use edge detection operators like 'Sobel' etc, but they detect all the edges present in the image. All I want is the border of the image. Also many of the edge detection functions including 'bwboundaries' work only with binary or grayscale images. My image is RGB.
I tried using 'imcrop', but this is more of interactive cropping. I am keen on doing this automatically.
Uploading a test image:

Since this is an rgb image, there will be apparent color in the gray areas, but there should be none in the white ones. You can make use of this to find the image, then you can get the bounding box.
img = imread('http://i.stack.imgur.com/dEawA.jpg');
%# instead of "==" you can check for similarity within a tolerance
tt=img(:,:,1)==img(:,:,2) & img(:,:,2) == img(:,:,3);
%# invert tt so that it's 1 where there is signal
tt = ~tt;
%# clean up some of the smaller artifacts
tto = imopen(~tt,strel('square',100));
%# get the areas and bounding box of the areas above threshold
%# as an additional criterion, you could also use excentricity
%# or you could simply remove the bottom 100 rows of the scan
stats = regionprops(tto,'BoundingBox','Area');
area = cat(1,stats.Area);
[~,maxAreaIdx] = max(Area);
bb = round(stats(maxAreaIdx).BoundingBox);
%# note that regionprops switches x and y (it's a long story)
croppedImage = img(bb(2):bb(2)+bb(4),bb(1):bb(1)+bb(3),:);
There is a bit of a border left due to rotation. You can use the mask tto above to set all non-image pixels to NaN before cropping, or you can use imrotate to fix your image.

You can try to detect the corners of your image using e.g. the Harris-Detector (corner in Matlab). Set the maximum number of corners to detect to 4. Then use the positions of the corners in imcrop. If you would post an image I could give you more specific hints. Your image being RGB shouldn't be a problem, just convert it to grayscale.

You can try using bwlabel http://www.mathworks.com/help/toolbox/images/ref/bwlabel.html (along with find, as noted in the help page) to get the indices of the image and use those to crop the original.
You'll first need to convert the original image to binary using im2bw http://www.mathworks.com/help/toolbox/images/ref/im2bw.html.

Related

How to trace the surface area as well as smoothen a specific region in an image using MATLAB

I have an image with 6 colors each indicating a value. I had obtained an image as shown below.
I need to smoothen the edges and then find out the area as well as the surface area of that region. The second image shows a black line drawn in the edges which indicates that I need to smoothen the edges in such a way.
I had used segmentation to create a mask as shown in the third image, and then obtain a segmented image using the code following the image.
I have used the following code for generating till the masked image.
Source : How to segment
imshow(Out1)
str = 'Click to select initial contour location. Double-click to confirm and proceed.';
title(str,'Color','b','FontSize',12);
disp(sprintf('\nNote: Click close to object boundaries for more accurate result.'));
mask = roipoly;
figure, imshow(mask)
title('Initial MASK');
maxIterations = 3000;
bw = activecontour(Out1, mask, maxIterations, 'Chan-Vese');
% Display segmented image
figure, imshow(bw)
title('Segmented Image');
In order to use the 'activecontour' function my image needs to be a grey-scale image, which I'm not being able to convert to greyscale and back. Also to find out surface area/ area of the region is there any inbuilt function. Please help thanks.
use im2double, im2uint8, etc. to convert binary image to grayscale.
use bwarea or regionprops to find the region area.

How to blend tone mapping noise into an image without a patch effect?

I would like to create tone mapping (including contrast change, brightness change, gamma change) noises in specific areas of a facial image (eyes, mouth, nose).
I've managed to auto extract the required features from the image.
I've used imadjust to create contrast change (for example) on the specific features of the image and then I've blended them using vision.AlphaBlender and a mask of the extracted areas.
The result is the patched image below:
What should I do in order to blend the noised feature into the original image with a natural effect which won't create a patchy image?
The answer to my question is taking the mask of the extracted areas.
apply Gaussian noise on the mask which will create a blurring effect on the mask.
Then, apply by weighting , the blurred mask on the original image to blend the noise into the image natuarlly and that way preventing any patch effect as displayed on the attached image in my question.
Here is the code snippet:
% create a guassian filter
G = fspecial('gaussian', [25 25], 20);
% blur the mask - make sure your original mask is a double type
blurredMask = imfilter(mask,G,'same');
% blend the image , the noised image and the original
% image by weighting with the blurred mask
image = originalImage.*(1-blurredMask ) + noisedImage.*blurredMask;
I hope I've helped someone with my question and my answer.

Resizing an image to fit around an isolated object in MATLAB

I am working with RGB images that contain a single object against a monochrome background.
My goal is to isolate the object in the image and resize the image to contain only the object.
I have successfully been able to detect the object by converting the image to a binary image using an appropriate threshold. Then, in order to isolate the object in the original RGB image I use the binary image as a mask with the original RGB image.
maskedImage = bsxfun(#times,originalimage, cast(binaryimage,class(originalimage)));
This leaves me with a image only containing the object surrounded by a black background. This is due to the fact that the binary image mask I used contained the object in white pixels and the background in black pixels and since possess intensity values of 0 the masking process converted all pixels that didn't belong to the object to black pixels. I've attached an example below.
I would now like to draw a bounding box around the object and resize the image to the size of the bounding box, so that I can get rid as much of the surrounding black pixels as possible. Is there any way of doing this? Any help would be appreciated.
Given the segmented image, you want to crop out all of the black pixels and provide the closest bounding box that fully encapsulates the object. That's very simple.
You already have a binary mask that determines what is an object and what's background. You simply need to find the minimum spanning bounding box. You can find the top-left and bottom right corner by obtaining all of the pixel locations that are non-zero in the mask, and finding the minimum and maximum row and column coordinates. You'd then just use these to crop out the segmented image.
As such:
%// Find all non-zero locations in the mask
[row,col] = find(binaryImage);
%// Find the top left corner of the mask
topLeftRow = min(row);
topLeftCol = min(col);
%// Find the bottom right corner of the mask
bottomRightRow = max(row);
bottomRightCol = max(col);
%// Extract the object
extracted = maskedImage(topLeftRow:bottomRightRow, topLeftCol:bottomRightCol, :);
The words of the day are Bounding boxes !
If you want the minimum-area rectangle to crop only the nonzero values, you want the bounding box of your region, then set your phasers to stun and you're all set !
See this Matlab help forum question for more implementation details in Matlab.

Crop an image in Matlab

I want to crop an image from a specific row onwards. Please help me how can I do this. I am a beginner in Matlab.
This page has a lot of great info on dealing with images in matlab.
When you load an image in matlab, it is loaded as a MxNx3 matrix. The third dimension stores the RGB values of each pixel. So to crop an image you simply select just the range of rows and columns you want to keep:
cropped_image = image(RowStart:RowEnd,ColStart:ColEnd,:);
See this: http://www.mathworks.com/help/techdoc/creating_plots/f9-47085.html
There is a graph editor icon in the screen where you see your graph, it should look like this:
Press it, you will get a big graph editor, now try pressing on the graph or one of the functions, in the lower right part you can set ranges, this will crop the image.
You can use imcrop function in Matlab
CropIm = imcrop(I, rectangle);
rectangle is a four-element position vector [xmin ymin width height] which indicates the size and position of the crop rectangle.
Im = imread('test.tif');
Im2 = imcrop(Im,[75 68 130 112]);
imshow(Im), figure, imshow(Im2)

In MATLAB, how to annotate a figure with an image?

I'd like to overlay an image on top of my figure at a specific point..
e.g. I want "cherry.png" [24px X 24px] drawn at the normalized point [0.20, 0.50] of a 600px X 600px figure.
I have access to the Image Processing toolbox, and I'm aware of "imread()", however it is unclear to me how to overlay at a specific point. Any ideas/references that I should check out?
If you want your 24-by-24 pixel image to be centered at the normalized point (0.2,0.5) (equivalent to (120,300) in pixels), then you can create an axes object that is 24-by-24 pixels and centered at your point and add an image to the axes with the IMAGE function. For example:
img = imread('cherry.png'); %# Read the data from your image file
hFigure = figure('Position',[100 100 600 600]); %# Make the figure window
hAxes = axes('Parent',hFigure,... %# Add the axes to the figure
'Units','pixels',... %# with units of pixels
'Position',[108 288 24 24]); %# so the position is easy to define
hImage = image(img,'Parent',hAxes); %# Plot the image
set(hAxes,'Visible','off'); %# Turn the axes visibility off
Note that when I loaded the image data using IMREAD I assumed it was a 3-D RGB image. If it's an indexed image you'll have to get the additional color map output from IMREAD so you can convert the indexed image to an RGB image.

Resources