Matlab图像旋转错误排查及旋转裁剪图分窗口显示实现
Hey there! Let's work through your two MATLAB image processing questions step by step, using your code as a starting point.
Your current code uses imshow(uprightImage); hold on, which overwrites the same window with each new image. To get a separate window for every rotated pill, just add a figure() call before imshow—you can even name each window to keep track of which pill is which:
Replace the imshow(uprightImage); hold on line in your loop with:
figure('Name', sprintf('Upright Pill %d', k)); imshow(uprightImage);
This creates a new, named figure window for each object, so you can view all rotated crops side by side without overlapping.
The root cause here is a mismatch between how regionprops defines the Orientation angle and how imrotate interprets rotation angles:
regionprops.Orientation: This value ranges from-90°to0°, representing the angle between the x-axis (rightward) and the object's major axis. A0°value means the pill is horizontal (pointing right), while-90°means it's vertical (pointing down).imrotateangle rule: Positive angles rotate images clockwise, negative angles rotate them counterclockwise.
Your original code uses uprightImage = imrotate(croppedImage, angle);, which applies the raw Orientation value directly. For example, a vertical pill with -90° orientation would get rotated counterclockwise 90°—resulting in a horizontal pill pointing left, not the upright right-facing result you want.
Fix 1: Correct the Rotation Direction
Invert the angle to get the right rotation direction:
uprightImage = imrotate(croppedImage, -angle);
Fix 2: Handle Circular Pills
For nearly circular pills (like some in pillsetc.png), Orientation is arbitrary (since circles have no distinct major axis), leading to random-looking rotations. You can skip rotating these by checking the Circularity property (values close to 1 mean the object is circular):
Update your regionprops call to include Circularity, then add a conditional check:
measurements = regionprops(thisObject, 'Orientation', 'BoundingBox', 'Circularity'); if measurements.Circularity < 0.9 angle = measurements.Orientation; uprightImage = imrotate(croppedImage, -angle); else uprightImage = croppedImage; % Keep circular pills as-is end
Full Corrected Code
Here's the complete code with both fixes applied:
clear; clc; RGB = imread('pillsetc.png'); I = rgb2gray(RGB); bw = imbinarize(I); bw = bwareaopen(bw,30); bw = imfill(bw,'holes'); imshow(bw) [B,L] = bwboundaries(bw,'noholes'); imshow(bw) [labeledImage, numBlobs] = bwlabel(bw); for k = 1 : numBlobs thisObject = ismember(labeledImage, k); measurements = regionprops(thisObject, 'Orientation', 'BoundingBox', 'Circularity'); croppedImage = imcrop(RGB, measurements.BoundingBox); % Apply rotation only to non-circular objects if measurements.Circularity < 0.9 angle = measurements.Orientation; uprightImage = imrotate(croppedImage, -angle); else uprightImage = croppedImage; end % Show each result in a separate window figure('Name', sprintf('Upright Pill %d', k)); imshow(uprightImage); end
内容的提问来源于stack exchange,提问作者jane

