Convert JPG image to pixel values

Hi, I’m using Images package to convert JPG image to an array with pixel values. I first loaded the image and then used channelview but I’m getting some weird values in the array. Can someone tell me how to convert this to pixel values?

img = load("IMG_2372.jpg")
img = channelview(img)

Printing img[1,1,1] returns 0.624N0f8.


Don’t jpegs load as an array of RGB pixels? Or do you want black and white?

Those N0f8 values are normalized fixed point Uints. Basically they are an UInt8 but instead of going from 0 to 255 they go from 0.0 to 1.0.

If you want to look at the underlying integer-valued counts, you can use something like this:

imagecounts(img) = (rawview ∘ channelview)(img)

That’ll give a 3 x h x w array of UInt8s that you can convert to something like Int64 for further inspection. I’ve often found myself writing something like this - maybe it should live somewhere in Images.jl? It’s only a sensible transformation for raw image sensor data, but that’s the only type of data I work with, and I imagine other experimentalists are similarly situated.

Why should you have to worry about this? Well, pixels in Images.jl are stored in a packed format with all the color channels adjacent to each other in memory. Taking an individual pixel, we can peer into the underlying storage:

julia> img = rand(RGB{N0f8}, 16, 16);

julia> px = img[1, 1]

julia> dump(px)
  r: N0f8
    i: UInt8 0x0b
  g: N0f8
    i: UInt8 0x20
  b: N0f8
    i: UInt8 0xad

julia> Base.summarysize(px) # number of bytes needed for storage

What’s the advantage of using RGB{N0f8} instead of UInt8 by default? It lets us harness Julia’s method dispatch to make operations on pixels behave as you’d expect them to:

julia> using Statistics

julia> mean(img)

julia> mean(imagecounts(img))

Averaging an image should retain the color channel information, which the former does and the latter doesn’t. Great!

1 Like