Maintain same imrect position at different resolution - image

I'm using the function imrect, to crop the ROI in image for further processing. I have two images to compare (imagine they are the same but with different resolution):
Image 1: 1024x1024 pixels and Image 2: 2000x2000 pixels. The pixel value is known, so I don't want to resize images. At first I select the ROI in the image 1, using the draggable rectangle:
imshow(image1);
h=imrect(gca,[10 10 200 200]); position=wait(h);
I=imcrop(image1,position);
Then I open image2 which is the same image at different resolution. Now I need to calculate the position of imrect so it would cover the same ROI. The position of ROI in this image is different because of different resolution. So the position of the imrect should be different as well.
For image2 I want to run a code like this, but I don't know how to estimate the position variable:
imshow(image2);
I2=imcrop(image2,unknown_position);
How can I estimate the position in image2?

Maths to the rescue!
x_2 = x_1 * width_2 / width_1
y_2 = y_1 * height_2 / height_1

Related

Retrieve corner coordinates of image given resolution and center point

I'm going through an image dataset which has image pixel coordinate and the resolution of the image. Is there any way to map that information to corner coordinates of the image.
For instance if the image pixel coordinates are -403059.626, -12869811.372 and image is 4168 x 3632 pixels, Is it possible to extract the real world coordinates of the four corners of each image in the rectangle? We can assume the size of the pixel as 1 unit
Assuming p = (-403059.626, -12869811.372) is the pixel in the middle of the image, and an image of size s = (4168, 3632) pixels, and a pixel size of 1 (meaning pixels are in the same units as the location given by p), then the coordinates of the top-left corner can be computed as follows:
q = p - s/2 = ( -403059.626 - 4168/2 , -12869811.372 - 3632/2 )
The s/2 value above can be computed differently depending on what you consider the pixel in the middle of the image. Here I assume the top-left pixel has index (0,0), and the pixel in the middle has index (4168/2,3632/2).
The above assumes no rotation (i.e. the image axes are aligned with the coordinate system), and no distortion (it is possible that the camera adds distortion to the image, causing the pixel pitch to change in different parts of the image).
The bottom-right corner then has coordinates:
r = q + s-1 = p + s/2 - 1

How can I save/show the croped image and uncroped image in MATLAB

I am having issue with cropping of image. My task includes an image. I have to crop the image at x,y coordinates, which I have tried and got success.
Now I want to show/save both images, the cropped one and also the image which is being cropped (which will have a subtracted area of cropped part just like subtracting the small cavity from the image).
My Code:
B = imread('B1.jpg');
% figure,imshow(B)
GimageB = rgb2gray(B);
% figure, imshow(GimageB)
J = imcrop(B,[284 235 95 80]);
figure, imshow(J)
To show the image without the "extracted" area, fill that area with zero!
img=rgb2gray(imread('http://weknowyourdreams.com/images/cat/cat-03.jpg'));
img2 = imcrop(img,[500 600 700 800]);
img3=img;
% fill area with zero (note the numbers, compare to imcrop)
img3(500:500+700, 600:600+800)=0;
figure()
imshow(img3)

How to scale a rotated rectangle to always fit another rectangle

the background of my question is the following.
I have a picture and a crop rectangle which describes how the picture should be cropped to produce the resulting picture. The crop rectangle is always smaller or at maximum the size of the picture.
Now it should be possible to rotate the crop rectangle.
This means that when rotating the crop regtanle inside the picture, the crop must be scaled in order that its extends does not exceed the photo.
Can anybode help me with a formula of how to compute the scale of the crop rectanlge based on the axis aligned photo regtancle?
My first attempt was to compute a axis aligned bounding box of the crop rectanlge and than make this fit it the photo rectangle. But somehow i get stuck with this approach,
Edited:
One more think to note:
- The crop rectangle can have other dimension and another center point inside the surrounding rectangle. This means the crop rectangle can be much smaller but for example is located at the lower left bound of the picture rectangle. So when rotating the smaller crop it will also exceed its limits
Thanks in advance
Sebastian
When you rotate an axis-aligned rectangle of width w and height h by an angle φ, the width and height of the rotated rectangle's axis-aligned bounding box are:
W = w·|cos φ| + h·|sin φ|
H = w·|sin φ| + h·|cos φ|
(The notation |x| denotes an absolute value.) This is the bounding box of the rotated crop rectangle which you can scale to fit the original rectangle of width wo and height ho with the factor
a = min(wo / W, ho / H)
if a is less than 1, the rotated crop rectangle fits inside the original rectangle and you don't have to scale. Otherwise, reduce the crop rectangle to the scaled dimensions
W′ = a·W
H′ = a·H
You could start checking if the dimension of the cropped rectangle fit in the old rectangle:
bound_x = a * cos(theta) + b * sin(theta)
bound_y = b * cos(theta) + a * sin(theta)
Where a and b are the new dimensions, theta us the angle and bound_x and bound_y should be smaller of the original rectangle.

