Skip to content

Commit ab25372

Browse files
committed
* optimize app_vlm, add app thermal256
1 parent 6ab8499 commit ab25372

File tree

6 files changed

+156
-48
lines changed

6 files changed

+156
-48
lines changed
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
id: thermal_camera
2-
name: Thermal Camera
3-
name[zh]: 热成像仪
1+
id: thermal256_camera
2+
name: Thermal256 Camera
3+
name[zh]: 热成像仪256
44
version: 1.0.0
55
icon: assets/thermal.json
66
author: Sipeed Ltd
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"v":"4.8.0","meta":{"g":"LottieFiles AE 1.0.0","a":"Bas Milius","k":"Meteocons, Weather icons, Icon set","d":"Thermometer - Meteocons.com","tc":""},"fr":60,"ip":0,"op":360,"w":512,"h":512,"nm":"thermometer","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"thermometer","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[256,256,0],"ix":2},"a":{"a":0,"k":[256,256,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[4,-24],[32,-24]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[4,-88],[32,-88]],"c":false},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[4,-56],[32,-56]],"c":false},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0,-19.305],[30.928,0],[0,31.389],[-14.496,10.272],[0,0],[-17.673,0],[0,-17.937],[0,0]],"o":[[0,31.389],[-30.928,0],[0,-19.305],[0,0],[0,-17.937],[17.673,0],[0,0],[14.496,10.272]],"v":[[56,79.164],[0,136],[-56,79.164],[-32,32.559],[-32,-103.522],[0,-136],[32,-103.522],[32,32.559]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.796078443527,0.835294127464,0.882352948189,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":6,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":5,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[256,256],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"thermometer-glass","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[255.798,213],[255.798,336]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":30,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[255.985,236],[255.985,336]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":60,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[255.798,213],[255.798,336]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[255.985,236],[255.985,336]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":120,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[255.798,213],[255.798,336]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":150,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[255.985,236],[255.985,336]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":180,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[255.798,213],[255.798,336]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":210,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[255.985,236],[255.985,336]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":240,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[255.798,213],[255.798,336]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":270,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[255.985,236],[255.985,336]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":300,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[255.798,213],[255.798,336]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":330,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[255.985,236],[255.985,336]],"c":false}]},{"t":359,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[255.798,213],[255.798,336]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.937254905701,0.266666680574,0.266666680574,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":24,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,19.882],[19.882,0],[0,-19.882],[-19.882,0]],"o":[[0,-19.882],[-19.882,0],[0,19.882],[19.882,0]],"v":[[292,336],[256,300],[220,336],[256,372]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.937254905701,0.266666680574,0.266666680574,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[256,336],"ix":2},"a":{"a":0,"k":[256,336],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"thermometer-mercury","np":4,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":360,"st":0,"bm":0}],"markers":[]}
Lines changed: 66 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,27 @@
11
from maix import pinmap
22
from maix import i2c, spi
3-
from maix import time
3+
from maix import time, app
44
from maix import display, app, image, camera, nn, tensor, touchscreen
55

6+
old_ai_isp = int(app.get_sys_config_kv("npu", "ai_isp", "0"))
7+
app.set_sys_config_kv("npu", "ai_isp", "0")
8+
9+
ts = touchscreen.TouchScreen()
10+
11+
disp = display.Display()
12+
print("display init done")
13+
print(f"display size: {disp.width()}x{disp.height()}")
14+
cam = camera.Camera(disp.width(), disp.height()) # Manually set resolution
15+
# | 手动设置分辨率
16+
image.load_font("sourcehansans", "/maixapp/share/font/SourceHanSansCN-Regular.otf", size = 20)
17+
# image.set_default_font("sourcehansans")
18+
img = image.Image(320, 240)
19+
img.clear()
20+
init_str = "Initializing.."
21+
init_str_size = image.string_size(init_str, font="sourcehansans")
22+
img.draw_string((img.width() - init_str_size.width())//2, (img.height() - init_str_size.height())//2, "Initializing..", image.COLOR_WHITE, font="sourcehansans")
23+
disp.show(img)
24+
625
PREVIEW_TEMP = True
726
FRAME_NUM = 0
827
Vtemp = 0
@@ -22,17 +41,6 @@
2241
exit(-1)
2342

2443
###############################################################################
25-
disp = display.Display()
26-
print("display init done")
27-
print(f"display size: {disp.width()}x{disp.height()}")
28-
29-
img = image.Image(disp.width(), disp.height())
30-
loading_str = "Initializing..."
31-
loading_str_size = image.string_size(loading_str, scale=1.5)
32-
img.draw_string((disp.width() - loading_str_size.width()) // 2, (disp.height() - loading_str_size.height()) // 2, loading_str, image.COLOR_WHITE, scale=1.5)
33-
disp.show(img)
34-
35-
3644
bus = i2c.I2C(7, i2c.Mode.MASTER)
3745
slaves = bus.scan()
3846
print("find slaves:")
@@ -249,7 +257,6 @@ def scale_to_range(arr, target_min, target_max):
249257
scaled_arr = (arr - original_min) / (original_max - original_min) * (target_max - target_min) + target_min
250258
return scaled_arr
251259

252-
253260
import numpy as np
254261
import cv2
255262
import time
@@ -258,22 +265,28 @@ def scale_to_range(arr, target_min, target_max):
258265
need_exit = 0
259266
hide_hud = False
260267
enable_x3 = True
261-
ts = touchscreen.TouchScreen()
268+
switch_x3 = False
269+
262270

263271
# x3model_name = '/root/models/x3c_192x256.mud'
264-
x3model_name = '/root/models/espcn_x3.mud'
272+
# x3model_name = '/root/models/espcn_x3.mud'
273+
x3model_name = '/root/models/sr3_ir_32.mud'
265274

266275
x3model = nn.NN(x3model_name)
267276
if x3model_name == '/root/models/espcn_x3.mud':
268277
output_layer_name = '19'
269278
elif x3model_name == '/root/models/x3c_192x256.mud':
270279
output_layer_name = 'image_output'
280+
elif x3model_name == '/root/models/sr3_ir_32.mud' or \
281+
x3model_name == '/root/models/sr2.5_ir32.mud' or \
282+
x3model_name == '/root/models/sr2.5_ir48.mud':
283+
output_layer_name = 'output'
271284
else:
272285
raise RuntimeError("Unsupported x3 model")
273286

274287
image_frame = bytearray(width*height*2)
275288
while not app.need_exit():
276-
img = image.Image(disp.width(), disp.height(), bg=image.COLOR_BLACK)
289+
img = cam.read()
277290
img.draw_string(img.width()//2, img.height()//2, "Error: Init Failed.", image.Color.from_rgb(255, 0, 0))
278291
gray = np.array([])
279292
a0 = time.perf_counter()
@@ -297,23 +310,45 @@ def scale_to_range(arr, target_min, target_max):
297310
grayimg = image.cv2image(img_8bit).resize(256, 192)
298311
x3graytensors = x3model.forward_image(grayimg)
299312
x3graytensor = x3graytensors[output_layer_name]
300-
if x3model_name == '/root/models/espcn_x3.mud':
313+
if "espcn_x3.mud" in x3model_name:
301314
x3grayimg_np = tensor.tensor_to_numpy_float32(x3graytensor, copy = False).reshape((576, 768))
302-
elif x3model_name == '/root/models/x3c_192x256.mud':
315+
elif "x3c_192x256.mud" in x3model_name:
316+
x3grayimg_np = tensor.tensor_to_numpy_uint8(x3graytensor, copy = False).reshape((576, 768))
317+
elif "sr3_ir_32.mud" in x3model_name:
303318
x3grayimg_np = tensor.tensor_to_numpy_uint8(x3graytensor, copy = False).reshape((576, 768))
319+
elif "sr2.5_ir32.mud" in x3model_name or "sr2.5_ir48.mud" in x3model_name:
320+
x3grayimg_np = tensor.tensor_to_numpy_uint8(x3graytensor, copy = False).reshape((480, 640))
304321
else:
305322
raise RuntimeError("Unsupported x3 model")
306323
x3grayimg_np = x3grayimg_np.astype(np.uint8)
307324

325+
if switch_x3:
326+
switch_x3 = False
327+
if x3model_name == '/root/models/espcn_x3.mud':
328+
x3model_name = '/root/models/sr3_ir_32.mud'
329+
output_layer_name = 'output'
330+
if x3model_name == '/root/models/sr3_ir_32.mud':
331+
x3model_name = '/root/models/sr2.5_ir32.mud'
332+
output_layer_name = 'output'
333+
elif x3model_name == '/root/models/sr2.5_ir32.mud':
334+
x3model_name = '/root/models/sr2.5_ir48.mud'
335+
output_layer_name = 'output'
336+
elif x3model_name == '/root/models/sr2.5_ir48.mud':
337+
x3model_name = '/root/models/espcn_x3.mud'
338+
output_layer_name = '19'
339+
else:
340+
raise RuntimeError("Unsupported x3 model")
341+
x3model = nn.NN(x3model_name)
308342

309343
img_8bit = cv2.resize(x3grayimg_np, (disp.width(), disp.height()))
310344

311345
img_8bit = scale_to_range(img_8bit, img_8bit_raw_min_max[0], img_8bit_raw_min_max[1]).astype(np.uint8)
312346
else:
313347
img_8bit = cv2.resize(img_8bit, (disp.width(), disp.height()))
314-
348+
print(f"{inspect.currentframe().f_lineno}: 耗时: {time.perf_counter() - a0:.6f} 秒")
315349
# 伪彩色映射(热力图)
316350
color_img = cv2.applyColorMap(img_8bit, cv2.COLORMAP_MAGMA) # BGR格式 COLORMAP_HOT COLORMAP_TURBO
351+
print(f"{inspect.currentframe().f_lineno}: 耗时: {time.perf_counter() - a0:.6f} 秒")
317352
color_img = image.cv2image(color_img)
318353

319354
center_pos = (height//2, width//2)
@@ -393,10 +428,20 @@ def scale_to_range(arr, target_min, target_max):
393428
targetfile = os.path.join(filepath, filename)
394429
np.save(targetfile, gray)
395430
os.fsync(os.open(targetfile, os.O_RDWR))
431+
432+
filename = f"gray_{datetime.now().strftime("%Y%m%d_%H%M%S")}_{FRAME_NUM}.npy"
433+
targetfile = os.path.join(filepath, filename)
434+
np.save(targetfile, gray)
435+
os.fsync(os.open(targetfile, os.O_RDWR))
436+
filename = f"x3gray_{datetime.now().strftime("%Y%m%d_%H%M%S")}_{FRAME_NUM}.npy"
437+
targetfile = os.path.join(filepath, filename)
438+
np.save(targetfile, x3grayimg_np)
439+
os.fsync(os.open(targetfile, os.O_RDWR))
396440
elif x >= 0 and x <= 120 and y >= img.height()-40 and y <= img.height(): # Lo-Res
397441
enable_x3 = False
398442
elif x >= img.width()-120 and x <= img.width() and y >= img.height()-40 and y <= img.height(): # Hi-Res
399443
enable_x3 = True
444+
switch_x3 = True
400445
elif x >= img.width()//2-60 and x <= img.width()//2+60 and y >= 0 and y <= 40: # Hide HUD
401446
hide_hud = True
402447
elif x >= img.width()//2-60 and x <= img.width()//2+60 and y >= img.height()-40 and y <= img.height(): # Show HUD
@@ -410,10 +455,12 @@ def scale_to_range(arr, target_min, target_max):
410455
if not hide_hud:
411456
img.draw_string( 10, 10, "Quit(Holding)", image.Color.from_rgb(255, 0 if need_exit == 0 else 255, 0), scale=2, thickness=2)
412457
img.draw_string( img.width()-140, 10, "Capture", image.Color.from_rgb(255, 0, 0), scale=2, thickness=2)
458+
img.draw_string( img.width()-140, 60,x3model_name[2:], image.Color.from_rgb(255, 0, 0), scale=2, thickness=2)
413459
img.draw_string( 10, img.height()-20, "Lo-Res", image.Color.from_rgb(255, 0, 0), scale=2, thickness=2)
414460
img.draw_string( img.width()-120, img.height()-20, "Hi-Res", image.Color.from_rgb(255, 0, 0), scale=2, thickness=2)
415461
img.draw_string(img.width()//2-60, 10, "Hide HUD", image.Color.from_rgb(255, 0, 0), scale=2, thickness=2)
416462
img.draw_string(img.width()//2-60, img.height()-20, "Show HUD", image.Color.from_rgb(255, 0, 0), scale=2, thickness=2)
417463
disp.show(img)
418464

465+
app.set_sys_config_kv("npu", "ai_isp", str(old_ai_isp))
419466
# /64 - 273.15

projects/app_thermal_camera/assets/thermal.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)