I’m trying to speed up this image illumination flattening routine (i.e. this kind of thing) that highpasses each frame, then rescales the image back to UInt8. I’ve been trying out adding Threads.@threads
before the for
(with JULIA_NUM_THREADS
set to 4), but experienced a few segfaults which may be linked to the large size of the vid variable, so I wondered if there’s a smarter way to optimize this.
For instance, can imfilter be used directly on video stacks? or is there a faster imfilter alternative that approximates a gaussian filter? or a direct highpass filter (rather than lowpass and divide)?
Unfortunately I don’t think I can use a common background image for all frames as the image moves around.
(I’ve been looking for fast global registration methods too, which if found could mean using a single background image, and only doing one lowpass)
using Images, ImageFiltering, StatsBase, Profile, ProfileView
function flatten(vid)
gauss_kern = Kernel.gaussian(100)
for i = 1:size(vid,3)
img = vid[:,:,i] ./ imfilter(vid[:,:,i],gauss_kern) #Division by the gaussian blur of itself i.e. highpass
f = scaleminmax(percentile(img[:], 0.1), percentile(img[:], 99)) #rescaling image to percentile range
vid[:,:,i] = round.(UInt8,(f.(img)*255)) #conversion back to UInt8
end
end
vid = rand(UInt8,10,10,10) #run once before @profile
flatten(vid);
vid = rand(UInt8,1280,1024,50) #random noise frames for testing
@profile flatten(vid)
ProfileView.view()