加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

項(xiàng)目分享 | 基于ELF 1開(kāi)發(fā)板的遠(yuǎn)程監(jiān)測(cè)及人臉識(shí)別項(xiàng)目

03/14 08:27
3573
閱讀需 19 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

今天非常榮幸地向各位小伙伴分享一個(gè)由共創(chuàng)社成員完成的遠(yuǎn)程監(jiān)測(cè)及人臉識(shí)別項(xiàng)目,該項(xiàng)目依托ELF 1開(kāi)發(fā)板為核心硬件平臺(tái),構(gòu)建了一套完整的視頻監(jiān)控系統(tǒng),并在此基礎(chǔ)上集成了人臉識(shí)別功能。接下來(lái),就為各位小伙伴詳盡展示這一項(xiàng)目的相關(guān)細(xì)節(jié)。

項(xiàng)目實(shí)現(xiàn)步驟

1.視頻監(jiān)控

這一步驟中需要實(shí)現(xiàn)兩個(gè)程序:

(1)在連接攝像頭的ELF 1開(kāi)發(fā)板上實(shí)現(xiàn)一個(gè)服務(wù)器程序:它一邊讀取攝像頭數(shù)據(jù),一邊等待客戶端連接并發(fā)送數(shù)據(jù)??梢杂脙蓚€(gè)線程實(shí)現(xiàn),一個(gè)負(fù)責(zé)采集圖像信息;一個(gè)負(fù)責(zé)等待鏈接,并發(fā)送數(shù)據(jù)。

(2)在手機(jī)或電腦上,編寫(xiě)客戶端程序,它會(huì)從ELF 1開(kāi)發(fā)板上獲得數(shù)據(jù)并顯示出來(lái)。同樣,也可以用兩個(gè)線程來(lái)實(shí)現(xiàn)。一個(gè)負(fù)責(zé)接受數(shù)據(jù),一個(gè)負(fù)責(zé)顯示數(shù)據(jù)。這2個(gè)程序之間,并不需要實(shí)現(xiàn)復(fù)雜的協(xié)議。

MJPG‐streamer是一個(gè)開(kāi)源軟件。MJPG-streamer從Linux UVC兼容的網(wǎng)絡(luò)攝像頭、文件系統(tǒng)或其他輸入插件獲取JPG,并通過(guò)HTTP、RTSP、UDP等將其作為M-JPEG流式傳輸?shù)絎ebBrowser、VLC和其他軟件。

MJPG-streamer 需要很少的CPU和內(nèi)存資源就可以工作,大部分編碼工作都是攝像頭完成的,所以對(duì)于內(nèi)存和性能都有限的嵌入式系統(tǒng)十分適用。

將MJPG-streamer移植并運(yùn)行在ARM板上,在同一局域網(wǎng)內(nèi)的設(shè)備輸入正確的ip地址即可直接觀看到視頻畫(huà)面。對(duì)ARM板的性能要求不高,主頻200MHz的ARM芯片也能實(shí)現(xiàn)。

下載MJPG-streamer:

git clone https://github.com/shrkey/mjpg-streamer

啟動(dòng)MJPG-streamer后,輸入ip地址以及端口號(hào)即可看到攝像頭內(nèi)容如下圖:

同時(shí)后續(xù)人臉識(shí)別功能中需要能夠從視屏流中提取出照片,需要修改MJPG-streamer源碼,使其支持拍照功能。具體修改如下:

修改完成之后只要向有名管道/tmp/webcom寫(xiě)入相應(yīng)的字符串就能實(shí)現(xiàn)拍照功能。

# cd mjpg-streamer-rc63/plugins/output_file
 
# vim output_file.c
 
//在96行 函數(shù) void*worker_thread(void *arg) 體中加入以下代碼:
 
charbuf[10];   //
intflags = 0;   //
intfd_com = 0; //打開(kāi)管道
stop_num = 0; //拍照計(jì)數(shù)
 
if ( access(“/tmp/webcom”,F_OK) < 0 )    //創(chuàng)建有名管道用于接收拍照命令
{
    if ( mkfifo(“/tmp/webcom”,0666 ) < 0)
    {
        Printf(“ photo fifo create failedn”);
    }
}
  fd_com = open (“/tmp/webcom”,O_RDONLY,0666);
  if (fd < 0)
{
    perror (“open the file webcom error”);
}
 
//在while( ok >= 0 && !pglobal->stop){ 后加入
 
if (flags == 0)
{
    while(1)
    {
        reade(fd_com,buf,sizeof(buf));
        if(strncmp(buf,”danger”,6) == 0)    //拍11張照片
        {
            flags = 1;   
            bzero(buf,sizeof(buf));
            break;
        }
    if(strncmp(buf,”one”,3) == 0)   //拍1張照片
    {
        flags = 2;
        bzero(buf,sizeof(buf));
        break;
    }
}
}
 
 
//在if (delay > 0){
 
   usleep(1000*delay);
 
}后加入
 
