MATLAB求二值图像的最小外接矩形

算法描述

计算最小外接矩形(MER)的一种方法是,将物体的边界以每次以一定的角度增量(例如3°)在90°范围内旋转。每旋转一次记录一次其坐标系方向上的外接矩形边界点的最大和最小x、y值。旋转到某一个角度后,外接矩形的面积(或周长)达到最小。取面积最小的外接矩形的参数为主轴意义下的长度和宽度。
旋转物体使外接矩形最小

步骤流程

  1. 输入图像
    源图像

  2. 输出图像
    旋转角度从0°~90°,步长为10°,求得的MER,如下图;
    步长为10°
    旋转角度从0°~90°,步长为1°,求得的MER,如下图。
    步长为1°

源代码

%%%寻找图像最小外接矩形

%%%先用迭代式阈值求法将图像变为二值图
img = imread('test0.png');
img = rgb2gray(img);
Th = mean(img( : ));            %将灰度均值设为初始阈值
newTh = 0;
i = 1;
while (Th - newTh) > 1
    pic1 = img;
    pic1(pic1 > Th) = 0;            %大于阈值置零方便求均值
    miu1 = mean(pic1(:));        %小于阈值的像素的灰度均值
    pic2 = img;
    pic2(pic2 < Th) = 0;            %小于阈值置零方便求均值 
    miu2 = mean(pic2( : ));      %大于阈值的像素的灰度均值
    if i ~= 1
        Th = newTh; 
    end
    i = i + 1;
    newTh = (miu1 + miu2) / 2;
end
imgTh = img;
imgTh(imgTh < Th) = 1;
imgTh(imgTh > Th) = 256;
imgTh = 256 - imgTh;
%%%先用迭代式阈值求法将图像变为二值图
%%%旋转图像求其MER
for angle = 0 : 1 : 90
    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);
%%%重现

subplot(2,1,1);
imshow(uint8(imgTh));
title('原图像');

out1 = imrotate(imgTh,typicalAngle,'bicubic','loose');
rectx = [xMin, xMax, xMax, xMin, xMin];
recty = [yMax, yMax, yMin, yMin, yMax];
subplot(2,1,2);
imshow(out1);
title(['旋转角度为',num2str(typicalAngle),'°']);
line(rectx(:),recty(:),'color','r');

% out2 = imrotate(Figure1,-typicalAngle,'bicubic','loose');
% imshow(out2);
% rectx = [XLU, XLD, XRD, XRU, XLU];
% recty = [YLU, YLD, YRD, YRU, YLU];
% imshow(uint8(imgTh));
% line(rectx(:),recty(:),'color','r');
%%%旋转图像求其MER

结论

从输入输出图像中可以看到,通过旋转图像法求最小外接矩形,实验效果较好。通过改变旋转角度的步长可以使MER的计算变得更为精确,但也会使得程序运行时间增加。此外通过这一方法求MER,阈值分割的准确性也很重要,本次实验中选区的图像背景较为简洁,因此阈值分割效果也比较好。但在实际应用中,背景通常没有这么间接,因此在进行阈值分割时应当进行形态学的腐蚀与膨胀,以确保阈值分割的效果。一旦阈值分割出现一点点小瑕疵,整个程序都会出问题。

原始图像在旋转55°之后的坐标系内,有主轴意义下的MER。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一入机械深似海

小手一抖

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值