千家信息网

人脸识别SDK在网络摄像头中怎么应用

发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,本篇内容介绍了"人脸识别SDK在网络摄像头中怎么应用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1
千家信息网最后更新 2025年01月23日人脸识别SDK在网络摄像头中怎么应用

本篇内容介绍了"人脸识别SDK在网络摄像头中怎么应用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

1.海康SDK接入基本流程

a.初始化并登录验证

        NET_DVR_Init();        NET_DVR_DEVICEINFO_V30 struDeviceInfo = { 0 };        long lUserID = NET_DVR_Login_V30(m_cameraIp, m_cameraPort,            m_cameraUser, m_cameraPwd, &struDeviceInfo);        if (lUserID < 0)        {            NET_DVR_Cleanup();            return false;        }

b.创建线程并注册回调函数

        thread videoThread(&HCNetCamera::getCameraPreview, this);        videoThread.detach();        bool HCNetCamera::getCameraPreview()        {            NET_DVR_CLIENTINFO ClientInfo;            ClientInfo.lChannel = 1; //Channel number 设备通道号            ClientInfo.hPlayWnd = NULL;  //窗口为空,设备SDK不解码只取流            ClientInfo.lLinkMode = 0;    //Main Stream            ClientInfo.sMultiCastIP = NULL;            //预览取流             g_realHandle = NET_DVR_RealPlay_V30(g_cameraUserId, &ClientInfo, fRealDataCallBack, NULL, TRUE);            if (g_realHandle < 0)            {                qDebug() << "NET_DVR_RealPlay_V30 failed! Error number: " << NET_DVR_GetLastError();                return false;            }            return true;        }

c.使用回调接口,获取实时的视频帧数据

        void CALLBACK fRealDataCallBack(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, void *pUser)        {            UNREFERENCED_PARAMETER(lRealHandle);            UNREFERENCED_PARAMETER(pUser);            DWORD dRet = 0;            BOOL inData = FALSE;            switch (dwDataType)            {            case NET_DVR_SYSHEAD:                if (g_cameraPort >= 0)                {                    break; //同一路码流不需要多次调用开流接口                }                if (!PlayM4_GetPort(&g_cameraPort))                {                    break;                }                if (!PlayM4_OpenStream(g_cameraPort, pBuffer, dwBufSize, 1024 * 1024))                {                    dRet = PlayM4_GetLastError(g_cameraPort);                    break;                }                //设置解码回调函数                 if (!PlayM4_SetDecCallBack(g_cameraPort, DecCBFun))                {                    dRet = PlayM4_GetLastError(g_cameraPort);                    break;                }                //打开视频解码                if (!PlayM4_Play(g_cameraPort, NULL))                {                    dRet = PlayM4_GetLastError(g_cameraPort);                    break;                }                dRet = PlayM4_GetLastError(g_cameraPort);                break;            case NET_DVR_STREAMDATA:       //视频流数据            default:                inData = PlayM4_InputData(g_cameraPort, pBuffer, dwBufSize);                while (!inData)                {                    Sleep(10);                    inData = PlayM4_InputData(g_cameraPort, pBuffer, dwBufSize);                    dRet = PlayM4_GetLastError(g_cameraPort);                    OutputDebugString(L"PlayM4_InputData failed \n");                }                break;            }        }
        //解码回调 视频为YUV数据(YV12)        void CALLBACK DecCBFun(long port, char * pBuf, long nSize, FRAME_INFO * pFrameInfo, long nReserved1, long nReserved2)        {            UNREFERENCED_PARAMETER(nReserved1);            UNREFERENCED_PARAMETER(nReserved2);            UNREFERENCED_PARAMETER(nSize);            UNREFERENCED_PARAMETER(port);            //图像格式转换             if (pFrameInfo->nType == T_YV12)            {                {                    lock_guard locker(g_CameraMutex);                    Utils_ns::ImageUtils_ns::YV12ToBGR24_FFMPEG((unsigned char*)pBuf, (unsigned char*)g_curRGBImage->imageData,                        pFrameInfo->nWidth, pFrameInfo->nHeight);//得到全部RGB图像                 }            }        }

d.应用层获取视频帧,这里为了简化操作,只获取了当前帧;大家也可以使用线程安全队列来处理

        int HCNetCamera::getFrame(Mat& image)        {            lock_guard locker(g_CameraMutex);            if (g_curRGBImage && g_curRGBImage->imageData)            {                image = g_curRGBImage;                return 0;            }            return -1;        }        //以下是线程函数的一部分,主要是取帧,然后进行人脸检测        {            lock_guard locker(g_CameraMutex);            int ret = m_camera->getFrame(curFrame);            if (ret == -1)            {                continue;            }        }        ftProcessor->faceDetect(curFrame);

2.基本图像格式转换

目前虹软SDK支持以下几种图像数据格式:

在实际开发过程中一般使用opencv,opencv默认的图像数据格式是BGR24,而我使用的海康摄像头视频编码格式是H264,视频帧数据格式是YV12,因此需要将YV12转换为BGR24 ,同时也会说明下怎么转换为虹软SDK支持的其它格式,主要参考了[2],以下的代码仅供参考。

a.YV12 To BGR24

void yv12ToBGR24(unsigned char* yv12, unsigned  char* bgr24, int width, int height){    unsigned char* y_yv12 = yv12;    unsigned char* v_yv12 = yv12 + width*height;    unsigned char* u_yv12 = yv12 + width*height + width*height / 4;    unsigned char* b = bgr24;    unsigned char* g = bgr24 + 1;    unsigned char* r = bgr24 + 2;    int yIndex, uIndex, vIndex;    for (int i = 0; i < height; ++i)    {        for (int j = 0; j < width; ++j)        {            yIndex = i * width + j;            vIndex = (i / 2) * (width / 2) + (j / 2);            uIndex = vIndex;            *b = (unsigned char)(y_yv12[yIndex] + 1.732446 * (u_yv12[vIndex] - 128));            *g = (unsigned char)(y_yv12[yIndex] - 0.698001 * (u_yv12[uIndex] - 128) - 0.703125 * (v_yv12[vIndex] - 128));            *r = (unsigned char)(y_yv12[yIndex] + 1.370705 * (v_yv12[uIndex] - 128));            b += 3;            g += 3;            r += 3;        }    }}

b.YV12 To I420

void yv12ToI420(unsigned char* yv12, unsigned char* i420, int width, int height){    unsigned char* y_yv12 = yv12;    unsigned char* v_yv12 = yv12 + width*height;    unsigned char* u_yv12 = yv12 + width*height + width*height / 4;    unsigned char* y_i420 = i420;    unsigned char* u_i420 = i420 + width*height;    unsigned char* v_i420 = i420 + width*height + width*height / 4;    memcpy(i420, yv12, width*height);    memcpy(v_i420, v_yv12, width*height / 4);    memcpy(u_i420, u_yv12, width*height / 4);}

c.YV12 To NV21

void yv12ToNV21(unsigned char* yv12, unsigned char* nv21, int width, int height){    unsigned char* y_yv12 = yv12;    unsigned char* v_yv12 = yv12 + width*height;    unsigned char* u_yv12 = yv12 + width*height + width*height / 4;    unsigned char* y_nv21 = nv21;    unsigned char* v_nv21 = nv21 + width*height;    unsigned char* u_nv21 = nv21 + width*height + 1;    memcpy(nv21, yv12, width*height);    for (int i = 0; i < width*height / 4; ++i)    {        *v_nv21 = *v_yv12;        *u_nv21 = *u_yv12;        v_nv21 += 2;        u_nv21 += 2;        ++v_yv12;        ++u_yv12;    }}

d.YV12 To NV12

void yv12ToNV12(unsigned char* yv12, unsigned  char* nv12, int width, int height){    unsigned char* y_yv12 = yv12;    unsigned char* v_yv12 = yv12 + width*height;    unsigned char* u_yv12 = yv12 + width*height + width*height / 4;    unsigned char* y_nv12 = nv12;    unsigned char* u_nv12 = nv12 + width*height;    unsigned char* v_nv12 = nv12 + width*height + 1;    memcpy(nv12, yv12, width*height);    for (int i = 0; i < width*height / 4; ++i)    {        *v_nv12 = *v_yv12;        *u_nv12 = *u_yv12;        v_nv12 += 2;        u_nv12 += 2;        ++v_yv12;        ++u_yv12;    }}

e.YV12 To YUYV

void yv12ToYUYV(unsigned char* yv12, unsigned char* yuyv, int width, int height){    unsigned char* y_yv12 = yv12;    unsigned char* v_yv12 = yv12 + width*height;    unsigned char* u_yv12 = yv12 + width*height + width*height / 4;    unsigned char* y_yuyv = yuyv;    unsigned char* u_yuyv = yuyv + 1;    unsigned char* v_yuyv = yuyv + 3;    for (int i = 0; i < width; ++i)    {        for (int j = 0; j < height; ++j)        {            *y_yuyv = *y_yv12;            y_yuyv += 2;            ++y_yv12;        }    }    for (int j = 0; j < height / 2; ++j)    {        for (int i = 0; i < width / 2; ++i)        {            *u_yuyv = *u_yv12;            *(u_yuyv + width * 2) = *u_yv12;            u_yuyv += 4;            ++u_yv12;            *v_yuyv = *v_yv12;            *(v_yuyv + width * 2) = *v_yv12;            v_yuyv += 4;            ++v_yv12;        }        u_yuyv += width * 2;        v_yuyv += width * 2;    }}

"人脸识别SDK在网络摄像头中怎么应用"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

格式 视频 数据 图像 人脸 摄像头 应用 摄像 函数 线程 网络 内容 实际 接口 更多 知识 设备 过程 海康 支持 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 小学网络安全怎么导入 网络技术基础会计思维导图 广州手机软件开发常见问题 语音指纹属于哪一类网络安全机制 网狐棋牌数据库连接不存在 疫情期间网络安全环节 宝山区市场软件开发业务流程 长沙软件开发实习工资 北京八斗互动网络技术 独立服务器配置 数据库如何查询两个表格数据 北京软件开发工资标准 辽宁专业软件开发价格参考价格 开源信息网络技术有限公司 软件开发库入库条件 云服务器和实体服务器哪个划算 查询数据库中表数量 嘉定区现代化网络技术专业服务 机关开展网络安全工作存在的问题 互联网教育的高科技 山西专业软件开发参考价格 成都网络安全行业集成商群 安徽网络安全工程师简单易学 侠盗猎车手罪恶都市多人服务器 数据库联合查询 警告本网站在国内服务器 怎么把本机电脑设置成服务器 靠谱的财务软件开发定制公司 奉贤区通用软件开发服务产品介绍 小米路由器为什么连不上服务器
0