matlab的minboundrect.m 函数

本来目的是想将每个连通区域用一个斜的box框起来,可是函数貌似针对整幅图片的。
正在改进
minboundrect.m 函数

function [rectx,recty,area,perimeter] = minboundrect(x,y,metric)
% minboundrect: Compute the minimal bounding rectangle of points in the plane
% usage: [rectx,recty,area,perimeter] = minboundrect(x,y,metric)
%
% arguments: (input)
%  x,y - vectors of points, describing points in the plane as
%        (x,y) pairs. x and y must be the same lengths.
%
%  metric - (OPTIONAL) - single letter character flag which
%        denotes the use of minimal area or perimeter as the
%        metric to be minimized. metric may be either 'a' or 'p',
%        capitalization is ignored. Any other contraction of 'area'
%        or 'perimeter' is also accepted.
%
%        DEFAULT: 'a'    ('area')
%
% arguments: (output)
%  rectx,recty - 5x1 vectors of points that define the minimal
%        bounding rectangle.
%
%  area - (scalar) area of the minimal rect itself.
%
%  perimeter - (scalar) perimeter of the minimal rect as found
%
%
% Note: For those individuals who would prefer the rect with minimum
% perimeter or area, careful testing convinces me that the minimum area
% rect was generally also the minimum perimeter rect on most problems
% (with one class of exceptions). This same testing appeared to verify my
% assumption that the minimum area rect must always contain at least
% one edge of the convex hull. The exception I refer to above is for
% problems when the convex hull is composed of only a few points,
% most likely exactly 3. Here one may see differences between the
% two metrics. My thanks to Roger Stafford for pointing out this
% class of counter-examples.
%
% Thanks are also due to Roger for pointing out a proof that the
% bounding rect must always contain an edge of the convex hull, in
% both the minimal perimeter and area cases.
%
%
% See also: minboundcircle, minboundtri, minboundsphere
%
%
% default for metric
if (nargin<3) || isempty(metric)
  metric = 'a';
elseif ~ischar(metric)
  error 'metric must be a character flag if it is supplied.'
