'Cropping' image from a rotatable drawrectangle ROI
19 次查看(过去 30 天)
显示 更早的评论
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:
Result:
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.
0 个评论
回答(3 个)
Sid Singh
2019-10-24
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.
Image Analyst
2019-10-28
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?
0 个评论
cui,xingxing
2022-3-5
编辑:cui,xingxing
2024-4-27
I've written an enhanced 'imcrop' function that supports rotated rectangle interception, which would satisfy your case
please see here in details
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
-------------------------Off-topic interlude, 2024-------------------------------
I am currently looking for a job in the field of CV algorithm development, based in Shenzhen, Guangdong, China,or a remote support position. I would be very grateful if anyone is willing to offer me a job or make a recommendation. My preliminary resume can be found at: https://cuixing158.github.io/about/ . Thank you!
Email: cuixingxing150@gmail.com
0 个评论
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!