Search code examples
pythonnumpyimage-processingmatplotlibjpeg2000

How to read JPG2000 with Python?


I have read several JP2 (JPEG200) images with matplotlib and got numpy arrays with big numbers, exceeding 40000.

Reading code:

img_blue =mpimg.imread('B02.jp2')
img_green =mpimg.imread('B03.jp2')
img_red =mpimg.imread('B04.jp2')

Data is:

[[12290 12694 13034 ...,  1968  2078  2118]
 [12174 12374 12696 ...,  1998  2068  2134]
 [12422 12522 12512 ...,  1990  1972  1990]
 ..., 
 [ 4268  4276  4064 ...,     0     0     0]
 [ 4174  4114  3938 ...,     0     0     0]
 [ 3954  4036  3906 ...,     

What does this data mean?

Does it mean JP2 can contain larger dynamic range? How can I convert it to normal image? Just normalize? What is denominator?

Example of file is here: http://sentinel-s2-l1c.s3.amazonaws.com/tiles/37/U/DB/2017/5/10/0/B02.jp2


Solution

  • Question: Does it mean JP2 can contain larger dynamic range?

    Yes, it does:

    JPEG 2000 supports any bit depth, such as 16- and 32-bit floating point pixel images, and any color space.


    Question: How can I convert it to normal image? Just normalize? What is denominator?

    An HDR image must be mapped to an 8-bit image through tonemapping which, in general, is a non-linear mapping. Different tonemapping curves will produce different results. You can do it with OpenCV as shown in the OpenCV tutorial on HDR image processing:

    # Play with the gamma value to arrive at a result that you like
    tonemap = cv2.createTonemapDurand(gamma=2.2)
    tonemapped_img = tonemap.process(img.copy())
    img_8bit = numpy.clip(tonemapped_img*255, 0, 255).astype('uint8')