You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
1. W. Burger and M. J. Burge. *Digital Image Processing*. Texts in Computer Science, 2016. [doi:10.1007/978-1-4471-6684-9](https://doi.org/10.1007/978-1-4471-6684-9)
length(src_intervals) ==length(dst_intervals) ||throw(ArgumentError("The dst_intervals must define an interval pair for each consecutive src_interval pair, i.e. length(src_intervals) == length(dst_intervals)."))
107
+
for src_pair in src_intervals
108
+
iffirst(src_pair) ==last(src_pair)
109
+
throw(ArgumentError("The start and end of an interval in src_intervals cannot be equal."))
110
+
end
111
+
end
112
+
T =promote_type(T₁, T₂)
113
+
new{T}(src_intervals, dst_intervals)
114
+
end
115
+
end
116
+
117
+
function (f::PiecewiseLinearStretching)(out::GenericGrayImage, img::GenericGrayImage)
118
+
# Verify that the specified dst_intervals fall inside the permissible range
119
+
# of the output type.
120
+
T =eltype(out)
121
+
for (a,b) in f.dst_intervals
122
+
p =typemin(T)
123
+
r =typemax(T)
124
+
if!(p <= a <= r) ||!(p <= b <= r)
125
+
throw(DomainError("The specified interval [$a, $b] falls outside the permissible range [$p, $r] associated with $T"))
126
+
end
127
+
end
128
+
# A linear mapping of a value x in the interval [A, B] to the interval [a,b] is given by
129
+
# the formula f(x) = (x-A) * ((b-a)/(B-A)) + a. The operation r * x - o is equivalent to
130
+
# (x-A) * ((b-a)/(B-A)) + a. Precalculate the r and o so that later on an inner loop
131
+
# contains only multiplication and addition to get better performance.
132
+
N =length(f.src_intervals)
133
+
rs =zeros(Float64, N)
134
+
os =zeros(Float64, N)
135
+
for (src, dst) inzip(pairs(f.src_intervals), pairs(f.dst_intervals))
136
+
n, (A,B) = src
137
+
_, (a,b) = dst
138
+
rs[n] = (b - a) / (B - A)
139
+
os[n] = (A*b - B*a) / (B - A)
140
+
end
141
+
142
+
# Determine which interval the source pixel fall into, and apply the accompanying linear
143
+
# transformation taking into account NaN values.
144
+
@inboundsfor p ineachindex(img)
145
+
val = img[p]
146
+
ifisnan(val)
147
+
out[p] = val
148
+
else
149
+
is_inside_src_intervals =false
150
+
for (n, (A,B)) inpairs(f.src_intervals)
151
+
if (A <= val < B) || (A <= val <= B && n == N)
152
+
newval = rs[n] * val - os[n]
153
+
out[p] = T <:Integer?round(Int, newval) : newval
154
+
is_inside_src_intervals =true
155
+
break
156
+
end
157
+
end
158
+
if!is_inside_src_intervals
159
+
# Saturate pixels that fall outside the specified src_intervals by setting
160
+
# them equal to the start/end of the edge dst_intervals.
161
+
a =first(first(f.dst_intervals))
162
+
b =last(last(f.dst_intervals))
163
+
A =first(first(f.src_intervals))
164
+
newval = val < A ? a : b
165
+
out[p] = T <:Integer?round(Int, newval) : newval
166
+
end
167
+
end
168
+
end
169
+
return out
170
+
end
171
+
172
+
function (f::PiecewiseLinearStretching)(out::AbstractArray{<:Color3}, img::AbstractArray{<:Color3})
0 commit comments