ParaMonte MATLAB 3.0.0
Parallel Monte Carlo and Machine Learning Library
See the latest version documentation.
crop_borders.m
Go to the documentation of this file.
1function [A, vA, vB, bb_rel] = crop_borders(A, bcol, padding, crop_amounts)
2%CROP_BORDERS Crop the borders of an image or stack of images
3%
4% [B, vA, vB, bb_rel] = crop_borders(A, bcol, [padding])
5%
6%IN:
7% A - HxWxCxN stack of images.
8% bcol - Cx1 background colour vector.
9% padding - scalar indicating how much padding to have in relation to
10% the cropped-image-size (0<=padding<=1). Default: 0
11% crop_amounts - 4-element vector of crop amounts: [top,right,bottom,left]
12% where NaN/Inf indicate auto-cropping, 0 means no cropping,
13% and any other value mean cropping in pixel amounts.
14%
15%OUT:
16% B - JxKxCxN cropped stack of images.
17% vA - coordinates in A that contain the cropped image
18% vB - coordinates in B where the cropped version of A is placed
19% bb_rel - relative bounding box (used for eps-cropping)
20
21%{
22% 06/03/15: Improved image cropping thanks to Oscar Hartogensis
23% 08/06/15: Fixed issue #76: case of transparent figure bgcolor
24% 21/02/16: Enabled specifying non-automated crop amounts
25% 04/04/16: Fix per Luiz Carvalho for old Matlab releases
26% 23/10/16: Fixed issue #175: there used to be a 1px minimal padding in case of crop, now removed
27% 15/05/22: Fixed EPS bounding box (issue #356)
28%}
29
30 if nargin < 3
31 padding = 0;
32 end
33 if nargin < 4
34 crop_amounts = nan(1,4); % =auto-cropping
35 end
36 crop_amounts(end+1:4) = NaN; % fill missing values with NaN
37
38 [h, w, c, n] = size(A);
39 if isempty(bcol) % case of transparent bgcolor
40 bcol = A(ceil(end/2),1,:,1);
41 end
42 if isscalar(bcol)
43 bcol = bcol(ones(c, 1));
44 end
45
46 % Crop margin from left
47 if ~isfinite(crop_amounts(4))
48 bail = false;
49 for l = 1:w
50 for a = 1:c
51 if ~all(col(A(:,l,a,:)) == bcol(a))
52 bail = true;
53 break;
54 end
55 end
56 if bail
57 break;
58 end
59 end
60 else
61 l = 1 + abs(crop_amounts(4));
62 end
63
64 % Crop margin from right
65 if ~isfinite(crop_amounts(2))
66 bcol = A(ceil(end/2),w,:,1);
67 bail = false;
68 for r = w:-1:l
69 for a = 1:c
70 if ~all(col(A(:,r,a,:)) == bcol(a))
71 bail = true;
72 break;
73 end
74 end
75 if bail
76 break;
77 end
78 end
79 else
80 r = w - abs(crop_amounts(2));
81 end
82
83 % Crop margin from top
84 if ~isfinite(crop_amounts(1))
85 bcol = A(1,ceil(end/2),:,1);
86 bail = false;
87 for t = 1:h
88 for a = 1:c
89 if ~all(col(A(t,:,a,:)) == bcol(a))
90 bail = true;
91 break;
92 end
93 end
94 if bail
95 break;
96 end
97 end
98 else
99 t = 1 + abs(crop_amounts(1));
100 end
101
102 % Crop margin from bottom
103 bcol = A(h,ceil(end/2),:,1);
104 if ~isfinite(crop_amounts(3))
105 bail = false;
106 for b = h:-1:t
107 for a = 1:c
108 if ~all(col(A(b,:,a,:)) == bcol(a))
109 bail = true;
110 break;
111 end
112 end
113 if bail
114 break;
115 end
116 end
117 else
118 b = h - abs(crop_amounts(3));
119 end
120
121 if padding == 0 % no padding
122 % Issue #175: there used to be a 1px minimal padding in case of crop, now removed
123 %{
124 if ~isequal([t b l r], [1 h 1 w]) % Check if we're actually croppping
125 padding = 1; % Leave one boundary pixel to avoid bleeding on resize
126 bcol(:) = nan; % make the 1px padding transparent
127 end
128 %}
129 elseif abs(padding) < 1 % pad value is a relative fraction of image size
130 padding = sign(padding)*round(mean([b-t r-l])*abs(padding)); % ADJUST PADDING
131 else % pad value is in units of 1/72" points
132 padding = round(padding); % fix cases of non-integer pad value
133 end
134
135 if padding > 0 % extra padding
136 % Create an empty image, containing the background color, that has the
137 % cropped image size plus the padded border
138 B = repmat(bcol,[(b-t)+1+padding*2,(r-l)+1+padding*2,1,n]); % Fix per Luiz Carvalho
139 % vA - coordinates in A that contain the cropped image
140 vA = [t b l r];
141 % vB - coordinates in B where the cropped version of A will be placed
142 vB = [padding+1, (b-t)+1+padding, padding+1, (r-l)+1+padding];
143 % Place the original image in the empty image
144 B(vB(1):vB(2), vB(3):vB(4), :, :) = A(vA(1):vA(2), vA(3):vA(4), :, :);
145 A = B;
146 else % extra cropping
147 vA = [t-padding b+padding l-padding r+padding];
148 A = A(vA(1):vA(2), vA(3):vA(4), :, :);
149 vB = [NaN NaN NaN NaN];
150 end
151
152 % For EPS cropping, determine the relative BoundingBox - bb_rel
153 bb_pixels = [l-1 h-b-1 r+1 h-t+1]; %[LowerLeftXY, UpperRightXY]
154 bb_pixels(bb_pixels<0) = 0;
155 bb_pixels = min(bb_pixels, [w h w h]);
156 bb_rel = bb_pixels ./ [w h w h];
157end
158
159function A = col(A)
160 A = A(:);
161end
function version(in silent)
Return a scalar MATLAB string containing the latest available ParaMonte MATLAB version newer than the...
function abs(in path, in style)
Return the Get absolute canonical path of a file or folder.
function crop_borders(in A, in bcol, in padding, in crop_amounts)
function col(in A)