'Cropping' image from a rotatable drawrectangle ROI

19 views (last 30 days)
Hello,
I am currently working on a GUI to perform several morphological operations on images and am having an issue with ROI's from a rotated rectangle of specified dimensions. I found a similar question here and got to where I am using the documentation from the suggested functions.
My goal is taking a series of images of a tube under magnification, taking pictures and rotating it under the camera between each shot, then concatenating segments from each image into a flat map of the surface. However, this tube is not perfectly straight and has somewhat of a curve so I was testing methods on cropping out a diagonal region of an image
The functions 'customWait' and 'clickCallback' are from the mathworks documentation on using a wait funciton with an ROI example here. The relevant code is:
[file,path] = uigetfile({'*.jpg';'*.jpeg';'*.tiff'});
image = imread([path file]);
S = [1 1 2500 120]; %ROI of 2500x1200px placed at coordinate 1 1
imshow(Scomp);
h = drawrectangle(gca,'Position', S, 'Rotatable', true);
position = customWait(h);
I2 = imcrop(Scomp,position);
imshow(I2); % the output image of your ROI
function pos = customWait(hROI)
% Listen for mouse clicks on the ROI
l = addlistener(hROI,'ROIClicked',@clickCallback);
% Block program execution
uiwait;
% Remove listener
delete(l);
% Return the current position
pos = hROI.Position;
end
function clickCallback(~,evt)
if strcmp(evt.SelectionType,'double')
uiresume;
end
end
ROI selection:
Capture.JPG
Result:
Capture.JPG
The method works perfectly when the ROI is perfectly horizontal or vertical. Whenever the rectangle is rotated however, it crops a horizontal segment from the centerline of the rectangle ignoring the rotated position. I imagine this is due to that in rotatted orientations, the diagonal edges cannot be recorded properly in a square or rectangular matrix.
I looked into ROI poly, but could not find how to specify the dimensions of the polygon or how to make it interactable.
I have considered just rotating the images so that the crop fits as best as possible, but since I am working with large image sequences (100+ images for about a dozen subjects) of a subject irregularly occurring bends and curves in it. Finding each image's necessary rotation angle individually would be a very time consuming task to perform image by image. The original idea was to use rotated rectangular crop and the batch image processing app to just cycle through the images and rotate the rectangle as needed.
Is there a way to achieve what I'm looking for, cropping and angled rectangle or region? Or perhaps a method better suited given my application? I am open to revising my methods if a better alternative exists.

Answers (3)

Sid Singh
Sid Singh on 24 Oct 2019
Hi, the method that you are using is only meant for drawing a rectangle and it is not intended for extraction purposes. Images are stored as a 2D matrix internally and indexing/subset extraction is much more efficient if it is a rectangular area.
You can try rotating the image itself with bilinear or bicubic interpolation and then extract rectangular regions from it.
  1 Comment
Jorge Cossio
Jorge Cossio on 28 Oct 2019
Hi Sid,
As I mentioned in the question itself:
"I have considered just rotating the images so that the crop fits as best as possible, but since I am working with large image sequences (100+ images for about a dozen subjects) of a subject with irregularly occurring bends and curves. Finding each image's necessary rotation angle individually would be a very time consuming task to perform image by image."
I am aware rotating the image was an option, but wanted to see if there is an alternative method to achieve this with a "non-horizontal" ROI.

Sign in to comment.


Image Analyst
Image Analyst on 28 Oct 2019
I'm not sure what your ROI is selecting. It does not look like it's enclosing a tube.
You should be able to get the angle to rotate it by if you have the coordinates of the corners of the rectangles.
Do the boxes NEED to be horizontal? Why can't you just mask the image and leave it tilted?

cui,xingxing
cui,xingxing on 5 Mar 2022
I've written an enhanced 'imcrop' function that supports rotated rectangle interception, which would satisfy your case
function croppedImg = imgCrop(srcImg,rect)
% 功能:build-in中的imcrop增强型函数,额外支持旋转矩形截图
% 输入:
% srcImg: source image
% rect: 1*4 double,形如[x,y,width,height]代表垂直坐标轴的矩形或者
% 1*5 double 形如[x,y,width,height,yaw] 代表旋转矩形,yaw为弧度,绕x轴逆时针为正
% 输出:
% croppedImg: m*n 与srcImg同类型的截取图像
%
% Email: cuixingxing150@gmail.com
% 2022.3.5 create this file
% Impleametation in Matlab 2021a
%
arguments
srcImg
rect (1,:) double
end
if length(rect)==4 % vertical rectangle
croppedImg = imcrop(srcImg,rect);
elseif length(rect)==5 % rotate rectangle
x = rect(1);
y = rect(2);
width = rect(3);
height = rect(4);
theta = -rect(5);
% transform, or use the comment section to get 'tform'
% rect = [rect(1:4),rect(5)*180/pi];
% vertices = getVertices(rect);
% matchedPoints1 = vertices;
% matchedPoints2 = [1,height;
% 1,1;
% width,1;
% width,height];
% transformType = 'rigid';
% tform = estimateGeometricTransform2D(matchedPoints1,matchedPoints2,transformType);% or use fitgeotrans
rot = [cos(theta),sin(theta);
-sin(theta),cos(theta)];
trans = [width,height]/2-[x,y]*rot;
tform = rigid2d(rot,trans);
outputView = imref2d([height,width]);
croppedImg = imwarp(srcImg,tform,'OutputView',outputView);
else
croppedImg = [];
end

Categories

Find more on Images in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!