/ examples / mlx90640_pil.py
mlx90640_pil.py
 1  """This example is for Raspberry Pi (Linux) only!
 2     It will not work on microcontrollers running CircuitPython!"""
 3  
 4  import math
 5  import board
 6  import adafruit_mlx90640
 7  from PIL import Image
 8  
 9  FILENAME = "mlx.jpg"
10  
11  MINTEMP = 25.0  # low range of the sensor (deg C)
12  MAXTEMP = 45.0  # high range of the sensor (deg C)
13  COLORDEPTH = 1000  # how many color values we can have
14  INTERPOLATE = 10  # scale factor for final image
15  
16  mlx = adafruit_mlx90640.MLX90640(board.I2C())
17  
18  # the list of colors we can choose from
19  heatmap = (
20      (0.0, (0, 0, 0)),
21      (0.20, (0, 0, 0.5)),
22      (0.40, (0, 0.5, 0)),
23      (0.60, (0.5, 0, 0)),
24      (0.80, (0.75, 0.75, 0)),
25      (0.90, (1.0, 0.75, 0)),
26      (1.00, (1.0, 1.0, 1.0)),
27  )
28  
29  colormap = [0] * COLORDEPTH
30  
31  # some utility functions
32  def constrain(val, min_val, max_val):
33      return min(max_val, max(min_val, val))
34  
35  
36  def map_value(x, in_min, in_max, out_min, out_max):
37      return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
38  
39  
40  def gaussian(x, a, b, c, d=0):
41      return a * math.exp(-((x - b) ** 2) / (2 * c ** 2)) + d
42  
43  
44  def gradient(x, width, cmap, spread=1):
45      width = float(width)
46      r = sum(
47          [gaussian(x, p[1][0], p[0] * width, width / (spread * len(cmap))) for p in cmap]
48      )
49      g = sum(
50          [gaussian(x, p[1][1], p[0] * width, width / (spread * len(cmap))) for p in cmap]
51      )
52      b = sum(
53          [gaussian(x, p[1][2], p[0] * width, width / (spread * len(cmap))) for p in cmap]
54      )
55      r = int(constrain(r * 255, 0, 255))
56      g = int(constrain(g * 255, 0, 255))
57      b = int(constrain(b * 255, 0, 255))
58      return r, g, b
59  
60  
61  for i in range(COLORDEPTH):
62      colormap[i] = gradient(i, COLORDEPTH, heatmap)
63  
64  # get sensor data
65  frame = [0] * 768
66  success = False
67  while not success:
68      try:
69          mlx.getFrame(frame)
70          success = True
71      except ValueError:
72          continue
73  
74  # create the image
75  pixels = [0] * 768
76  for i, pixel in enumerate(frame):
77      coloridx = map_value(pixel, MINTEMP, MAXTEMP, 0, COLORDEPTH - 1)
78      coloridx = int(constrain(coloridx, 0, COLORDEPTH - 1))
79      pixels[i] = colormap[coloridx]
80  
81  # save to file
82  img = Image.new("RGB", (32, 24))
83  img.putdata(pixels)
84  img = img.transpose(Image.FLIP_TOP_BOTTOM)
85  img = img.resize((32 * INTERPOLATE, 24 * INTERPOLATE), Image.BICUBIC)
86  img.save("ir.jpg")