[K10项目分享]行空板K10:变脸相机

2024-9-24 16:20:03 [显示全部楼层]
498浏览
查看: 498|回复: 1

[K10项目分享] 行空板K10:变脸相机

[复制链接]
本帖最后由 TRIM 于 2024-9-24 16:22 编辑


灵感来源

在造物记发现一个帖子:现代科技与中国传统文化京剧变脸相结合
这个项目通过行空板K10的加速度传感器,实现每翻转一次行空板,屏幕上切换不同的脸谱图片

行空板上有人脸检测功能,那为何不做一个变脸相机呢?打开摄像头,检测到人脸,就朝着人脸那覆盖一个脸谱图片。每当“变脸”(人脸消失又出现)时,更换显示的图片。

制作过程

这看上去是一个非常简单的程序,我先做了一个简单的测试程序来试试:

行空板K10:变脸相机图1

马上,我便发现了两大问题:
1. 绘制上去的图片不支持透明通道,脸谱旁会有难看的黑框,如图所示:
行空板K10:变脸相机图2

2. 由于开启了屏幕后,对屏幕的任何操作都会自动刷新,所以,从清屏到重新绘制图片的这个间隔里,并不会显示图片,总体看上去一闪一闪的,达不到预期效果:
(图片先欠着)

发现原有的行空板库无法实现,我便查找了行空板库中使用的图形库:LVGL:一个轻量级嵌入式图形库


首先解决图片的透明通道显示问题!
LVGL是支持透明图片的,但是要在构建图片结构体时将header.cf设为LV_IMG_CF_TRUE_COLOR_ALPHA(带透明通道)
于是我改了改原来的函数
  1. void canvasDrawAlphaImage(int16_t x,int16_t y,int16_t w,int16_t h,const uint8_t* imageData) {
  2.     lv_img_dsc_t image;
  3.     image.header.always_zero = 0;
  4.     image.header.w = w;
  5.     image.header.h = h;
  6.     image.data_size = w * h * 2;
  7.     image.header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA; // 改了这里!
  8.     image.data = imageData,
  9.     k10.canvas->canvasDrawImage(x,y,&image);
  10. }
复制代码

但是,使用此函数,不能直接使用原有的图像数据,需要到LVGL的图片转换工具中,将图片转换成带透明通道的数组:
行空板K10:变脸相机图3
选择与代码中相同的格式,转换,得到了一个c文件!
里面的数组是这样的:
  1. const LV_ATTRIBUTE_MEM_ALIGN LV_ATTRIBUTE_LARGE_CONST LV_ATTRIBUTE_IMG_Y uint8_t y_map[] = {
  2.   #if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8
  3.     /*Pixel format: Alpha 8 bit, Red: 3 bit, Green: 3 bit, Blue: 2 bit*/
  4.     //这里是一组图像数据,但行空板用不着
  5.   #endif
  6.   #if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP == 0
  7.     /*Pixel format: Alpha 8 bit, Red: 5 bit, Green: 6 bit, Blue: 5 bit*/
  8.     //这里是一组图像数据,但行空板也用不着
  9.     #endif
  10.   #if LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP != 0
  11.     /*Pixel format: Alpha 8 bit, Red: 5 bit, Green: 6 bit, Blue: 5 bit  BUT the 2  color bytes are swapped*/
  12.     //这里是一组图像数据,行空板用的是这组,将这组拿出,放到自己代码中即可
  13.   #endif
  14.   #if LV_COLOR_DEPTH == 32
  15.     //这里还有一组图像数据,照样用不着
  16.   #endif
  17. };
复制代码

取出数组,放到代码中,使用新的函数canvasDrawAlphaImage(x,y,w,h,imageData)绘制图片即可!
(把数组传入imageData中)
效果如图:
(图片先欠着)

接着,该解决图片闪烁的问题了!

我发现原来的库里,“清除屏幕”中,会将全屏清除,并且还会刷新一次屏幕。如果绘制图片后,仅擦除对应的区域,并且不刷新,图片的闪烁问题就会得到改善。
另外,原来的库使用xSemaphoreTake()和xSemaphoreGive()防止冲突,如果将图片的擦除和绘制同时在这两个语句之间执行,就不会有其他地方的强制刷新干扰了。

于是,我在原来的canvasDrawAlphaImage函数中加入了清除上一次绘制的图片代码

  1. void canvasDrawAlphaImage(lv_obj_t *_canvas, int16_t x, int16_t y, int16_t XToClean, int16_t YToClean, int16_t w, int16_t h, const uint8_t *imageData)
  2. {
  3.         lv_draw_img_dsc_t img_dsc;
  4.         xSemaphoreTake(xLvglMutex, portMAX_DELAY);
  5.         // 分配缓冲区,里面存放100*138的透明图片数据用于擦除
  6.         lv_color_t *_canvasNullBuf = (lv_color_t *)heap_caps_malloc(100 * 138 * sizeof(lv_color_t) * 8, MALLOC_CAP_SPIRAM); // MALLOC_CAP_SPIRAM;
  7.         assert(_canvasNullBuf);
  8.         memset(_canvasNullBuf, 0, 100 * 138 * sizeof(lv_color_t) * 8);
  9.         // 将指定的区域擦除
  10.         lv_canvas_copy_buf(_canvas, _canvasNullBuf, XToClean, YToClean, 100, 138);
  11.         lv_canvas_set_px_opa(_canvas, XToClean, YToClean, LV_OPA_TRANSP);
  12.         // 创建图像结构体
  13.         lv_img_dsc_t image;
  14.         image.header.always_zero = 0;
  15.         image.header.w = w;
  16.         image.header.h = h;
  17.         image.data_size = w * h * 2;
  18.         image.header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA; // 设置颜色格式:带透明通道
  19.         image.data = imageData,
  20.         // 绘制到指定区域
  21.                 lv_draw_img_dsc_init(&img_dsc);
  22.         lv_canvas_draw_img(_canvas, x, y, &image, &img_dsc);
  23.         // 这里再一并刷新
  24.         lv_task_handler();
  25.         xSemaphoreGive(xLvglMutex);
  26.         // 释放内存
  27.         heap_caps_free(_canvasNullBuf);
  28. }
复制代码

效果完美!
接下来,我还增加了RGB灯的显示,与脸谱的颜色同步变化,既可以让被拍摄者知道目前状态,又可以增添氛围感


效果展示

将行空板对准人脸,人脸上方覆盖脸谱,RGB灯同步颜色。当人脸被遮挡又出现后,切换脸谱及灯效
视频还是先欠着(拿不到手机拍不了视频)


代码下载

提示:
代码可复制到Mind+的“手动编辑”区,可直接上传
代码中的图片大小均为100x138
代码中包含较大的图片数据,如需复制到Mind+,建议选择已格式化图片数据的版本,以免出现卡死的情况
下载附件K10.zip



昊盟  见习技师

发表于 2024-9-25 10:24:39

有有有创意,厉害
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail