搜索内容 搜索用户

# [已解决] matlab里对一个区域进行定位 NO_34 发表于 2018-5-14 11:24:02
 如图，希望得到图中坦克的位置坐标，并且把该区域框起来。求程序，谢谢各位老师。

### 本帖子中包含更多资源

x atpalain 发表于 2018-5-14 11:53:46
 代码如下，可根据自己的需要修改算法： close all clear clc I = imread('HB14982.JPG'); level = graythresh(I); Ibw = im2bw(I,1.5*level); regionsMax = maxArea(Ibw,1,1); objIdx = find(regionsMax>0); [y, x] = ind2sub(size(I), objIdx); [rectx,recty,area,perimeter] = minboundrect(x,y); % show result figure; imshow(I); hold on; line(rectx,recty,'color','g'); function regionsMax = maxArea(Ibw,regionNumber,strelSize) %----------------------------------------------------------- % 功能：找到二值图像中区域最大的几个形状 % % 函数名： maxArea（） % 参数： %   Ibw： 二值图像； %   regionNumber: 最大形状个数 %   strelSize：使细小连通区域分离的开运算元素半径大小 % 输出值： %   regionsMax：最大区域图形 %------------------------------------------------------------ se = strel('disk',strelSize);  % 半径为strelSize的圆盘型元素 % BW = imopen(Ibw,se);   % 图像开运算 BW = imclose(Ibw,se);   % 图像闭运算 L = bwlabel(BW);       % 图像中图形区域编号 S = regionprops(L,'Area'); % 求各图形的面积 areas =[S.Area]; [~,ind] = sort(areas,'descend'); regionsMax = ismember(L,ind(1:regionNumber));  % 选择图形中面积最大的前regionNumber个图形 end 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. % % % Example usage: %  x = rand(50000,1); %  y = rand(50000,1); %  tic,[rx,ry,area] = minboundrect(x,y);toc % %  Elapsed time is 0.105754 seconds. % %  [rx,ry] %  ans = %      0.99994  -4.2515e-06 %      0.99998      0.99999 %   2.6441e-05            1 %  -5.1673e-06   2.7356e-05 %      0.99994  -4.2515e-06 % %  area %  area = %      0.99994 % % % See also: minboundcircle, minboundtri, minboundsphere % % % Author: John D'Errico % E-mail: woodchips@rochester.rr.com % Release: 3.0 % Release date: 3/7/07 % 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 % 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     edges = convhull(x,y);         % exclude those points inside the hull as not relevant     % also sorts the points into their convex hull as a     % closed polygon         x = x(edges);     y = y(edges);         % 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

x

13 条回复

## 倒序浏览 atpalain 发表于 2018-5-14 11:53:46
 代码如下，可根据自己的需要修改算法： close all clear clc I = imread('HB14982.JPG'); level = graythresh(I); Ibw = im2bw(I,1.5*level); regionsMax = maxArea(Ibw,1,1); objIdx = find(regionsMax>0); [y, x] = ind2sub(size(I), objIdx); [rectx,recty,area,perimeter] = minboundrect(x,y); % show result figure; imshow(I); hold on; line(rectx,recty,'color','g'); function regionsMax = maxArea(Ibw,regionNumber,strelSize) %----------------------------------------------------------- % 功能：找到二值图像中区域最大的几个形状 % % 函数名： maxArea（） % 参数： %   Ibw： 二值图像； %   regionNumber: 最大形状个数 %   strelSize：使细小连通区域分离的开运算元素半径大小 % 输出值： %   regionsMax：最大区域图形 %------------------------------------------------------------ se = strel('disk',strelSize);  % 半径为strelSize的圆盘型元素 % BW = imopen(Ibw,se);   % 图像开运算 BW = imclose(Ibw,se);   % 图像闭运算 L = bwlabel(BW);       % 图像中图形区域编号 S = regionprops(L,'Area'); % 求各图形的面积 areas =[S.Area]; [~,ind] = sort(areas,'descend'); regionsMax = ismember(L,ind(1:regionNumber));  % 选择图形中面积最大的前regionNumber个图形 end 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. % % % Example usage: %  x = rand(50000,1); %  y = rand(50000,1); %  tic,[rx,ry,area] = minboundrect(x,y);toc % %  Elapsed time is 0.105754 seconds. % %  [rx,ry] %  ans = %      0.99994  -4.2515e-06 %      0.99998      0.99999 %   2.6441e-05            1 %  -5.1673e-06   2.7356e-05 %      0.99994  -4.2515e-06 % %  area %  area = %      0.99994 % % % See also: minboundcircle, minboundtri, minboundsphere % % % Author: John D'Errico % E-mail: woodchips@rochester.rr.com % Release: 3.0 % Release date: 3/7/07 % 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 % 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     edges = convhull(x,y);         % exclude those points inside the hull as not relevant     % also sorts the points into their convex hull as a     % closed polygon         x = x(edges);     y = y(edges);         % 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

