Matlab: apply projection correction to an image subset - matlab

Following the question I posted here, I need to apply a projective transformation to an image given 4 points.
Say I successfully segmented the QR code from an image:
and I have stored in an array of points the coordinates of the QR vertices. In this case I would only need a rotation in order oto obtain the rectified image but in here:
I need to apply a projective correction to the image.
Is there a way of making these transformations knowing the coordinates of the said vertices?
EDIT
I solved it using #Xiang's suggestion and using HSV components of the image.

If I understand the question correctly you have the 4 corner points and you want to know to which coordinates to map them in the transformed image. Well, this is up to you. You know this is a square so just choose an arbitrary height or calculate based on some measurement from the original image and generate the coordinates:
(0,0)
(0, size)
(size, 0)
(size, size)
Now you can compute the transform and apply it to the original image using maketform.
From Matlab docs http://www.mathworks.com/help/images/ref/maketform.html:
T = maketform('projective',U,X)
To apply the transform use imtransform and set the fields UData, VData, XData, YData to specify your source coordinate system and the new sampling coordinates you wish to transform to.

Related

Crop an image using multiple coordinates in Matlab

I used the "imfreehand" to crop an irregular shape and save its positions into a variable. This position variable is a 85*2 double matrix (85 points, X and Y coordinates). Now, I want to use the same position to crop another image (different layer of the image, but the location of the objects is the same). The functions I can find all requires rectangle positions (X1,X2,Y1,Y2). In my situation, I have 82 different (X,Y) coordinates, how can I use the position information to crop a new image?
From what I understand, you want to take the coordinates created by imfreehand(...) to create a cropable object on another image. You can use the function impoly(hparent,position) for this purpose.
The MathWorks page provides an example to guide you on its usage.

Projective Transformation: Find New Pixel Location MATLAB

I am transforming my images using a protective transformation matrix. I get my transformation by doing the following, where a are 4 fixed points, and b are 4 moving points.
my_tform = fitgeotrans(a,b,'projective');
I then transform my images using imwarp and my transformation matrix my_tform as follows:
newImage = imwarp(Im,my_tform,'cubic','OutputView', imref2d( size(Im) ));
This works really well. The problem I have is that I want to know the new pixel location given a pixel location before the transformation. I need some fast code, since I would be doing this for each pixel in the image.
Basically, given a location such as (256,256) in the original image, what is the new location in the transformed image?
Please see the following example image below. On the right is the original image, and on the left is the transformed image. The data tip is the same pixel in both images, but at different locations. I want to know how I can go between the two.

How can I rotate connected components so that they are upright in Matlab?

Currently I am working with a sudoku grid and I have the binary image. I am using Regionprops to get the area of the connected components and then turn the rest of the image black. After this I call the OCR method to try and read the sudoku numbers. The problem is that this only works if the sudoku grid in the image is straight and upright. If it is rotated even a little bit I am not able to pull the numbers. This is the code I have so far:
% get grid connected parts
conn_part = bwconncomp(im_binary);
% blacken area outside
stats = regionprops(conn_part,'Area');
im_out = im_binary; % Make mask
im_out(vertcat(conn_part.PixelIdxList{[stats.Area] < 825 | [stats.Area] > 2500})) = 0;
imagesc(im_out);
title("Numbers pulled");
sudokuNum = ocr(im_out,'TextLayout','Block','CharacterSet','0123456789');
sudokuNum.Text;
Where im_binary is the binary image
im_out is the output image
stats is the object returned from regionprops containing the area of the connected components
I know I can rotate the image before getting the OCR results by doing:
im_out = imrotate(im_out, angle)
However I don't know what angle the grid is at since this is part of a function that loops through for multiple images. I looked into the regionprops method because there is an attribute 'Orientation' which I can pull from there but I don't understand how I would actually use it. It also states that regionprops will return a value between -90 and 90, but my image could be rotated by more than 90 degrees.
Don't rotate the connected component or the binary image. First use the binary image to determine the rotation, then rotate the original grey-scale or color input image, and then binarize the rotated image. You'll be able to transform with interpolation, which will improve your results greatly. It does require to do the binarization step twice, but I don't think this step usually is too expensive.
The regionprops orientation feature is computed by "fitting" an ellipse to the shape. This is meaningful only for elongated objects. For a square sudoku grid this will not yield any valuable information.
Instead, look at the angle at which the smallest Feret diameter was obtained. The Feret diameters are the lengths of the projections at arbitrary angles. At one angle, this projection is smallest. By necessity it will be at an angle corresponding to one of the principal axes of the square. Here is more information about how to compute Feret diameters in MATLAB.
A different alternative is e.g. to use the Hough transform to detect the lines of the grid.
Do note that the geometry of the puzzle will never tell you about which side is up. The angle you get here should be taken modulo π/2 (i.e. constrain to the range -π/4 to π/4).
To know what direction is up you might do by trying to read the text, if it fails, rotate by 90 degrees and try again.

transformed image should always visible

I am trying to transform an image using Bi-linear interpolation, my input image is I, I have my affine matrix [A], which will give me transformed image I', according to bi-linear interpolation I am taking inverse of affine matrix inv([A]) and applying that to every point of output image(which is all zero at initial level), as we cant guarantee that output image size can be of any size, so first I found the bounds so I can get the size of the output image,
Now I have input image, Affine matrix, and output image which have atleast that size in which transformed image can be saved easily, But If I apply backward backward method of warping, according to that I have to iterate through every pixel of output image(which is zero right now), I want my transformed image at the center so my transformed image should always be visible, any idea how can I do that ?
Note I don't want to use matlab's built in function.
EDIT
If I transformed my A Image I got B, but You see corner of the image got cropped, I want those to be shown as well.
When rotating a rectangle from the upright position to a diagonal one, the vertical distance between the highest and lowest point will increase.
Now there are two approaches you can take:
Put the new picture in a bigger environment
OR
Rescale the rotated picture to make it fit in the original sized environment.

matlab: how do create a projection

I want to create a perspective projection of a 3D image onto the x,y plane with a focal length of 10 and a principal point (-1, -5).
I found:
view
viewmtx
But I do not get how to tell matlab that I want to use the x,y plane nor how to set the focal length? Can someone explain me how to do that?
I'm afraid you are not looking for the right functions.
The view function does only change the point of view on the current axis, while viewmtxreturn a transformation matrix.
You may want to do something similar to what it is discussed on this post How do I draw a texture-mapped triangle in MATLAB?, where maketform and imtransform are the key functions to get a plane image reprojected into another certain 3d plane.