stop_num++
if(flags == 1)        //判斷拍照的數(shù)量
{
    if ( stop_num > 9)
   {
        stop_num= 0;
        flsgs= 0;    
    }
}
elseif (flags == 2)
{
    stop_num= 0;
    flags= 0;
}

2.人臉檢測(cè)

'haarcascade_frontalface_default.xml'是Opencv中已經(jīng)訓(xùn)練好的人臉?lè)诸惼魑募?。它是基于Haar特征的級(jí)聯(lián)分類器,可以用于檢測(cè)正面的人臉。該文件是通過(guò)大量的正負(fù)樣本訓(xùn)練而成,可以用于人臉檢測(cè)的應(yīng)用中。具體調(diào)用代碼如下:

#! user/bin/python
#- * -coding:UTF-8 - * -
 
import cv2
import numpy as np
 
 
def myfilter(img):
    # 圖像轉(zhuǎn)化為灰度格式
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
 
    # 導(dǎo)入人臉級(jí)聯(lián)分類器引擎,'xml'文件包含訓(xùn)練好的人臉特征
          
    face_cascade=cv2.CascadeClassifier('  
    /home/xuyang/test1/haarcascade_frontalface_default.xml')
    #為防止報(bào)錯(cuò)使用該文件在opencv下的絕對(duì)路徑
    # 用人臉級(jí)聯(lián)分類器引擎進(jìn)行人臉識(shí)別,返回的faces為人臉坐標(biāo)列表
    faces = face_cascade.detectMultiScale(gray)
    
    return faces
 
def myfaces_count(img,faces):    
    count = 0 #人臉計(jì)數(shù)初值
    # 對(duì)每張臉,操作如下
    for (x,y,w,h) in faces:
        '''畫(huà)矩形圈出人臉
        輸入?yún)?shù)依次為:圖片,右上角的點(diǎn)坐標(biāo),矩形大小,線條顏色,寬度
        '''
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),2)
        count += 1 # 累計(jì)人數(shù)
        # 把統(tǒng)計(jì)人數(shù)顯示出來(lái)
        cv2.putText(img,'{}'.format(count),(x,y-7),3,1.2,(0,0,255),2)
 
    return img
 
#打開(kāi)mjpg-streamer視頻流(通過(guò)URL)
#cap = cv2.VideoCapture('http://192.168.106.128:8080/?action=stream')
#打開(kāi)視頻
cap = cv2.VideoCapture('video.mp4')
y = 0
#獲取視頻相關(guān)數(shù)據(jù)以便于保存視頻
width = int(cap.get(3))
height = int(cap.get(4))
fps = cap.get(5)
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
output_file  = 'output_video.mp4'
video_writer = cv2.VideoWriter(output_file,fourcc,fps,(width,height),isColor = True)
while True:
    # 讀取每一幀圖像
    ret, frame = cap.read()
    
    if not ret:
        break
    if y == 0:
        faces = myfilter(frame)  #人臉識(shí)別特征每10次循環(huán)做一次 不然運(yùn)行速度太慢了
    y = y + 1
    if y == 10:
        y =0
    frame = myfaces_count(frame,faces)
    # 在窗口上顯示當(dāng)前幀的圖像
    cv2.imshow("Frame", frame)
    video_writer.write(frame) #保存視頻
    # 按下 'q' 退出循環(huán)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
 
# 關(guān)閉所有窗口及釋放對(duì)象
cap.release()
video_writer.release()
cv2.destroyAllWindows()

3.人臉識(shí)別

鑒于開(kāi)發(fā)板運(yùn)行人臉檢測(cè)模型已經(jīng)有一定的運(yùn)算壓力,同時(shí)為了豐富項(xiàng)目?jī)?nèi)容,人臉識(shí)別部分我們通過(guò)傳送照片在云端完成。

本文通過(guò)libcurl庫(kù)調(diào)用云端API實(shí)現(xiàn)人臉識(shí)別。需要libcurl庫(kù)支持https協(xié)議。要讓LibCurl庫(kù)支持https協(xié)議實(shí)現(xiàn)人臉識(shí)別,就需要安裝移植Openssl這個(gè)庫(kù)。此篇人臉識(shí)別介紹主要目的是判斷兩張人臉圖片的相似程度或者接近程度。安裝移植LibCurl庫(kù)和Openssl庫(kù)不多贅述。

首先是注冊(cè)一個(gè)OCR云識(shí)別平臺(tái)賬號(hào)如圖:

詢對(duì)應(yīng)平臺(tái)的API和接口地址:

下面是調(diào)用人臉識(shí)別API的代碼:

#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h> 
 
typedef unsigned int bool;
#define true 1            
#define false 0
 
 
char buf[1024]={'