I am rotating my image with the following code:
CGAffineTransform rotate = CGAffineTransformMakeRotation( [ratio floatValue] );
[imageView setTransform:rotate];
But it doesn't have sharp edges, does someone know a solution for this?
Here's the image I get:
Using the UIImageView's CALayer to rasterize the image will provide the best antialiasing.
imageView.layer.shouldRasterize = YES;
The edges of the image itself look jagged because they are being placed into a pixel grid directly, and not being interpolated. Nearest Neighbor Interpolation is the simplest kind of interpolation, where if you have pixel grid A and you move your image to pixel grid B, the pixels in grid B are chosen by simply choosing the closest pixel from grid A. Other forms of interpolation choose a weighted average of the closest pixels to arrive at the pixel value in grid B.
Your image, with its jagged edges, looks like it's using nearest neighbor interpolation, which may be the default type of interpolation on an affine transform on an iphone.
When you use some other interpolation scheme other than nearest neighbor, you'll get aliasing effects, where the subsampling isn't perfect as you transfer from one pixel grid to another. That effect makes edges in the image itself seem blurrier than they otherwise would.
just add 1px transparent border to your image
CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);
UIGraphicsBeginImageContext( imageRect.size );
[image drawInRect:CGRectMake(1,1,image.size.width-2,image.size.height-2)];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Anytime you do transforms on an image (except in 90° increments) it is going to cause slightly softer edges due to pixel interpolation.
There is a key that you can set in Info.plist that enables antialiasing of the edges: UIViewEdgeAntialiasing.
As described in the following answer: When I rotate an UIImageView with the transform property, the edges pixellate
The simplest solution:
Simply add this key-value pair to your Info.plist:
UIViewEdgeAntialiasing set to YES.
https://stackoverflow.com/a/12066215/1469060
Related
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...
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).
I want to rotate an image (UIImage) but can only do it from a default axis which is dead centre of the image ! as in Fig A. I want to move the axis to the centre of the x axis at the foot of the image as in Fig B. Can someone help me with this? I can only think of work arounds such as placing the image on an imaginary circle around the origin where the centre of the image would be where I position, then rotate the objects. This is too complicated and hopefully unneccessary. Imagine i want to place a number of images around a clock face with the origin in the centre where the clock hands originate, that's what I want to achieve. (The maths for doing this would also be appreciated).
(mid x axis and mid y axis).
Try using the view's underlying CALayer's anchorPoint property.
http://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html#//apple_ref/doc/uid/TP40004500-CH1-SW36
I think you can do it by first rotating using CGContextRotateCTM and then shifting that center point to the point you want it to be by using CGContextTranslateCTM
Like rotate 90 degree first to right
then shift center(x,y) to newPoint((x- width/2), (y - height/2)) here width and height are of rotated image.
I hope this helps.
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;