瑞芯微板子人脸识别demo展现

13 篇文章 3 订阅
11 篇文章 0 订阅

       我使用的瑞芯微板子是RK3399Pro,这个板子自带有人脸识别功能,于是参看Rockchip_Developer_Guide_RockX_SDK_CN.pdf这个文档进行测试,具体操作手册上还算详细,在此不赘述。

        原始的程序中是可以用摄像头来demo的,但是板子没直接接显示器,你imshow不了呀,无赖之下只能采用网络通讯方式来把结果发送到pc端然后绘制结果,最后显示,在此我采用了python3中的socket来通讯并收发json数据,下面直接上程序吧,先说明下,原始代码写的有些复杂我改写了好些地方。

1、板子服务端程序:

import os
import sys
import time
import sqlite3
import argparse
import numpy as np

from rockx import RockX
import cv2,json,socket


class FaceDB:

    def __init__(self, db_file):
        self.db_file = db_file
        self.conn = sqlite3.connect(self.db_file)
        self.cursor = self.conn.cursor()
        if not self._is_face_table_exist():
            self.cursor.execute("create table FACE (NAME text, VERSION int, FEATURE blob, ALIGN_IMAGE blob)")

    def load_face(self):
        all_face = dict()
        c = self.cursor.execute("select * from FACE")
        for row in c:
            name = row[0]
            version = row[1]
            feature = np.frombuffer(row[2], dtype='float32')
            align_img = np.frombuffer(row[3], dtype='uint8')
            align_img = align_img.reshape((112, 112, 3))
            all_face[name] = {
                'feature': RockX.FaceFeature(version=version, len=feature.size, feature=feature),
                'image': align_img
            }
        return all_face

    def insert_face(self, name, feature, align_img):
        self.cursor.execute("INSERT INTO FACE (NAME, VERSION, FEATURE, ALIGN_IMAGE) VALUES (?, ?, ?, ?)",
                            (name, feature.version, feature.feature.tobytes(), align_img.tobytes()))
        self.conn.commit()

    def _get_tables(self):
        cursor = self.cursor
        cursor.execute("select name from sqlite_master where type='table' order by name")
        tables = cursor.fetchall()
        return tables

    def _is_face_table_exist(self):
        tables = self._get_tables()
        for table in tables:
            if 'FACE' in table:
                return True
        return False


def get_max_face(results):
    max_area = 0
    max_face = None
    for result in results:
        area = (result.box.bottom - result.box.top) * (result.box.right * result.box.left)
        if area > max_area:
            max_face = result
    return max_face


def get_face_feature(image_path):
    img = cv2.imread(image_path)
    img_h, img_w = img.shape[:2]
    ret, results = face_det_handle.rockx_face_detect(img, img_w, img_h, RockX.ROCKX_PIXEL_FORMAT_BGR888)
    if ret != RockX.ROCKX_RET_SUCCESS:
        return None, None
    max_face = get_max_face(results)
    if max_face is None:
        return None, None
    ret, align_img = face_landmark5_handle.rockx_face_align(img, img_w, img_h,
                                                            RockX.ROCKX_PIXEL_FORMAT_BGR888,
                                                            max_face.box, None)
    if ret != RockX.ROCKX_RET_SUCCESS:
        return None, None
    if align_img is not None:
        ret, face_feature = face_recog_handle.rockx_face_recognize(align_img)
        if ret == RockX.ROCKX_RET_SUCCESS:
            return face_feature, align_img
    return None, None


def get_all_image(image_path):
    img_files = dict()
    g = os.walk(image_path)

    for path, dir_list, file_list in g:
        for file_name in file_list:
            file_path = os.path.join(path, file_name)
            if not os.path.isdir(file_path):
                img_files[os.path.splitext(file_name)[0]] = file_path
    return img_files


def import_face(face_db, images_dir):
    image_files = get_all_image(images_dir)
    image_name_list = list(image_files.keys())
    for name, image_path in image_files.items():
        feature, align_img = get_face_feature(image_path)
        if feature is not None:
            face_db.insert_face(name, feature, align_img)
            print('[%d/%d] success import %s ' % (image_name_list.index(name)+1, len(image_name_list), image_path))
        else:
            print('[%d/%d] fail import %s' % (image_name_list.index(name)+1, len(image_name_list), image_path))


def search_face(face_library, cur_feature):
    min_similarity = 10.0
    target_name = None
    target_face = None
    for name, face in face_library.items():
        feature = face['feature']
        ret, similarity = face_recog_handle.rockx_face_similarity(cur_feature, feature)
        if similarity < min_similarity:
            target_name = name
            min_similarity = similarity
            target_face = face
    if min_similarity < 1.0:
        return target_name, min_similarity, target_face
    return None, -1, None


