www.gusucode.com > 冈萨雷斯数字图像处理matlab版源码V1.1 > 冈萨雷斯数字图像处理matlab版源码V1.1.3/code/diameter.m
function s = diameter(L) %DIAMETER Measure diameter and related properties of image regions. % S = DIAMETER(L) computes the diameter, the major axis endpoints, % the minor axis endpoints, and the basic rectangle of each labeled % region in the label matrix L. Positive integer elements of L % correspond to different regions. For example, the set of elements % of L equal to 1 corresponds to region 1; the set of elements of L % equal to 2 corresponds to region 2; and so on. S is a structure % array of length max(L(:)). The fields of the structure array % include: % % Diameter % MajorAxis % MinorAxis % BasicRectangle % % The Diameter field, a scalar, is the maximum distance between any % two pixels in the corresponding region. % % The MajorAxis field is a 2-by-2 matrix. The rows contain the row % and column coordinates for the endpoints of the major axis of the % corresponding region. % % The MinorAxis field is a 2-by-2 matrix. The rows contain the row % and column coordinates for the endpoints of the minor axis of the % corresponding region. % % The BasicRectangle field is a 4-by-2 matrix. Each row contains % the row and column coordinates of a corner of the % region-enclosing rectangle defined by the major and minor axes. % % For more information about these measurements, see Section 11.2.1 % of Digital Image Processing, by Gonzalez and Woods, 2nd edition, % Prentice Hall. % Copyright 2002-2004 R. C. Gonzalez, R. E. Woods, & S. L. Eddins % Digital Image Processing Using MATLAB, Prentice-Hall, 2004 % $Revision: 1.6 $ $Date: 2003/11/21 14:31:09 $ s = regionprops(L, {'Image', 'BoundingBox'}); for k = 1:length(s) [s(k).Diameter, s(k).MajorAxis, perim_r, perim_c] = ... compute_diameter(s(k)); [s(k).BasicRectangle, s(k).MinorAxis] = ... compute_basic_rectangle(s(k), perim_r, perim_c); end %-------------------------------------------------------------------% function [d, majoraxis, r, c] = compute_diameter(s) % [D, MAJORAXIS, R, C] = COMPUTE_DIAMETER(S) computes the diameter % and major axis for the region represented by the structure S. S % must contain the fields Image and BoundingBox. COMPUTE_DIAMETER % also returns the row and column coordinates (R and C) of the % perimeter pixels of s.Image. % Compute row and column coordinates of perimeter pixels. [r, c] = find(bwperim(s.Image)); r = r(:); c = c(:); [rp, cp] = prune_pixel_list(r, c); num_pixels = length(rp); switch num_pixels case 0 d = -Inf; majoraxis = ones(2, 2); case 1 d = 0; majoraxis = [rp cp; rp cp]; case 2 d = (rp(2) - rp(1))^2 + (cp(2) - cp(1))^2; majoraxis = [rp cp]; otherwise % Generate all combinations of 1:num_pixels taken two at at time. % Method suggested by Peter Acklam. [idx(:, 2) idx(:, 1)] = find(tril(ones(num_pixels), -1)); rr = rp(idx); cc = cp(idx); dist_squared = (rr(:, 1) - rr(:, 2)).^2 + ... (cc(:, 1) - cc(:, 2)).^2; [max_dist_squared, idx] = max(dist_squared); majoraxis = [rr(idx,:)' cc(idx,:)']; d = sqrt(max_dist_squared); upper_image_row = s.BoundingBox(2) + 0.5; left_image_col = s.BoundingBox(1) + 0.5; majoraxis(:, 1) = majoraxis(:, 1) + upper_image_row - 1; majoraxis(:, 2) = majoraxis(:, 2) + left_image_col - 1; end %-------------------------------------------------------------------% function [basicrect, minoraxis] = compute_basic_rectangle(s, ... perim_r, perim_c) % [BASICRECT,MINORAXIS] = COMPUTE_BASIC_RECTANGLE(S, PERIM_R, % PERIM_C) computes the basic rectangle and the minor axis % end-points for the region represented by the structure S. S must % contain the fields Image, BoundingBox, MajorAxis, and % Diameter. PERIM_R and PERIM_C are the row and column coordinates % of perimeter of s.Image. BASICRECT is a 4-by-2 matrix, each row % of which contains the row and column coordinates of one corner of % the basic rectangle. % Compute the orientation of the major axis. theta = atan2(s.MajorAxis(2, 1) - s.MajorAxis(1, 1), ... s.MajorAxis(2, 2) - s.MajorAxis(1, 2)); % Form rotation matrix. T = [cos(theta) sin(theta); -sin(theta) cos(theta)]; % Rotate perimeter pixels. p = [perim_c perim_r]; p = p * T'; % Calculate minimum and maximum x- and y-coordinates for the rotated % perimeter pixels. x = p(:, 1); y = p(:, 2); min_x = min(x); max_x = max(x); min_y = min(y); max_y = max(y); corners_x = [min_x max_x max_x min_x]'; corners_y = [min_y min_y max_y max_y]'; % Rotate corners of the basic rectangle. corners = [corners_x corners_y] * T; % Translate according to the region's bounding box. upper_image_row = s.BoundingBox(2) + 0.5; left_image_col = s.BoundingBox(1) + 0.5; basicrect = [corners(:, 2) + upper_image_row - 1, ... corners(:, 1) + left_image_col - 1]; % Compute minor axis end-points, rotated. x = (min_x + max_x) / 2; y1 = min_y; y2 = max_y; endpoints = [x y1; x y2]; % Rotate minor axis end-points back. endpoints = endpoints * T; % Translate according to the region's bounding box. minoraxis = [endpoints(:, 2) + upper_image_row - 1, ... endpoints(:, 1) + left_image_col - 1]; %-------------------------------------------------------------------% function [r, c] = prune_pixel_list(r, c) % [R, C] = PRUNE_PIXEL_LIST(R, C) removes pixels from the vectors % R and C that cannot be endpoints of the major axis. This % elimination is based on geometrical constraints described in % Russ, Image Processing Handbook, Chapter 8. top = min(r); bottom = max(r); left = min(c); right = max(c); % Which points are inside the upper circle? x = (left + right)/2; y = top; radius = bottom - top; inside_upper = ( (c - x).^2 + (r - y).^2 ) < radius^2; % Which points are inside the lower circle? y = bottom; inside_lower = ( (c - x).^2 + (r - y).^2 ) < radius^2; % Which points are inside the left circle? x = left; y = (top + bottom)/2; radius = right - left; inside_left = ( (c - x).^2 + (r - y).^2 ) < radius^2; % Which points are inside the right circle? x = right; inside_right = ( (c - x).^2 + (r - y).^2 ) < radius^2; % Eliminate points that are inside all four circles. delete_idx = find(inside_left & inside_right & ... inside_upper & inside_lower); r(delete_idx) = []; c(delete_idx) = [];