实现二值图像最小外接矩形(正)
用于目标识别 散点图画框
% 原文链接:https://blog.csdn.net/rosfreshman/article/details/116380981
原文效果如下
main.m 旋转角度固定为0° 可以得到平行于坐标轴的矩形
%% 寻找图像最小外接矩形 白色画框
% 先将图像变为二值图
% 计算最小外接矩形(MER)的一种方法是,将物体的边界以每次以一定的角度增量(例如3°)在90°范围内旋转。
% 每旋转一次记录一次其坐标系方向上的外接矩形边界点的最大和最小x、y值。
% 旋转到某一个角度后,外接矩形的面积(或周长)达到最小。取面积最小的外接矩形的参数为主轴意义下的长度和宽度。
clc;clear;close all;
%% 读取rgb原图
%img = imread('2.png');
%img = rgb2gray(img); %灰度化
%thresh = graythresh(img ); %自动阈值
%img = im2bw(img ,thresh ); %对图像二值化
%或者直接读取二值图像
img = imread('2.png');
img =imcomplement(img);%二值图像反相
imgTh = im2uint8(img);
figure(1);
subplot(1,2,1);
imshow(img);title('原图像');
%%%旋转图像求其MER
% for angle = 0 : 1 : 90
for angle = 0
imgRotated = double(imrotate(imgTh,angle,'bicubic','loose')); %求旋转后的图像
%imshow(uint8(imgRotated));
[row, col] = size(imgRotated);
%%%判断最小外接矩形的边界
for i = 1 : row
if sum(imgRotated(i, :)) > col
break;
end
end
yMinTest = i;
for i = row : -1 : 1
if sum(imgRotated(i, :)) > col
break;
end
end
yMaxTest = i;
for i = 1 : col
if sum(imgRotated(:, i)) > row
break;
end
end
xMinTest = i;
for i = col : -1 : 1
if sum(imgRotated(:, i)) > row
break;
end
end
xMaxTest = i;
%%%判断最小外接矩形的边界
%%%计算面积
XLU = xMinTest * cosd(angle) - yMinTest * sind(angle);
YLU = xMinTest * sind(angle) + yMinTest * cosd(angle);
XLD = xMinTest * cosd(angle) - yMaxTest * sind(angle);
YLD = xMinTest * sind(angle) + yMaxTest * cosd(angle);
XRU = xMaxTest * cosd(angle) - yMinTest * sind(angle);
YRU = xMaxTest * sind(angle) + yMinTest * cosd(angle);
XRD = xMaxTest * cosd(angle) - yMaxTest * sind(angle);
YRD = xMaxTest * sind(angle) + yMaxTest * cosd(angle);
l1 = sqrt((XLU - XRU) ^ 2 + (YLU - YRU) ^ 2);
l2 = sqrt((XLU - XLD) ^ 2 + (YLU - YLD) ^ 2);
nowSize = l1 * l2;
%%%保存当前求得的MER
if angle == 0 || nowSize < typicalSize
xMin = xMinTest;
yMin = yMinTest;
xMax = xMaxTest;
yMax = yMaxTest;
typicalSize = nowSize;
typicalAngle = angle;
typicalImg = imgRotated;
end
%%%保存当前求得的MER
lastSize = nowSize;
end
%%%重现
XLU = xMin * cosd(typicalAngle) - yMin * sind(typicalAngle);
YLU = xMin * sind(typicalAngle) + yMin * cosd(typicalAngle);
XLD = xMin * cosd(typicalAngle) - yMax * sind(typicalAngle);
YLD = xMin * sind(typicalAngle) + yMax * cosd(typicalAngle);
XRU = xMax * cosd(typicalAngle) - yMin * sind(typicalAngle);
YRU = xMax * sind(typicalAngle) + yMin * cosd(typicalAngle);
XRD = xMax * cosd(typicalAngle) - yMax * sind(typicalAngle);
YRD = xMax * sind(typicalAngle) + yMax * cosd(typicalAngle);
%%%重现
out1 = imrotate(imgTh,typicalAngle,'bicubic','loose');
rectx = [xMin; xMax; xMax; xMin; xMin];
recty = [yMin; yMin; yMax; yMax; yMin];
subplot(1,2,2);
imshow(out1);
% title(['旋转角度为',num2str(typicalAngle),'°']);
title(['最小外接矩形(正)']);
line(rectx(:),recty(:),'color','r');
[wei, hei] = minboxing(rectx(1:end-1),recty(1:end-1)) %显示外接矩形长和宽
代码只是能用,后面可能会再进一步改写。