How do I convert a csv file (16bit (high) color) to image in Python?
Question:
Context:
I built a small thermal camera which can save 70×70 pixels to an SD card.
These pixels have a color value ranging from 0 to 2^16. (Actually certain colors, like black (value 0) are never displayed).
This color is determined like explained here: c++ defined 16bit (high) color
I want to convert this data into an Image with my computer using Python.
An example gathered from another question unfortunately doesn’t yield satisfying results:
bad image
As you can see, the image doesn’t look very good.
My screen shows something like this (note that these two examples were not captured at the same time):
photo
The white frame is not part of the csv-file.
This is the code I have used to generate the image:
I have experimented with the color_max
value but didn’t get good results.
#Python CSV to Image converter
#pip2 install cImage
#pip2 install numpy
from PIL import Image, ImageDraw
from numpy import genfromtxt
color_max = 256
#original 256
g = open('IMAGE_25.TXT','r')
temp = genfromtxt(g, delimiter = ',')
im = Image.fromarray(temp).convert('RGB')
pix = im.load()
rows, cols = im.size
for x in range(cols):
for y in range(rows):
#print str(x) + " " + str(y)
pix[x,y] = (int(temp[y,x] // color_max // color_max % color_max),int(temp[y,x] // color_max % color_max),int(temp[y,x] % color_max))
im.save(g.name[0:-4] + '.jpeg')
This is the csv-file: Image Data
31 represents blue in this case, high values are more red.
Thanks for any help!
Here’s some additional information about my project:
Arduino Thermal Camera with SD card support and image saving capability using the AMG8833 Thermal Imaging sensor made by Panasonic: Datasheet
GitHub (Arduino and Python Code)
Answers:
I think it should look like this:
#!/usr/local/bin/python3
import numpy as np
from PIL import Image
# Read 16-bit RGB565 image into array of uint16
with open('IMAGE_25.TXT','r') as f:
rgb565array = np.genfromtxt(f, delimiter = ',').astype(np.uint16)
# Pick up image dimensions
h, w = rgb565array.shape
# Make a numpy array of matching shape, but allowing for 8-bit/channel for R, G and B
rgb888array = np.zeros([h,w,3], dtype=np.uint8)
for row in range(h):
for col in range(w):
# Pick up rgb565 value and split into rgb888
rgb565 = rgb565array[row,col]
r = ((rgb565 >> 11 ) & 0x1f ) << 3
g = ((rgb565 >> 5 ) & 0x3f ) << 2
b = ((rgb565 ) & 0x1f ) << 3
# Populate result array
rgb888array[row,col]=r,g,b
# Save result as PNG
Image.fromarray(rgb888array).save('result.png')
Context:
I built a small thermal camera which can save 70×70 pixels to an SD card.
These pixels have a color value ranging from 0 to 2^16. (Actually certain colors, like black (value 0) are never displayed).
This color is determined like explained here: c++ defined 16bit (high) color
I want to convert this data into an Image with my computer using Python.
An example gathered from another question unfortunately doesn’t yield satisfying results:
bad image
As you can see, the image doesn’t look very good.
My screen shows something like this (note that these two examples were not captured at the same time):
photo
The white frame is not part of the csv-file.
This is the code I have used to generate the image:
I have experimented with the color_max
value but didn’t get good results.
#Python CSV to Image converter
#pip2 install cImage
#pip2 install numpy
from PIL import Image, ImageDraw
from numpy import genfromtxt
color_max = 256
#original 256
g = open('IMAGE_25.TXT','r')
temp = genfromtxt(g, delimiter = ',')
im = Image.fromarray(temp).convert('RGB')
pix = im.load()
rows, cols = im.size
for x in range(cols):
for y in range(rows):
#print str(x) + " " + str(y)
pix[x,y] = (int(temp[y,x] // color_max // color_max % color_max),int(temp[y,x] // color_max % color_max),int(temp[y,x] % color_max))
im.save(g.name[0:-4] + '.jpeg')
This is the csv-file: Image Data
31 represents blue in this case, high values are more red.
Thanks for any help!
Here’s some additional information about my project:
Arduino Thermal Camera with SD card support and image saving capability using the AMG8833 Thermal Imaging sensor made by Panasonic: Datasheet
GitHub (Arduino and Python Code)
I think it should look like this:
#!/usr/local/bin/python3
import numpy as np
from PIL import Image
# Read 16-bit RGB565 image into array of uint16
with open('IMAGE_25.TXT','r') as f:
rgb565array = np.genfromtxt(f, delimiter = ',').astype(np.uint16)
# Pick up image dimensions
h, w = rgb565array.shape
# Make a numpy array of matching shape, but allowing for 8-bit/channel for R, G and B
rgb888array = np.zeros([h,w,3], dtype=np.uint8)
for row in range(h):
for col in range(w):
# Pick up rgb565 value and split into rgb888
rgb565 = rgb565array[row,col]
r = ((rgb565 >> 11 ) & 0x1f ) << 3
g = ((rgb565 >> 5 ) & 0x3f ) << 2
b = ((rgb565 ) & 0x1f ) << 3
# Populate result array
rgb888array[row,col]=r,g,b
# Save result as PNG
Image.fromarray(rgb888array).save('result.png')