How to scale a rotated rectangle to always fit another rectangle - algorithm

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.

Related

Can rectangle be placed inside other rectangle?

I was given width and height of two rectangles and have to determine if the first one has enough space to be inside the second one.
I checked the obvious horizontal and vertical cases, but what about rotation?
Can someone give me a little hint?
You can calculate dimensions of bounding box for rotated rectangle depending on rotation angle as shown here
H = w * Abs(Sin(Fi)) + h * Abs(Cos(Fi))
W = w * Abs(Cos(Fi)) + h * Abs(Sin(Fi))
where w, h are rotated rectangle dimensions and H, W are bounding box dimensions.
There might exist some intervals of angles where H<Height2 and some intervals with W<Width2. If these intervals do intersect, so rotated rectangle fits into the second one.

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

Find the new position of rectangle for resized image

I have a four element position vector [xmin ymin width hight] that specifies the size and position of crop rectangle from image I. How can i find the new position and size for the resized image I?
It is not entirely clear, what you want, as we don't know your coordinate system. Assuming x is the horizontal axis and y is the vertical axis and your point (1,1) is at the top left corner, you can use the following snippet:
p = [xmin ymin width height];
I = I_orig(p(2):p(2)+p(4)-1,p(1):p(1)+p(3)-1);
The size is of course your specified width and height.
You can convert your original bounding box to relative values (that is assuming the image size is 1x1)
[origH origW] = size( origI(:,:,1) );
relativeBB = [xmin / origW, ymin / origH, width / origW, hight / origH];
Now, no matter how you resized your origI, you can recover the bounding box w.r.t the new size from the relative representation:
[currH currW] = size(I(:,:,1));
currBB = relativeBB .* [currW, currH, currW, currH];
You might need to round things a bit: you might find floor better for xmin and ymin and ceil more suitable for width and height.

How to crop rectangle box in image in matlab code

I want to crop a detected faces in my code. Here is my code.
function DisplayDetections(im, dets)
imshow(im);
k = size(dets,1);
hold on;
for i=1:k
rectangle('Position', dets(i,:),'LineWidth',2,'EdgeColor', 'r');
end
imcrop(rectangle);
hold off;
Their is syntax error in cropping.
Can anybody help in cropping rectangle box detected in above box.
That code only draws the rectangles in your image. If you actually want to crop out portions of the image with the defined rectangles, use imcrop.
As such, you would do something like this to store all of your cropped rectangles. This is assuming that im and dets are already defined in your code from your function:
k = size(dets,1);
cropped = cell(1,k);
for i=1:k
cropped{k} = imcrop(im, dets(i,:));
end
cropped would be a cell array where each element will store a cropped image defined by each rectangle within your dets array. This is assuming that dets is a 2D array where there are 4 columns, and the number of rows determines how many rectangles you have. Each row of dets should be structured like:
[xmin ymin width height]
xmin, ymin are the horizontal and vertical co-ordinate of the top-left corner of the rectangle, and width and height are the width and height of the rectangle.
If you want to access a cropped portion in the cell array, simply do:
crp = cropped{k};
k would be the kth rectangle detected in your image.

creating an image in matlab of 9 small white circles in a large black square

Im looking to create an image in Matlab of a large black rectangle with 9 small circles arranged as a a 3x3 array aligned in the centre of the rectangle, i.e. the centre circle will have its midpoint in the centre of the square.
I need the circles evenly spaced apart with some distance between each circle and between the outer circles and the border of the rectangle (think of a square piece of paper with 9 holes placed in it by stabbing it with a pen). I need this so that i can see how image convolution using a 2D gaussian will distort this image.
However I’m relatively new to Matlab and have been trying to create this image. I have successfully made a black/white square and a white circle in a black square which takes up most of the square itself but I cant seem to make a small white circle in any desired location in a black square let alone multiple small circles in a specific alignment.
This is what I have used to create the black square with a large circle:
X = ones([100,1])*([-50:49]);
Y = ([-50:49]')*(ones([1,100]));
Z = (X.^2)+(Y.^2);
image = zeros([100 100]);
image(find(Z<=50^2)) = 1;
imshow(image)
If I understood correctly, try this:
% size of each small box. Final image will be 3Nx3N
N = 100;
% create a circle mask
t = linspace(0,2*pi,50); % approximated by 100 lines
r = (N-10)/2; % circles will be separated by a 10 pixels border
circle = poly2mask(r*cos(t)+N/2+0.5, r*sin(t)+N/2+0.5, N, N);
% replicate to build image
img = repmat(circle, 3,3);
subplot(121), imshow(img)
% after applying Gaussian filter
h = fspecial('gaussian', [15 15], 2.5);
img2 = imfilter(im2double(img), h);
subplot(122), imshow(img2)

Resources