transformed image should always visible - matlab

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.

Related

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.

Problems in implementing the integral image in MATLAB

I tried to implement the integral image in MATLAB by the following:
im = imread('image.jpg');
ii_im = cumsum(cumsum(double(im)')');
im is the original image and ii_im is the integral image.
The problem here is the value in ii_im flows out of the 0 to 255 range.
When using imshow(ii_im), I always get a very bright image which I am not sure is the correct result. Am I correct here?
You're implementing the integral image calculations right, but I don't understand why you would want to visualize it - especially since the sums will go beyond any normal integer range. This is expected as you are performing a summation of intensities bounded by larger and larger rectangular neighbourhoods as you move to the bottom right of the image. It is inevitable that you will get large numbers towards the bottom right. Also, you will obviously get a white image when trying to show this image because most of the values will go beyond 255, which is visualized as white.
If I can add something, one small optimization I have is to get rid of the transposing and use cumsum to specify the dimension you want to work on. Specifically, you can do this:
ii_im = cumsum(cumsum(double(im), 1), 2);
It doesn't matter what direction you specify first (2 then 1, or 1 then 2). The summation of all pixels within each bounded area, as long as you specify all directions to operate on, should be the same.
Back to your question for display, if you really, really, really really... I mean really want to, you can normalize the contrast by doing:
imshow(ii_im, []);
However, what you should expect is a gradient image which starts to be dark from the top, then becomes brighter when you get to the bottom right of the image. Remember, each point in the integral image calculates the total summation of pixel intensities bounded by the top left corner of the image to this point, thus forming a rectangle of intensities you need to sum over. Therefore, as we move further down and to the right of the integral image, the total summation should increase.
With the cameraman.tif image, this is the original image, as well as it's integral image visualized using the above command:
Either way, there is absolutely no reason why you would want to visualize it. You would use this directly with whatever application requires it (adaptive thresholding, Viola-Jones detector, etc.)
Another option could be applying a log operation for each value in the integral image. Something like:
imshow(log(1 + ii_im), []);
However, this will make most of the pixels have the same contrast and this is probably not useful. This is what I get with cameraman.tif:
The moral of this story is that you need some sort of contrast normalization so that you can fit all of the values in your integral image within the confines of the data type that is used to display the image on the screen using imshow.

Matlab: apply projection correction to an image subset

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.

Derive a rotational/transformational matrix given an image and a rotated image in Java?

Need some advise and point me in the right direction.
My object detection system reads in this image(see below) and returns coordinates for bounding boxes for some detection results(in this case, a hammer)
http://i1116.photobucket.com/albums/k572/Ruihong_Zhou/z3IJx-1.png
However I wish to examine the accuracy of the detection results for the same image by feeding the system, rotated images of the original images and allow it to detect and return coordinates for detection results if any.
For example:
http://i1116.photobucket.com/albums/k572/Ruihong_Zhou/myJQA-1.jpg
Let's say the coordinates of the yellow point(in the image above) is found but it is with respect to the rotated frame of reference. How do i actually transform/rotate these coordinates and find out where do they actually lie in the original image with respect to the original frame of reference.
Someone has pointed out to me that I should use affine transformation but I'm not sure how to go about it as honestly this is the 1st time i have heard of affine transformation and i'm still trying to brute force my learning of it now.
Further research indicates that I need both the original set of coordinates in the original image and the same set of coordinates in the rotated image to come up with a transformation matrice but I only have the detected set of coordinates in the rotated image.

How Do I Find The Bounding Box For All Regions?

I'm using the MNIST digit images for a machine learning experiment, and I'm trying to center each image based on position, rather than the center of mass that they are centered on by default.
I'm using the regionprops class, BoundingBox method to extract the images. I create a B&W copy of the greyscale, use this to determine the BoundingBox properties (regionprops works only B&W images) and then apply that on the greyscale original to extract the precise image rectangle. This works fine on ~98% of the images.
The problem I have is that the other ~2% of images has some kind of noise or errant pixel in the upper left corner, and I end up extracting only that pixel, with the rest of the image discarded.
How can I incorporate all elements of the image into a single rectangle?
EDIT: Further research has made me realise that I can summarise and rephrase this question as "How do I find the bounding box for all regions?". I've tried adjusting a label matrix so that all regions are the same label, to no avail.
You can use an erosion mask with the same size of that noise to make it totally disappear " using imerode followed by imdilate to inverse erosion ", or you can use median filter