How can I "plot" an image on top of another image with a different colormap?

I've got two images, one 100x100 that I want to plot in grayscale and one 20x20 that I want to plot using another colormap. The latter should be superimposed on the former.
This is my current attempt:
A = randn(100);
B = ones(20);
imagesc(A);
colormap(gray);
hold on;
imagesc(B);
colormap(jet);
There are a couple of problems with this:
I can't change the offset of the smaller image. (They always share the upper-left pixel.)
They have the same colormap. (The second colormap changes the color of all pixels.)
The pixel values are normalised over the composite image, so that the first image changes if the second image introduces new extreme values. The scalings for the two images should be separate.
How can I fix this?
I want an effect similar to this, except that my coloured overlay is rectangular and not wibbly:
Just change it so that you pass in a full and proper color matrix for A (i.e. 100x100x3 matrix), rather than letting it decide:
A = rand(100); % Using rand not randn because image doesn't like numbers > 1
A = repmat(A, [1, 1, 3]);
B = rand(20); % Changed to rand to illustrate effect of colormap
imagesc(A);
hold on;
Bimg = imagesc(B);
colormap jet;
To set the position of B's image within its parent axes, you can use its XData and YData properties, which are both set to [1 20] when this code has completed. The first number specifies the coordinate of the leftmost/uppermost point in the image, and the second number the coordinate of the rightmost/lowest point in the image. It will stretch the image if it doesn't match the original size.
Example:
xpos = get(Bimg, 'XData');
xpos = xpos + 20; % shift right a bit
set(Bimg, 'XData', xpos);

How to lock image dimensions in MATLAB

So I have this matrix in MATLAB, 200 deep x 600 wide. It represents an image that is 2cm deep x 6cm wide. How can I plot this image so that it is locked into proper dimensions, i.e. 2cm x 6cm? If I use the image or imagesc commands it stretches it all out of shape and shows it the wrong size. Is there a way to lock it into showing an image where the x and y axes are proportional?
Second question, I need to then set this image into a 640x480 frame (20 pixel black margin on left and right, 280 pixel black margin on bottom). Is there a way to do this?
To keep aspect ratio, you can use axis equal or axis image commands.
Quoting the documentation:
axis equal sets the aspect ratio so that the data units are the same in every direction. The aspect ratio of the x-, y-, and z-axis is adjusted automatically according to the range of data units in the x, y, and z directions.
axis image is the same as axis equal except that the plot box fits tightly around the data`
For second question:
third_dimension_size=1; %# for b&w images, use 3 for rgb
framed_image=squeeze(zeros(640,480,third_dimension_size));
framed_image(20:20+600-1,140:140+200-1)= my_600_200_image;
imagesc(framed_image'); axis image;
set(gca,'DataAspectRatio',[1 1 1])
Second question:
new_image = zeros(480,640);
new_image(20:(200+20-1),20:(600+20-1)) = old_image;
As an alternative to the other answers, you might want:
set(gca, 'Units', 'centimeters', 'Position', [1 1 6 2])
Make sure you do this after plotting the image to get the other axis properties correct.
For the second question, take care with the number of colour channels:
new_image = zeros(480,640, size(old_image));
new_image(20:(200+20-1),20:(600+20-1),:) = old_image;

Resources