if __name__ == '__main__':

    parser = argparse.ArgumentParser(description="RockX Face Recognition Demo")
    parser.add_argument('-c', '--camera', help="camera index", type=str,
    default='rtsp://admin:abcd.1234@192.168.3.198:664/Streaming/Channels/101?transportmode=unicast&profile=Profile_101')#大华摄像机网络地址
    parser.add_argument('-b', '--db_file', help="face database path", required=True)
    parser.add_argument('-i', '--image_dir', help="import image dir")
    parser.add_argument('-d', '--device', help="target device id", type=str)
    args = parser.parse_args()

    print("camera=", args.camera)
    print("db_file=", args.db_file)
    print("image_dir=", args.image_dir)

    face_det_handle = RockX(RockX.ROCKX_MODULE_FACE_DETECTION, target_device=args.device)
    face_landmark5_handle = RockX(RockX.ROCKX_MODULE_FACE_LANDMARK_5, target_device=args.device)
    face_recog_handle = RockX(RockX.ROCKX_MODULE_FACE_RECOGNIZE, target_device=args.device)
    face_track_handle = RockX(RockX.ROCKX_MODULE_OBJECT_TRACK, target_device=args.device)

    face_db = FaceDB(args.db_file)

    if args.image_dir is not None:
        import_face(face_db, args.image_dir)
        exit(0)

    # load face from database
    face_library = face_db.load_face()
    print("load %d face" % len(face_library))

    cap = cv2.VideoCapture(args.camera)
    dstimhw=(480,640)
    last_face_feature = None


    serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 获取本地主机名
    ip_port=('192.168.3.266',8686)
    # 绑定端口号
    serversocket.bind(ip_port)

    # 设置最大连接数,超过后排队
    serversocket.listen(2)

    while True:
        # Capture frame-by-frame
        ret, frame = cap.read()
        if frame is None:
            cap = cv2.VideoCapture(args.camera)
            ret, frame = cap.read()
            # continue

        starttime=time.time()
        frame=cv2.resize(frame, dstimhw[::-1], None, fx=0, fy=0)

        # 建立客户端连接
        clientsocket, addr = serversocket.accept()

        in_img_h, in_img_w = frame.shape[:2]
        
        ret, results = face_det_handle.rockx_face_detect(frame, in_img_w, in_img_h, RockX.ROCKX_PIXEL_FORMAT_BGR888)
       
        ret, results = face_track_handle.rockx_object_track(in_img_w, in_img_h, 3, results)
        

        itemresults=[]
        index = 0
        for result in results:
            # face align
            ret, align_img = face_landmark5_handle.rockx_face_align(frame, in_img_w, in_img_h,
                                                                     RockX.ROCKX_PIXEL_FORMAT_BGR888,
                                                                     result.box, None)

            # get face feature
            if ret == RockX.ROCKX_RET_SUCCESS and align_img is not None:
                ret, face_feature = face_recog_handle.rockx_face_recognize(align_img)

            target_name=None
            # search face
            if ret == RockX.ROCKX_RET_SUCCESS and face_feature is not None:
                target_name, diff, target_face = search_face(face_library, face_feature)
                # print("target_name=%s diff=%s", target_name, str(diff))

            
            itemresult={}
            itemresult["result"]=result

            if target_name is not None:
                itemresult["target_name"]=target_name
            else:
                itemresult["target_name"]=None

            itemresults.append(itemresult)

        
        if itemresults:
            costtime=time.time()-starttime
            print('costtime={}'.format(costtime))
        itemresults=json.dumps(itemresults)
        sendmsg =itemresults.encode('utf-8')
        clientsocket.send(sendmsg)  #
        clientsocket.close()
            # print('itemresults=',itemresults)
            # break
       
    # When everything done, release the capture
    cap.release()

    face_det_handle.release()

    #python3 rockx_face_recog_server.py -b face.db

2、pc客服端程序:

# 导入 socket、sys 模块
import socket,cv2
import sys,json,time


def drawfacerecogresult(im,itemresults):
    for itemresult in itemresults:
        _, _, detbox, score =itemresult['result']
        target_name=itemresult['target_name']
        cv2.rectangle(im, (detbox[0], detbox[1]), (detbox[2], detbox[3]), (0, 255, 0),2)
        cv2.putText(im,target_name, (detbox[0], detbox[1] - 12),cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0))


