游乐游手机版
首页/AI热点日报/热点详情

开源迪文屏智能眼设计与实现

类型:热点整理2026-07-14
今天要分享的是一个极具趣味性的开源硬件项目——模拟人眼追踪与跟随运动的完整例程。开发者仅借助几张人眼图片素材,便在智能屏上实现了眼珠转动、眨眼动作、人脸识别与实时跟随等丰富功能,整体效果十分逼真生动。下面就来详细拆解一下整个实现过程与技术要点。 01 方案概述与设计思路 1 UI图片素材准备 迪文

今天要分享的是一个极具趣味性的开源硬件项目——模拟人眼追踪与跟随运动的完整例程。开发者仅借助几张人眼图片素材,便在智能屏上实现了眼珠转动、眨眼动作、人脸识别与实时跟随等丰富功能,整体效果十分逼真生动。下面就来详细拆解一下整个实现过程与技术要点。

01 方案概述与设计思路

1. UI图片素材准备

迪文智能屏采用图片素材完成UI开发,这种基于图层的设计方式能够非常便捷地实现各类细腻的显示效果。本次项目所涉及的素材包括不同状态的眼皮、眼珠图片,通过将这些素材灵活组合,即可逼真模拟人眼的多种动作与表情。

2. 界面开发与布局

通过DGUS软件开发界面十分简洁高效,仅需两个图形控件即可完成主体搭建。本例中,工程师选用了一款2.1寸圆形智能屏,其圆形显示区域恰好适合模拟人眼形态,视觉呈现更加自然。

3. 眨眼功能实现原理

眨眼的实现逻辑非常直观:每隔一段时间,让眼皮图片按照顺序轮流显示,从而形成从闭合到张开的完整动画过程。以下是实现眨眼功能的核心代码:

//眨眼动画
void blink_animat(void)
{
    if(blink_flag == 0)
    {
        blink_cnt++;
        if(blink_cnt >= 4)
        {
            blink_flag = 1;
        }
    }
    else
    {
        blink_cnt--;
        if(blink_cnt <= 0)
        {
            blink_flag = 0;
        }     
    }
    write_dgus_vp(0x3000, (u8 *)&blink_cnt, 2);
}

void blink_run()
{
    static u32 run_timer_cnt = 0;
    run_timer_cnt++;
    if(run_timer_cnt >= 2000000)
    {
        run_timer_cnt = 0;
        blink_animat();
        Delay_ms(30);
        blink_animat();
        Delay_ms(30);
        blink_animat();
        Delay_ms(30);
        blink_animat();
        Delay_ms(30);
        blink_animat();
        Delay_ms(30);
        blink_animat();
        Delay_ms(30);
        blink_animat();
        Delay_ms(30);
        blink_animat();
        Delay_ms(30);  
    }
}

代码中通过计时器进行累计计数,当达到预设次数后,连续调用眨眼动画函数,并结合延时控制,完整模拟出人眼从闭合到张开的自然过渡过程。

4. 眼珠自然左右运动实现

眼珠运动机制与眨眼类似,但需要更加精细的时间控制,使眼珠移动轨迹看起来平滑自然,而非生硬跳变。工程师经过多轮调试与优化,最终采用分阶段累加的控制方式,让眼珠在多个位置之间实现平滑过渡。核心代码如下:

//眼珠动画
void eyeball_animat(void)
{
    eyeball_timer_cnt++;
    if(eyeball_timer_cnt < 50)
    {
        eyeball_cnt = 20;
    }
    else if(eyeball_timer_cnt < 51)
    {
        eyeball_cnt = 50;
    }
    else if(eyeball_timer_cnt < 52)
    {
        eyeball_cnt = 80;
    }
    else if(eyeball_timer_cnt < 53)
    {
        eyeball_cnt = 94;
    }
    else if(eyeball_timer_cnt < 103)
    {
        eyeball_cnt = 94;
    }
    else if(eyeball_timer_cnt < 104)
    {
        eyeball_cnt = 80;
    }
    else if(eyeball_timer_cnt < 105)
    {
        eyeball_cnt = 50;
    }
    else if(eyeball_timer_cnt < 106)
    {
        eyeball_cnt = 20;
    }
    else if(eyeball_timer_cnt < 107)
    {
        eyeball_cnt = -10;
    }
    else if(eyeball_timer_cnt < 108)
    {
        eyeball_cnt = -40;
    }
    else if(eyeball_timer_cnt < 158)
    {
        eyeball_cnt = -54;
    }
    else if(eyeball_timer_cnt < 159)
    {
        eyeball_cnt = -40;
    }
    else if(eyeball_timer_cnt < 160)
    {
        eyeball_cnt = -10;
    }
    else if(eyeball_timer_cnt < 161)
    {
        eyeball_cnt = 20;
        eyeball_timer_cnt = 0;
    }
    //左右移动
//    if(eyeball_flag == 0)
//    {
//        eyeball_cnt++;
//        if(eyeball_cnt >= 94)
//        {
//            eyeball_flag = 1;
//        }
//    }
//    else
//    {
//        eyeball_cnt--;
//        if(eyeball_cnt <= -54)
//        {
//            eyeball_flag = 0;
//        }
//    }
    if(eyeball_cnt >= 0)
    {
        eyeball_pos[0] = 0x00;
        eyeball_pos[1] = eyeball_cnt;
    }
    else
    {
        eyeball_pos[0] = 0xFF;
        eyeball_pos[1] = (eyeball_cnt & 0xFF);
    }
    write_dgus_vp(0x3111, (u8 *)&eyeball_pos, 2);
}

void eyeball_run()
{
    static u32 run_timer_cnt = 0;
    run_timer_cnt++;
    if(run_timer_cnt >= 20000)
    {
        run_timer_cnt = 0;
        eyeball_animat();
    }
}

值得注意的是,这里采用了复杂的分段控制策略,而非简单的来回摆动。这种设计使得眼珠的运动轨迹更接近真实人眼的行为模式——先快速扫向一侧,再缓慢回正,随后转向另一侧,整体效果更加自然流畅。被注释掉的代码展示了一种简单的往返方案,但显然逼真度不足,因此被更优的分段控制所取代。

5. 融合ESP32人脸识别,实现眼珠实时跟随

这一功能是整个项目的点睛之笔。当ESP32模块检测到人脸时,眼珠便不再进行随机自主运动,而是根据人脸位置实时调整视线方向,呈现出智能追踪的效果。具体的处理逻辑是:定义一个变量在while循环中持续自增,当自增达到一定数值时,眼珠执行自主运动;当串口接收到外部数据时,该变量立即清零,并仅根据人脸位置信息驱动眼珠移动。关键代码如下:

if(rec_data_timer_cnt < 1000000)
{
    rec_data_timer_cnt++;
}
else
{
    eyeball_run();
}

extern u32 rec_data_timer_cnt;
extern u16 eyeball_timer_cnt;
void Communication_CMD(u8 st)
{
    if((uart[st].Rx_F==1 )&&(uart[st].Rx_T==0))
    {
        rec_data_timer_cnt = 0;
        eyeball_timer_cnt = 0;                                              
#if(Type_Communication==1)
        Describe_8283(st);
#elif(Type_Communication==2)
        Describe_Modbus(st);
#endif
        uart[st].Rx_F=0;
        uart[st].Rx_Num=0;
    }
}

整体逻辑非常清晰:串口收到数据时,立即重置计时器,同时将眼珠动画计时归零,使眼珠迅速切换到跟随模式;如果长时间未收到数据(例如人脸离开摄像头检测范围),计时器自增到设定值后,眼珠便自动恢复自主运动状态,让屏幕始终保持一种灵动的“生命感”。

整个项目巧妙地将图形界面开发、定时动画控制与外部传感器数据通信融为一体,虽然代码量不大,但最终呈现的效果相当惊艳。对于希望利用智能屏打造交互式显示应用的开发者来说,这无疑是一个非常经典的参考案例与学习范例。

来源:https://m.elecfans.com/article/2149233.html

相关热点

继续查看同栏目近期热点。

延伸阅读

补充最近整理过的热点入口。