Resizing an image to fit around an isolated object in MATLAB - image

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.

Related

Finding out number of pixels in white area in binary image as well as number of pixels of ROI in original image in MATLAB

I have segmented image in which my region of interest (ROI) was white color cotton. Now I want to compare the number of pixels in segmented area i.e. total number of pixels in white blob in binary image with actual number of pixels of ROI in actual image. How I can do that. Following figure can clear the point.
As we can see from original image, my ROI was white color cotton circled in red boundry. When I segmented this image I got binary image as shown. As we can noticed there are some missing areas in binary image as compare to original area. So, I want to count the number of pixels in original image of ROI and number of pixels of white blob in binary image. So that I can calculate difference in actual pixels of ROI and actual segmented number of pixels.
Thank You.
If you wish to not draw the boundaries yourself, you can try this. It might not be as precise as you need, but you might get close to the actual value by tweaking with the thresholding values I used (100 for all 3 channels in this case).
Assume I is your original image. First create the binary mask by thresholding with the RGB values. Then remove all the small objects that don't have at least a 2000 pixel area. Then sum up the pixels of that object.
IT = I(:,:,1) > 100;
IT(I(:,:,2) < 100) = 0;
IT(I(:,:,3) < 100) = 0;
IT = bwareaopen(IT, 2000);
sum(IT(:) > 0)
21380
Resulting image:

Get pixel values from image: Matlab

I have a simple green fluorescent image. I want to find the total number of pixels that are above a specific value using MATLAB. I don't know where the pixel values are stored in an image.
Here is the green fluorescent image. I want to know which percentage of the pixels have value of more than a specific threshold. For example in this image, if the pixel value in the cells are around X, then I want to find the total number of pixels that are above X.
If you read a colored image using imread, you get a 3D matrix in which the first two indices are the image coordinates; (row, columns); and the last index represents the color channels. For the typical use case of an RGB image, the color channels are:
1 = red
2 = green
3 = blue.
Other possibilities are grayscale, CMYK and indexed images. Please check the official documentation for more information.

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.

Image pixelation library, non-square "pixel" shape

I've seen a few libraries that pixelate images, some of them even feature non-square shapes such as The Pixelator's circle and diamond shapes.
I'm looking however to make a particular shape, I want a "pixel" that is 19x27 px. Essentially, the image would still look pixelated but it would use tallish rectangle shapes as the pixel base.
Are there any libraries out there that do this, if not, what alterations to existing algorithms/functions would I need to make to accomplish this?
Unless I am not understanding your question, the algorithm you need is quite simple!
Just break your image up into a grid of rectangles the size you want (in this case 19x27). Loop over each section of the grid and take the average color of the pixels inside (you can simply take the average of each channel in RGB independently). Then set all of the pixels contained inside to the average color.
This would give you an image that is the same size as your input. You could of course resize your image first to a more appropriate output size.
You might want to look up convolution matrices.
In a shader, you would use your current pixel location to grab a set of nearby pixels from the original image to render to a pixel in a new buffer image.
It is actually just a slight variation of the Box Blur image processing algorithm except that instead of grabbing from the nearby pixels you would grab by the divisions of the original image relative to the 19x27 divisions of the resulting image.

Find the edges of image and crop it in MATLAB

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.

Resources