Has anyone been able to fetch frames from a Raspberry Pi camera (i.e. an RPI with a NoIR Pi Cam connected to it with a ribbon cable) at a relatively high frame rate and resolution?
I realize that “relatively high frame rate and resolution” is literally a relative term, but has anyone been able to change the frames’ temporal and spatial resolutions while also using VideoIO.jl?
While it would be golden to achieve this with Julia alone, I’d be happy to hear any success stories you might have.
using VideoIO, UnicodePlots
function benchmark(cam)
img = read(cam)
t = zeros(100)
for i in eachindex(t)
read!(cam, img)
t[i] = Base.time()
end
fps = 1 ./ diff(t)
filter!(<(50), fps) # filter out all the unrealisticly high FPSs
println(histogram(fps))
end
for transcode in (true, false), target_format in (nothing, VideoIO.AV_PIX_FMT_GRAY8)
cam = opencamera(; transcode, target_format)
println("Transcode: $transcode Format: $target_format")
benchmark(cam)
close(cam)
end
My implementation is pretty basic (let me know if you see any possible improvements), but seems to work:
using ImageCore
function create_buffer(w, h)
w2 = 64ceil(Int, w/64) # dimension adjustments to hardware restrictions
h2 = 32ceil(Int, h/32)
nb = Int(w2*h2*3//2) # total number of bytes per frame
return (w2, h2, Vector{UInt8}(undef, nb))
end
struct Camera
o::Base.Process
buff::Vector{UInt8}
img # a reshaped view into the bytes buffer
function Camera(w, h, fps)
w2, h2, buff = create_buffer(w, h)
b = view(buff, 1:w2*h2)
Y = reshape(b, w2, h2)
img = colorview(Gray, normedview(view(Y, 1:w, 1:h)))
cmd = `libcamera-vid -n --framerate $fps --width $w --height $h -t 0 --codec yuv420 -o -` # I imagine that there might be a number of arguments improving things here, or tailoring it to what the user needs/wants
o = open(cmd) # to "close" the camera just `kill(c.o)`
new(o, buff, img)
end
end
function read_frame(c::Camera)
read!(c.o, c.buff) # not sure if `readbytes!` might be better here...
return c.img
end
I got a lot of help from @therealdavidp, a friendly Raspberry Pi Engineer & Forum Moderator on the Raspberry Pi forum (see the actual post here).
To me at least, this highlights the fact that both VideoIO.jl and libcamera can fetch frames from a camera, leaving the question of which is better suited for the job unclear.
I’m excited to see how testing this on the new Raspbian (ARMv8 64-bit) will fair…!