if __name__ == "__main__":
    camera='rtsp://admin:abcd.1234@192.168.3.198:664/Streaming/Channels/101?transportmode=unicast&profile=Profile_101'#大华摄像机网络地址
    cap = cv2.VideoCapture(camera)
    dstimhw=(480,640)
    cv2.namedWindow('myim',cv2.WINDOW_NORMAL)
    ip_port = ('192.168.3.266', 8686)

    while True:
        ret, im = cap.read()
        if im is None:
            cap = cv2.VideoCapture(camera)
            ret, im = cap.read()
            # continue
        im = cv2.resize(im, dstimhw[::-1], None, fx=0, fy=0)
        # print(im.shape)
        # 创建 socket 对象
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 连接服务,指定主机和端口
        s.connect(ip_port)
        # 接收小于 1024 字节的数据
        recvmsg = s.recv(4096)
        try:
            recvmsg=recvmsg.decode('utf-8')
            itemresults=json.loads(recvmsg)
        except:
            pass
        if itemresults:
            drawfacerecogresult(im, itemresults)
        cv2.imshow('myim', im)
        cv2.waitKey(1)
    cap.release()
    cv2.destroyAllWindows()
    s.close()

先启动服务端,然后执行客服端,可以显示,但是比较卡顿,画面也有些花的情况,可能是视频流解码跟不上步伐导致,具体还要查找

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于MSP430F5529设计的人脸识别考勤机开发板ALTIUM原理图+PCB+BOM+软件源码, 硬件4层板设计,板子大小128X90mm ,ALTIUM设计的工程文件,包括完整的原理图和PCB文件,可以做为你的设计参考。器件型号列表如下: Library Component Count : 82 Name Description ---------------------------------------------------------------------------------------------------- 0473460001 Connector, Receptacle, Micro-USB Type B, R/A, Bottom Mount SMT 06031C222JAT2A CAP, CERM, 2200 pF, 100 V, +/- 5%, X7R, 0603 06033C104JAT2A CAP, CERM, 0.1 礔, 25 V, +/- 5%, X7R, 0603 06035A180JAT2A CAP, CERM, 18 pF, 50 V, +/- 5%, C0G/NP0, 0603 1715721 Conn Term Block, 2POS, 5.08mm, TH 1902C Standoff, Hex, 0.5"L #4-40 Nylon 2SN-BK-G Shunt, 2mm, Gold plated, Black 4-1437565-1 Switch, Tactile, SPST-NO, 0.05A, 12V, SMT 5000 Test Point, Miniature, Red, TH 5001 Test Point, Miniature, Black, TH 5003 Test Point, Miniature, Orange, TH 5004 Test Point, Miniature, Yellow, TH 5050935-2 Socket, Mini Spring, Tin, TH 74ACT11244PW OCTAL BUFFER / LINE DRIVER WITH 3-STATE OUTPUTS, PW0024A 90120-0122 Header, 100mil, 2x1, Tin, TH ABMM-24.000MHZ-B2-T Crystal, 24.000MHz, 18pF, SMD AssemblyNote These assemblies are ESD sensitive, ESD precautions shall be observed. AssemblyNoteLabel Install lable in silkscreened box after final wash. Text shall be 8 pt. font. Text shall be per the Label Table in PDF schematic. BLM18SG260TN1D 6A Ferrite Bead, 26 ohm @ 100MHz, SMD BLM18SG331TN1D 1.5A Ferrite Bead, 330 ohm @ 100MHz, SMD C0603C225K8PACTU CAP, CERM, 2.2 礔, 10 V, +/- 10%, X5R, 0603 C0603C474K9RACTU CAP, CERM, 0.47 礔, 6.3 V, +/- 10%, X7R, 0603 C0805C106K8PACTU CAP, CERM, 10 礔, 10 V, +/- 10%, X5R, 0805 C0805C225K8PACTU CAP, CERM, 2.2 礔, 10 V, +/- 10%, X5R, 0805 C1608C0G1H100D CAP, CERM, 10 pF, 50 V, +/- 5%, C0G/NP0, 0603 C1608X7R1C105K CAP, CERM, 1 礔, 16 V, +/- 10%, X7R, 0603 C1608X7
OpenMV4是一种基于OpenMV4 H7的板子的开发板,它可以用于人脸识别。通过调用内置的haar模型来识别人脸,并使用find.feature函数返回找到的人脸的感兴趣区域(ROI),从而实现人脸识别。 除此之外,还可以通过修改人脸识别代码,使其能够匹配SD卡中存储的人脸图像,比较特异性差异,并识别出对应的人物。一旦识别到模板人脸,系统可以发送信息给主控,主控再将语音信息发送给SYN6988语音合成模块,通过连接的喇叭播放出来。 此外,还可以使用LBP特征进行人脸识别。通过运行示例代码,我们可以从AT&T faces数据库中提取人脸图像,然后计算每个人脸图像的LBP特征,并与模板人脸进行匹配。通过计算不同人脸之间的距离,可以评估人脸之间的相似性,从而实现人脸识别功能。 请注意,这个实现只是一个论文的概念验证版本,并不能在实际生活条件下很好地工作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [openmv学习之识别人脸](https://blog.csdn.net/weixin_63163242/article/details/128448314)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [基于OpenMV的智能人脸识别语音系统(STM32F407)](https://blog.csdn.net/lu_fresh_student/article/details/123271151)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值