Is it possible to crop an image along a particular curve. for ex. I want to crop out the finger image out of this image, but i dont want to crop it along a rectangle.
you need a binary mask and apply that mask as alpha map
here is how it is usually done
s = 100;
h = imagesc(rand(s));%show some garbage
%prepare a circular mask
dummy = meshgrid(-s/2:s/2-1).^2;%squared distances from the center
mask = sqrt(dummy+dummy') < 20;%20 is the radius of your mask
%here you go, mask the image in a curved manner
set(h,'alphaData',mask);
exporting it as a png would do the job.
so in your case, you need to make your own mask, this means either threshold your bitmap image or parameterize the space (as I did it with the circle above).
Related
I have this image (8 bit, pseudo-colored, gray-scale):
And I want to create an intensity band of a specific measure around it's border.
I tried erosion and other mathematical operations, including filtering to achieve the desired band but the actual image intensity changes as soon as I use erosion to cut part of the border.
My code so far looks like:
clear all
clc
x=imread('8-BIT COPY OF EGFP001.tif');
imshow(x);
y = imerode(x,strel('disk',2));
y1=imerode(y,strel('disk',7));
z=y-y1;
figure
z(z<30)=0
imshow(z)
The main problem I am encountering using this is that it somewhat changes the intensity of the original images as follows:
So my question is, how do I create such a band across image border without changing any other attribute of the original image?
Going with what beaker was talking about and what you would like done, I would personally convert your image into binary where false represents the background and true represents the foreground. When you're done, you then erode this image using a good structuring element that preserves the roundness of the contours of your objects (disk in your example).
The output of this would be the interior of the large object that is in the image. What you can do is use this mask and set these locations in the image to black so that you can preserve the outer band. As such, try doing something like this:
%// Read in image (directly from StackOverflow) and pseudo-colour the image
[im,map] = imread('http://i.stack.imgur.com/OxFwB.png');
out = ind2rgb(im, map);
%// Threshold the grayscale version
im_b = im > 10;
%// Create structuring element that removes border
se = strel('disk',7);
%// Erode thresholded image to get final mask
erode_b = imerode(im_b, se);
%// Duplicate mask in 3D
mask_3D = cat(3, erode_b, erode_b, erode_b);
%// Find indices that are true and black out result
final = out;
final(mask_3D) = 0;
figure;
imshow(final);
Let's go through the code slowly. The first two lines take your PNG image, which contains a grayscale image and a colour map and we read both of these into MATLAB. Next, we use ind2rgb to convert the image into its pseudo-coloured version. Once we do this, we use the grayscale image and threshold the image so that we capture all of the object pixels. I threshold the image with a value of 10 to escape some quantization noise that is seen in the image. This binary image is what we will operate on to determine those pixels we want to set to 0 to get the outer border.
Next, we declare a structuring element that is a disk of a radius of 7, then erode the mask. Once I'm done, I duplicate this mask in 3D so that it has the same number of channels as the pseudo-coloured image, then use the locations of the mask to set the values that are internal to the object to 0. The result would be the original image, but having the outer contours of all of the objects remain.
The result I get is:
How to identify boundaries of a binary image to crop in matlab?
ie. the input binary image has no noises. only has one black object in white background.
You can use the edge command in MATLAB.
E = edge(I);
I would be an input grayscale or binary image. This will return a binary image with only the edges.
This can provide further assistance:
http://www.mathworks.com/help/images/ref/edge.html
If your image is just black-and-white and has a single object, you can likely make use of the Flood fill algorithm, for which Matlab has built-in support!
Try the imfill function (ref).
This should give you the extents of the object, which would allow you to crop at will.
You can also invert the image, then do regionprops to extract all of the properties for separate objects. You need to invert the image as regionprops assumes that the objects are white while the background is black. A good thing about this approach is that it generalizes for multiple objects and you only need about a few lines of code to do it.
As an example, let's artificially create a circle in the centre of an image that is black on a white background as you have suggested. Let's assume this is also a binary image.
im = true(200, 200);
[X,Y] = meshgrid(1:200, 1:200);
ind = (X-100).^2 + (Y-100).^2 <= 1000;
im(ind) = false;
imshow(im);
This is what your circle will look like:
Now let's go ahead and invert this so that it's a white circle on black background:
imInvert = ~im;
imshow(imInvert);
This is what your inverted circle will look like:
Now, invoke regionprops to find properties of all of the objects in our image. In this case, there should only be one.
s = regionProps(imInvert, 'BoundingBox');
As such, s contains a structure that is 1 element long, and has a single field called BoundingBox. This field is a 4 element array that is structured in the following way:
[x y w h]
x denotes the column/vertical co-ordinate while y denotes the row/horizontal co-ordinate of the top-left corner of the bounding box. w,h are the width and height of the rectangle. Our output of the above code is:
s =
BoundingBox: [68.5000 68.5000 63 63]
This means that the top-left corner of our bounding box is located at (x,y) = (68.5,68.5), and has a width and height of 63 each. Therefore, the span of our bounding box goes from rows (68.5,131.5) and columns (68.5,131.5). To make sure that we have the right bounding box, you can draw a rectangle around our shape by using the rectangle command.
imshow(im);
rectangle('Position', s.BoundingBox);
This is what your image will look like with a rectangle drawn around the object. As you can see, the bounding box given from regionprops is the minimum spanning bounding box required to fully encapsulate the object.
If you wish to crop the object, you can do the following:
imCrop = imcrop(imInvert, s.BoundingBox);
This should give you the cropped image that is defined by the bounding box that we talked about earlier.
Hope this is what you're looking for. Good luck!
I'm trying to detect the screen border from the image (In need the 4 corners).
This is the Image:
I used HOUGH transform to detect lines and intersection points (the black circles) and this is the result:
Now I need to find the 4 corners or the 4 lines.. everything that will help me to crop the image, What can I do?
Maybe use the screen aspect ratio? but how?
I'm using Matlab.
Thanks.
A naive first approach that would do the trick if and only if you have same image conditions (background and laptop).
Convert your image to HSV (examine that in HSV the image inside the
screen is the only portion of the image with high Saturation, Value
values)
Create a mask by hard thresholding the Saturation and Value channels
Dilate the mask to connect disconnected regions
Compute the convex hull to get the mask boundaries
See a quick result:
Here is the same mask with the original image portion that makes it through the mask:
Here is the code to do so:
img = imread( 'imagename.jpg'); % change the image name
hsv = rgb2hsv( img);
mask = hsv(:,:,2)>0.25 & hsv(:,:,3)>0.5;
strel_size = round(0.025*max(size(mask)));
dilated_mask=imdilate(mask,strel('square',strel_size));
s=regionprops(dilated_mask,'BoundingBox','ConvexHull');
% here Bounding box produces a box with the minimum-maximum white pixel positions but the image is not actually rectangular due to perspective...
imshow(uint8(img.*repmat(dilated_mask,[1 1 3])));
line(s.ConvexHull(:,1),s.ConvexHull(:,2),'Color','red','LineWidth',3);
You may, of course, apply some more sophisticated processing to be a lot more accurate and to correct the convex hull to be just a rectangular shape with perspective, but this is just a 5 minutes attempt just to showcase the approach...
I have drawn some polygon on an image after using imshow and hold on, and filled it with white as follows:
fill(x(k),y(k),[1 1 1])
How can I make the rest of the image black while keeping the polygon white? In other words, how can I make a binary image, where the polygon is white, and the rest of the image is black? Provided that the polygon is a bit complex.
Thanks.
Use roipoly:
BW = roipoly( I, x(k), y(k) );
Where I is your input image (you only need it to get the desired output size of the binary maxk BW). y and x are the corners of your polygon.
I need to crop a circle in MATLAB.
I need to perform iris segmentation, and I´ve identified the center point and the radius of the iris, and I need to cut it off from the image.
I have a vector ci that ci(1) is X-coordinate ci(2) is Y-coordinate and ci(3) is the radius of the circle.
One way to do this is to create a binary mask with ones inside the circle and zeros outside. You can then use this array to either mask everything outside the circle with NaNs, or to read the pixel values of the image inside the mask.
To create a circle mask, an easy way is to create coordinate arrays centered on the iris, and threshold the distance, like this:
[xx,yy] = ndgrid((1:imageSize(1))-ci(1),(1:imageSize(2))-ci(2));
mask = (xx.^2 + yy.^2)<ci(3)^2;