Home > data-vis > supporting_functions > export_fig > crop_borders.m

crop_borders

PURPOSE ^

CROP_BORDERS Crop the borders of an image or stack of images

SYNOPSIS ^

function [A, vA, vB, bb_rel] = crop_borders(A, bcol, padding, crop_amounts)

DESCRIPTION ^

CROP_BORDERS Crop the borders of an image or stack of images

   [B, vA, vB, bb_rel] = crop_borders(A, bcol, [padding])

IN:
   A - HxWxCxN stack of images.
   bcol - Cx1 background colour vector.
   padding - scalar indicating how much padding to have in relation to
             the cropped-image-size (0<=padding<=1). Default: 0
   crop_amounts - 4-element vector of crop amounts: [top,right,bottom,left]
             where NaN/Inf indicate auto-cropping, 0 means no cropping,
             and any other value mean cropping in pixel amounts.

OUT:
   B - JxKxCxN cropped stack of images.
   vA     - coordinates in A that contain the cropped image
   vB     - coordinates in B where the cropped version of A is placed
   bb_rel - relative bounding box (used for eps-cropping)

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [A, vA, vB, bb_rel] = crop_borders(A, bcol, padding, crop_amounts)
0002 %CROP_BORDERS Crop the borders of an image or stack of images
0003 %
0004 %   [B, vA, vB, bb_rel] = crop_borders(A, bcol, [padding])
0005 %
0006 %IN:
0007 %   A - HxWxCxN stack of images.
0008 %   bcol - Cx1 background colour vector.
0009 %   padding - scalar indicating how much padding to have in relation to
0010 %             the cropped-image-size (0<=padding<=1). Default: 0
0011 %   crop_amounts - 4-element vector of crop amounts: [top,right,bottom,left]
0012 %             where NaN/Inf indicate auto-cropping, 0 means no cropping,
0013 %             and any other value mean cropping in pixel amounts.
0014 %
0015 %OUT:
0016 %   B - JxKxCxN cropped stack of images.
0017 %   vA     - coordinates in A that contain the cropped image
0018 %   vB     - coordinates in B where the cropped version of A is placed
0019 %   bb_rel - relative bounding box (used for eps-cropping)
0020 
0021 %{
0022 % 06/03/15: Improved image cropping thanks to Oscar Hartogensis
0023 % 08/06/15: Fixed issue #76: case of transparent figure bgcolor
0024 % 21/02/16: Enabled specifying non-automated crop amounts
0025 % 04/04/16: Fix per Luiz Carvalho for old Matlab releases
0026 % 23/10/16: Fixed issue #175: there used to be a 1px minimal padding in case of crop, now removed
0027 %}
0028 
0029     if nargin < 3
0030         padding = 0;
0031     end
0032     if nargin < 4
0033         crop_amounts = nan(1,4);  % =auto-cropping
0034     end
0035     crop_amounts(end+1:4) = NaN;  % fill missing values with NaN
0036 
0037     [h, w, c, n] = size(A);
0038     if isempty(bcol)  % case of transparent bgcolor
0039         bcol = A(ceil(end/2),1,:,1);
0040     end
0041     if isscalar(bcol)
0042         bcol = bcol(ones(c, 1));
0043     end
0044 
0045     % Crop margin from left
0046     if ~isfinite(crop_amounts(4))
0047         bail = false;
0048         for l = 1:w
0049             for a = 1:c
0050                 if ~all(col(A(:,l,a,:)) == bcol(a))
0051                     bail = true;
0052                     break;
0053                 end
0054             end
0055             if bail
0056                 break;
0057             end
0058         end
0059     else
0060         l = 1 + abs(crop_amounts(4));
0061     end
0062 
0063     % Crop margin from right
0064     if ~isfinite(crop_amounts(2))
0065         bcol = A(ceil(end/2),w,:,1);
0066         bail = false;
0067         for r = w:-1:l
0068             for a = 1:c
0069                 if ~all(col(A(:,r,a,:)) == bcol(a))
0070                     bail = true;
0071                     break;
0072                 end
0073             end
0074             if bail
0075                 break;
0076             end
0077         end
0078     else
0079         r = w - abs(crop_amounts(2));
0080     end
0081 
0082     % Crop margin from top
0083     if ~isfinite(crop_amounts(1))
0084         bcol = A(1,ceil(end/2),:,1);
0085         bail = false;
0086         for t = 1:h
0087             for a = 1:c
0088                 if ~all(col(A(t,:,a,:)) == bcol(a))
0089                     bail = true;
0090                     break;
0091                 end
0092             end
0093             if bail
0094                 break;
0095             end
0096         end
0097     else
0098         t = 1 + abs(crop_amounts(1));
0099     end
0100 
0101     % Crop margin from bottom
0102     bcol = A(h,ceil(end/2),:,1);
0103     if ~isfinite(crop_amounts(3))
0104         bail = false;
0105         for b = h:-1:t
0106             for a = 1:c
0107                 if ~all(col(A(b,:,a,:)) == bcol(a))
0108                     bail = true;
0109                     break;
0110                 end
0111             end
0112             if bail
0113                 break;
0114             end
0115         end
0116     else
0117         b = h - abs(crop_amounts(3));
0118     end
0119 
0120     if padding == 0  % no padding
0121         % Issue #175: there used to be a 1px minimal padding in case of crop, now removed
0122         %{
0123         if ~isequal([t b l r], [1 h 1 w]) % Check if we're actually croppping
0124             padding = 1; % Leave one boundary pixel to avoid bleeding on resize
0125             bcol(:) = nan;  % make the 1px padding transparent
0126         end
0127         %}
0128     elseif abs(padding) < 1  % pad value is a relative fraction of image size
0129         padding = sign(padding)*round(mean([b-t r-l])*abs(padding)); % ADJUST PADDING
0130     else  % pad value is in units of 1/72" points
0131         padding = round(padding);  % fix cases of non-integer pad value
0132     end
0133 
0134     if padding > 0  % extra padding
0135         % Create an empty image, containing the background color, that has the
0136         % cropped image size plus the padded border
0137         B = repmat(bcol,[(b-t)+1+padding*2,(r-l)+1+padding*2,1,n]);  % Fix per Luiz Carvalho
0138         % vA - coordinates in A that contain the cropped image
0139         vA = [t b l r];
0140         % vB - coordinates in B where the cropped version of A will be placed
0141         vB = [padding+1, (b-t)+1+padding, padding+1, (r-l)+1+padding];
0142         % Place the original image in the empty image
0143         B(vB(1):vB(2), vB(3):vB(4), :, :) = A(vA(1):vA(2), vA(3):vA(4), :, :);
0144         A = B;
0145     else  % extra cropping
0146         vA = [t-padding b+padding l-padding r+padding];
0147         A = A(vA(1):vA(2), vA(3):vA(4), :, :);
0148         vB = [NaN NaN NaN NaN];
0149     end
0150 
0151     % For EPS cropping, determine the relative BoundingBox - bb_rel
0152     bb_rel = [l-1 h-b-1 r+1 h-t+1]./[w h w h];
0153 end
0154 
0155 function A = col(A)
0156     A = A(:);
0157 end

Generated on Tue 23-May-2017 20:00:55 by m2html © 2005