Skip to content

Commit dc37c60

Browse files
committed
Merge pull request #557 from stefan-k/master
imthresh, ncc, ftshow, imgaussiannoise, fixed imfilter
2 parents f2ba989 + 3c88736 commit dc37c60

File tree

1 file changed

+67
-6
lines changed

1 file changed

+67
-6
lines changed

examples/image.jl

+67-6
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,17 @@ function ppmwrite(img, file::String)
5252
error("unsupported array dimensions")
5353
end
5454
elseif eltype(img) <: Float
55-
if ndims(img) == 3 && size(img,3) == 3
55+
# prevent overflow
56+
a = copy(img)
57+
a[img > 1] = 1
58+
a[img < 0] = 0
59+
if ndims(a) == 3 && size(a,3) == 3
5660
for i=1:n, j=1:m, k=1:3
57-
write(s, uint8(255*img[i,j,k]))
61+
write(s, uint8(255*a[i,j,k]))
5862
end
59-
elseif ndims(img) == 2
63+
elseif ndims(a) == 2
6064
for i=1:n, j=1:m, k=1:3
61-
write(s, uint8(255*img[i,j]))
65+
write(s, uint8(255*a[i,j]))
6266
end
6367
else
6468
error("unsupported array dimensions")
@@ -240,10 +244,20 @@ end
240244
# normalized by Array size
241245
sadn{T}(A::Array{T}, B::Array{T}) = sad(A, B)/numel(A)
242246

247+
# normalized cross correlation
248+
function ncc{T}(A::Array{T}, B::Array{T})
249+
Am = A[:]-mean(A[:])
250+
Bm = B[:]-mean(B[:])
251+
res = ((Am/norm(Am))'*(Bm/norm(Bm)))
252+
return res
253+
end
254+
243255
function imfilter{T}(img::Matrix{T}, filter::Matrix{T}, border::String, value)
244256
si, sf = size(img), size(filter)
245257
A = zeros(T, si[1]+sf[1]-1, si[2]+sf[2]-1)
246258
s1, s2 = int((sf[1]-1)/2), int((sf[2]-1)/2)
259+
# correlation instead of convolution
260+
filter = fliplr(fliplr(filter).')
247261
if border == "replicate"
248262
A[s1+1:end-s1, s2+1:end-s2] = img
249263
A[s1+1:end-s1, 1:s2] = repmat(img[:,1], 1, s2)
@@ -288,9 +302,32 @@ function imfilter{T}(img::Matrix{T}, filter::Matrix{T}, border::String, value)
288302
separable = separable && (abs(S[i]) < 10^-7)
289303
end
290304
if separable
291-
C = conv2(squeeze(U[:,1]*sqrt(S[1])), squeeze(V[1,:]*sqrt(S[1])), A)
305+
# conv2 isn't suitable for this (kernel center should be the actual center of the kernel)
306+
#C = conv2(squeeze(U[:,1]*sqrt(S[1])), squeeze(V[1,:]*sqrt(S[1])), A)
307+
x = squeeze(U[:,1]*sqrt(S[1]))
308+
y = squeeze(V[1,:]*sqrt(S[1]))
309+
sa = size(A)
310+
m = length(y)+sa[1]
311+
n = length(x)+sa[2]
312+
B = zeros(T, m, n)
313+
B[int((length(x))/2)+1:sa[1]+int((length(x))/2),int((length(y))/2)+1:sa[2]+int((length(y))/2)] = A
314+
y = fft([zeros(T,int((m-length(y)-1)/2)); y; zeros(T,int((m-length(y)-1)/2))])./m
315+
x = fft([zeros(T,int((m-length(x)-1)/2)); x; zeros(T,int((n-length(x)-1)/2))])./n
316+
C = fftshift(ifft2(fft2(B) .* (y * x.')))
317+
if T <: Real
318+
C = real(C)
319+
end
292320
else
293-
C = conv2(A, filter)
321+
#C = conv2(A, filter)
322+
sa, sb = size(A), size(filter)
323+
At = zeros(T, sa[1]+sb[1], sa[2]+sb[2])
324+
Bt = zeros(T, sa[1]+sb[1], sa[2]+sb[2])
325+
At[int(end/2-sa[1]/2)+1:int(end/2+sa[1]/2), int(end/2-sa[2]/2)+1:int(end/2+sa[2]/2)] = A
326+
Bt[int(end/2-sb[1]/2)+1:int(end/2+sb[1]/2), int(end/2-sb[2]/2)+1:int(end/2+sb[2]/2)] = filter
327+
C = fftshift(ifft2(fft2(At).*fft2(Bt))./((sa[1]+sb[1]-1)*(sa[2]+sb[2]-1)))
328+
if T <: Real
329+
C = real(C)
330+
end
294331
end
295332
sc = size(C)
296333
out = C[int(sc[1]/2-si[1]/2):int(sc[1]/2+si[1]/2)-1, int(sc[2]/2-si[2]/2):int(sc[2]/2+si[2]/2)-1]
@@ -317,3 +354,27 @@ function imlineardiffusion{T}(img::Array{T,2}, dt::Float, iterations::Integer)
317354
end
318355
u
319356
end
357+
358+
function imthresh{T}(img::Array{T,2}, threshold::Float)
359+
if !(0.0 <= threshold <= 1.0)
360+
error("threshold must be between 0 and 1")
361+
end
362+
img_max, img_min = max(img), min(img)
363+
tmp = zeros(T, size(img))
364+
# matter of taste?
365+
#tmp[img >= threshold*(img_max-img_min)+img_min] = 1
366+
tmp[img >= threshold] = 1
367+
return tmp
368+
end
369+
370+
function imgaussiannoise{T}(img::Array{T}, variance::Number, mean::Number)
371+
tmp = img + sqrt(variance)*randn(size(img)) + mean
372+
return tmp
373+
end
374+
375+
imgaussiannoise{T}(img::Array{T}, variance::Number) = imgaussiannoise(img, variance, 0)
376+
imgaussiannoise{T}(img::Array{T}) = imgaussiannoise(img, 0.01, 0)
377+
378+
# 'illustrates' fourier transform
379+
ftshow{T}(A::Array{T,2}) = imshow(log(1+abs(fftshift(A))),[])
380+

0 commit comments

Comments
 (0)