——來自迪文開發(fā)者論壇
本次為大家推薦的迪文開發(fā)者論壇開源項(xiàng)目是一個(gè)很有意思的模擬人眼跟隨運(yùn)動(dòng)的例程。工程師使用幾張人眼圖片素材,實(shí)現(xiàn)了眼珠運(yùn)動(dòng)、眨眼、人臉識(shí)別和跟隨等功能,讓我們一睹為快:
演示視頻
完整開發(fā)資料含迪文屏DGUS工程資料與代碼,可前往迪文開發(fā)者論壇獲?。?a title="" target="" style="font-size: 16px; text-decoration: underline;">http://inforum.dwin.com.cn:20080/forum.php?mod=viewthread&tid=8175&extra=page%3D1
【開源方案簡(jiǎn)介】
1. UI圖片素材
編者注:迪文是基于圖片來完成UI開發(fā)的,可以便捷的實(shí)現(xiàn)各類顯示效果。
2. 界面的開發(fā)
通過DGUS軟件開發(fā)界面比較簡(jiǎn)單,只需要兩個(gè)圖形控件即可。在該例程中,工程師選擇了一款2.1寸圓形智能屏。
3. 實(shí)現(xiàn)眨眼動(dòng)畫
隔一段時(shí)間讓眼皮的圖片輪流顯示一下:
//眨眼動(dòng)畫
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. 實(shí)現(xiàn)眼珠自然左右看
這里和眨眼類似,但是需要比較晶振的控制眼球運(yùn)動(dòng)的時(shí)間,這里經(jīng)過多次調(diào)試,工程師設(shè)計(jì)出了下面這套代碼。
//眼珠動(dòng)畫
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;
}
//左右移動(dòng)
// 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();
}
}
3. 加入ESP32人臉識(shí)別,實(shí)現(xiàn)眼珠跟隨人臉運(yùn)動(dòng)
這里的處理方法是,檢測(cè)到人臉的時(shí)候眼睛自己不運(yùn)動(dòng)了,定義一個(gè)變量在while循環(huán)中自增,當(dāng)自增到一定數(shù)值時(shí),眼珠就自己運(yùn)動(dòng)。當(dāng)串口收到數(shù)據(jù)時(shí),這個(gè)變量就清零,然后只根據(jù)人臉的位置進(jìn)行眼睛的移動(dòng)。主要代碼如下:
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;
}
}