Matlab 最小外接矩形
2016-05-12 15:07
2376 查看
Matlab 中并没有发现最小外接矩形的代码,为了方便
下面提供最小外接矩形的代码:
注:这个函数是源于网上找到的代码的改进版,原版不能检测水平线或者垂直线
当然这段代码并没有获取到外接矩形的长和宽,下面我在写一个函数,就可以获得对应外接矩形的长和宽
这里默认为较短的距离为宽,较长的距离为长。
调用代码如下:注(dataX, dataY为需要计算最小外接矩形的数据。)
下面提供最小外接矩形的代码:
注:这个函数是源于网上找到的代码的改进版,原版不能检测水平线或者垂直线
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
当然这段代码并没有获取到外接矩形的长和宽,下面我在写一个函数,就可以获得对应外接矩形的长和宽
function [ wid hei ] = minboxing( d_x , d_y ) %minboxing Summary of this function goes here % Detailed explanation goes here dd = [d_x, d_y]; dd1 = dd([4 1 2 3],:); ds = sqrt(sum((dd-dd1).^2,2)); wid = min(ds(1:2)); hei = max(ds(1:2)); end
这里默认为较短的距离为宽,较长的距离为长。
调用代码如下:注(dataX, dataY为需要计算最小外接矩形的数据。)
[recty,rectx,area,perimeter] = minboundrect(dataX, dataY); [wei hei] = minboxing(rectx(1:end-1),recty(1:end-1));
相关文章推荐
- 求纱管颜色直方图的matlab 程序
- 数字图像处理学习 matable
- matlab 高级函数 —— ind2sub、kron
- C#调用matlab动态链接库
- matlab打开和生成使用.p文件和exe文件
- Matlab绘图总结1
- Matlab绘制汉经纬度的散点图 2
- matlab cell
- matlab安装详解
- matlab制作及生成avi,gif动画
- Matlab截图小工具
- 数字图像处理(Matlab)读书笔记
- matlab画图
- Ubuntu16.04下 Matlab2015b安装与激活及注意事项:
- Matlab取棋子博弈问题
- Modelsim文件读取问题与matlab文件写入
- 数值计算误差
- Matlab学习 之 随机数
- matlab读入从文件中读取大量的数据
- matlab函数 size()函数和waterfal()l函数,三维图形,矩阵