I want to find a maximum of several images: load them into an array and find a maximum along first dimension.
Python code for example:
import cv2
import sys
import numpy as np
imgs_paths = sys.argv[1:]
imgs = list(map(cv2.imread, imgs_paths))
imgs_arr = np.array(imgs, dtype=np.float32)
imgs_max = np.max(imgs_arr, 0)
What I did is the following:
using Colors, Images
function im_to_array(im)
img_array = permutedims(channelview(im), (2,3,1))
img_array = Float32.(img_array)
return img_array
end
imgs = map(Images.load, imgs_paths)
imgs_arr = map(im_to_array, imgs)
a = imgs_arr
b = reshape(cat(a..., dims=1), tuple(length(a), size(a[1])...))
imgs_max = maximum(b, dims=1)
But it's ugly.
I found more simple way to get a maximum (code is below) but it's performance is awful. May be it does not what I'm expecting.
function im_to_array(im)
img_array = permutedims(channelview(im), (2,3,1))
img_array = Float32.(img_array)
return img_array
end
imgs = map(Images.load, imgs_paths)
imgs_arr = map(im_to_array, imgs)
imgs_max = max.(imgs_arr...)
Run time of the first method on 120 FHD images is ~5 seconds on my laptop. And I can't figure out run time of the second method because I was waiting for ~30 minutes and it didn't stop. I'm testing it on Julia 1.4.1
Is there a better way to find a maximum of multiple images?
UPD: here is simple case of what I want:
a = [zeros(Int8, 8, 8, 3), zeros(Int8, 8, 8, 3), zeros(Int8, 8, 8, 3)] # 3 black images with shape 8x8
max.(a) #doesn't work
max.(a...) #works with this simple input but when I test it on 120 FHD images it's extremely slow
UPD2: I tested both methods on a smaller number of images.
function max1(imgs_arr)
a = imgs_arr
b = reshape(cat(a..., dims=1), tuple(length(a), size(a[1])...))
imgs_max = maximum(b, dims=1)
return imgs_max
end
function max2(imgs_arr)
return max.(imgs_arr...)
end
imgs_arr = my_imgs_arrays[1:5]
@time max1(imgs_arr)
@time max2(imgs_arr)
0.247060 seconds (5.29 k allocations: 142.657 MiB)
0.154158 seconds (44.85 k allocations: 26.388 MiB)
imgs_arr = my_imgs_arrays[1:15]
@time max1(imgs_arr)
@time max2(imgs_arr)
0.600093 seconds (72.38 k allocations: 382.923 MiB)
0.769446 seconds (1.24 M allocations: 71.374 MiB)
imgs_arr = my_imgs_arrays[1:25]
@time max1(imgs_arr)
@time max2(imgs_arr)
1.057548 seconds (23.08 k allocations: 618.309 MiB)
5.270050 seconds (151.52 M allocations: 2.329 GiB, 4.77% gc time)
So, more images I use - more slowly it works.