Problems Converting Images from 8-bit to 10-bit

4.9k Views Asked by At

I am trying to convert 8 bit images to 10 bit. I thought it would be as easy as changing the bin values. I've tried to pillow and cv-python:

from PIL import Image
from numpy import asarray
import cv2

path = 'path/to/image'
img = Image.open(path)
data = asarray(img)

newdata = (data/255)*1023 #2^10 is 1024
img2 = Image.fromarray(newdata) #this fails

cv2.imwrite('path/newimage.png, newdata)

While cv2.imwrite successfully writes the new file, it is still encoded as an 8bit image even though bin goes up to 1023.

$ file newimage.png
newimage.png: PNG Image data, 640 x 480, 8-bit/color RGB, non-interlaced

Is there another way in either python or linux that can convert 8-bit to 10-bit?

2

There are 2 best solutions below

0
theastronomist On BEST ANSWER

I found a solution using pgmagick wrapper for python

import pgmagick as pgm

imagePath = 'path/to/image.png'
saveDir = '/path/to/save'

img = pgm.Image(imagePath)
img.depth(10) #sets to 10 bit

save_path = os.path.join(saveDir,'.'.join([filename,'dpx']))
img.write(save_path)
3
Mark Setchell On

Lots of things going wrong here.

  1. You are mixing OpenCV (cv2.imwrite) with PIL (Image.open) for no good reason. Don't do that, you will confuse yourself as they use different RGB/BGR orderings and conventions,

  2. You are trying to store 10-bit numbers in 8-bit vectors,

  3. You are trying to hold 3 16-bit RGB pixels in a PIL Image which will not work as RGB images must be 8-bit in PIL.


I would suggest:

import cv2
import numpy as np

# Load image
im = cv2.imread(IMAGE, cv2.IMREAD_COLOR)

res = im.astype(np.uint16) * 4
cv2.imwrite('result.png', res)