### 本帖子中包含更多资源

x NO_34 发表于 2018-5-14 12:32:55
 atpalain 发表于 2018-5-14 11:53 代码如下，可根据自己的需要修改算法： 谢谢您！我试了一下，提示未对参数 rectx 或者还有其他参数赋值，请问怎么赋值啊 atpalain 发表于 2018-5-14 12:51:46
 NO_34 发表于 2018-5-14 12:32 谢谢您！我试了一下，提示未对参数 rectx 或者还有其他参数赋值，请问怎么赋值啊 ... 并不需要赋值 那个是输出结果 所有代码跑一遍就行 dwj777 发表于 2018-5-14 14:59:37
 atpalain 发表于 2018-5-14 12:51 并不需要赋值 那个是输出结果 所有代码跑一遍就行 close all clear clc I = imread('d:\work\tank.jpg'); level = graythresh(I); Ibw = im2bw(I,1.5*level); Ibw = double(Ibw) regionsMax = maxArea(Ibw,1,1); objIdx = find(regionsMax>0); [y, x] = ind2sub(size(I), objIdx); [rectx,recty,area,perimeter] = minboundrect(x,y); % show result figure; imshow(I); hold on; line(rectx,recty,'color','g'); 到这就出错：Undefined function or method 'maxArea' for input arguments of type 'double' dwj777 发表于 2018-5-14 15:02:40
 Ibw = double(Ibw)这句是后来加的，一样的错误 atpalain 发表于 2018-5-14 15:28:42
 dwj777 发表于 2018-5-14 15:02 Ibw = double(Ibw)这句是后来加的，一样的错误 maxArea的输入参数是二值图 转成double型是无法使用这个函数的 dwj777 发表于 2018-5-14 16:20:56
 谢谢，但是您的原程序报Undefined function or method 'maxArea' for input arguments of type 'double'怎么解决啊！ dwj777 发表于 2018-5-14 16:25:32
 未定义的函数或方法“maxArea”用于输入“Double”类型的参数 dwj777 发表于 2018-5-14 16:29:41
 查了一下帮助，遗憾，我的版本2010B没有maxArea这个函数，再次谢谢您 NO_34 发表于 2018-5-15 10:38:31
 atpalain 发表于 2018-5-14 12:51 并不需要赋值 那个是输出结果 所有代码跑一遍就行 出错 minboundrect (line 71) if (nargin<3) || isempty(metric) 调用 "C:\Users\i_amares\Desktop\chengxu\minboundrect.m>minboundrect" 时，未对输出参数 "rectx" (可能还包括其他参数)赋值。 出错 Untitled7 (line 15) [rectx,recty,area,perimeter] = minboundrect(x,y);               我的总是报错这个。。 NO_34 发表于 2018-5-15 10:45:57
 atpalain 发表于 2018-5-14 12:51 并不需要赋值 那个是输出结果 所有代码跑一遍就行 出错 minboundrect (line 71) if (nargin<3) || isempty(metric) 调用 "C:\Users\i_amares\Desktop\chengxu\minboundrect.m>minboundrect" 时，未对输出参数 "rectx" (可能还包括其他参数)赋值。 出错 Untitled7 (line 15) [rectx,recty,area,perimeter] = minboundrect(x,y); 这是我的结果，不知道哪里出错了…… Qxbloy 发表于 2018-5-16 14:06:43
 同学你这个问题解决了吗，我也遇到这个不会，方便的话能互加qq讨论吗，1784089764，谢谢 atpalain 发表于 2018-5-17 16:59:00
 dwj777 发表于 2018-5-14 16:29 查了一下帮助，遗憾，我的版本2010B没有maxArea这个函数，再次谢谢您 这个函数写在主程序下面了 就在那段代码里面 把所有程序跑一遍是可以实现的 虽然我用的是2017 但是里面调用的函数并是不matlab自带的 而且都写在代码里了 你找个稍微懂的人帮帮忙 就可以正常运行
 本版积分规则 回帖后跳转到最后一页
##### 热门教程   