else
  % check for 'a' or 'p'
  metric = lower(metric(:)');                    
  ind = strmatch(metric,{'area','perimeter'});             
  if isempty(ind)                
    error 'metric does not match either ''area'' or ''perimeter'''
  end

  % just keep the first letter.
  metric = metric(1);
end

% preprocess data
x=x(:);
y=y(:);

% not many error checks to worry about
n = length(x);                                    
if n~=length(y)                               
  error 'x and y must be the same sizes'
end



% if var(x)==0

% start out with the convex hull of the points to
% reduce the problem dramatically. Note that any
% points in the interior of the convex hull are
% never needed, so we drop them.
if n>3 

    %%%%%%%%%%%%%%%%%%%%%%%%%
    if (var(x)== 0|| var(y)==0)
        if var(x)== 0
            x = [x-1;x(1); x+1 ];
            y = [y ;y(1);y];
            flag = 1;
        else
            y = [y-1;y(1); y+1 ];
            x = [x ;x(1);x];
            flag = 1;
        end

    else
        flag = 0;
     %%%%%%%%%%%%%%%%%%%%%%
    edges = convhull(x,y);  % 'Pp' will silence the warnings

    end

  % exclude those points inside the hull as not relevant
  % also sorts the points into their convex hull as a
  % closed polygon

  %%%%%%%%%%%%%%%%%%%%
  if flag == 0 
  %%%%%%%%%%%%%%%%%%%%    

  x = x(edges);
  y = y(edges);
  %%%%%%%%%%%%%%%%%%
  end
  %%%%%%%%%%%%%
  % probably fewer points now, unless the points are fully convex
  nedges = length(x) - 1;                       
elseif n>1
  % n must be 2 or 3
  nedges = n;
  x(end+1) = x(1);
  y(end+1) = y(1);
else
  % n must be 0 or 1
  nedges = n;
end

% now we must find the bounding rectangle of those
% that remain.

% special case small numbers of points. If we trip any
% of these cases, then we are done, so return.
switch nedges
  case 0
    % empty begets empty
    rectx = [];
    recty = [];
    area = [];
    perimeter = [];
    return
  case 1
    % with one point, the rect is simple.
    rectx = repmat(x,1,5);
    recty = repmat(y,1,5);
    area = 0;
    perimeter = 0;
    return
  case 2
    % only two points. also simple.
    rectx = x([1 2 2 1 1]);
    recty = y([1 2 2 1 1]);
    area = 0;
    perimeter = 2*sqrt(diff(x).^2 + diff(y).^2);
    return
end
% 3 or more points.

% will need a 2x2 rotation matrix through an angle theta
Rmat = @(theta) [cos(theta) sin(theta);-sin(theta) cos(theta)];

% get the angle of each edge of the hull polygon.
ind = 1:(length(x)-1);
edgeangles = atan2(y(ind+1) - y(ind),x(ind+1) - x(ind));
% move the angle into the first quadrant.
edgeangles = unique(mod(edgeangles,pi/2));

% now just check each edge of the hull
nang = length(edgeangles);              
area = inf;                           
perimeter = inf;
met = inf;
xy = [x,y];
for i = 1:nang                         
  % rotate the data through -theta 
  rot = Rmat(-edgeangles(i));
  xyr = xy*rot;
  xymin = min(xyr,[],1);
  xymax = max(xyr,[],1);

  % The area is simple, as is the perimeter
  A_i = prod(xymax - xymin);
  P_i = 2*sum(xymax-xymin);

  if metric=='a'
    M_i = A_i;
  else
    M_i = P_i;
  end

  % new metric value for the current interval. Is it better?
  if M_i<met
    % keep this one
    met = M_i;
    area = A_i;
    perimeter = P_i;

    rect = [xymin;[xymax(1),xymin(2)];xymax;[xymin(1),xymax(2)];xymin];
    rect = rect*rot';
    rectx = rect(:,1);
    recty = rect(:,2);
  end
end
% get the final rect

% all done

end % mainline end

使用实例1.

I=imread('E:\cutcut\whhhh.BMP'); %此处为图像所放路径和图片名字。
bw=im2bw(I,0.90);   %将图像二值化
bw = ~bw;%取反
bw = bwareaopen(bw,200,8);  %去除200以下的连通区域
img_reg= regionprops(bw);   %取连通区域,ima_reg默认有质心和box两个参数
bbboooxxx = cat(1,img_reg.BoundingBox); 数组保存所有box

for i=11
 rect = [bbboooxxx(i,1),bbboooxxx(i,2),bbboooxxx(i,3),bbboooxxx(i,4)];
 cutpic =imcrop(bw,rect);%每次裁一小块
 cutpic1 = bwareaopen( cutpic,600,8);%去除附近的其他东西
[r c]=find(cutpic1==1);  %找出边界
[rectx,recty,area,perimeter] = minboundrect(c,r,'a'); 
% 'a'是按面积算的最小矩形,调用函数
figure
imshow(cutpic);
line(rectx(:),recty(:),'color','r');
end

使用实例2.
这是matlab论坛上一个大佬的,果然好用,虽然不是自己写的感觉乖乖的

function minb(x)
I = imread(x);
h=figure;
subplot(2, 2, 1); imshow(I);
title('原图');
I1 = rgb2gray(I); 
subplot(2, 2, 2); imshow(I1);
title('灰度图');
I2 = medfilt2(I1); 
bw1 = im2bw(I2, graythresh(I2));
%bw1=~bw1;
bw1= bwareaopen(bw1,50,4);
subplot(2, 2, 3); imshow(bw1);
B=bwboundaries(bw1);
title('二值图');
[L, n]=bwlabel(bw1, 4);
figure;
imshow(I);
stats = regionprops(L,'all');
Cen = cat(1, stats.Centroid);
hold on;
for i=1:1:n
  boundary=B{i};
[rx,ry,area]=minboundrect(boundary(:,2),boundary(:,1));
hold on;
line(rx,ry ,'Color','r','LineWidth',2);
end
str = sprintf('共%d个', n);
title(str, 'Color', 'r');
end
评论 3 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

歌古道

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值