使用C#对华为IPC摄像头二次开发(二)
上一篇我们实现了用SDK登录摄像头并实现预览(https://www.cnblogs.com/wdw984/p/13564195.html),这次我们实现通过SDK调用摄像头本身自带的人脸抓拍功能。
因为篇幅较短,这里直接上代码。
首先我们在MainWindow代码里定义一个安全队列用来存储抓拍到的人脸数据,一个定时取队列数据的定时器,一个人脸抓拍回调事件
private static ConcurrentQueue<CaptureInfo> _concurrentQueue = new ConcurrentQueue<CaptureInfo>();
private static HuaWeiSdkHelper.PfRealDataCallBack _fedRealPlayCallbackFaceCapture;
private Timer _timer;
在窗体加载事件中初始化定时器,用来把抓拍到的数据保存到本地
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
//上一篇文章中的代码省略
_timer = new Timer(300)
{
Enabled = false
};
_timer.Elapsed += Timer_Elapsed;
}
SDK定义了人脸捕获需要定义的Struct和Enum
namespace HuaWeiCamera.Struct
{
/// <summary>
/// 元数据获取相关参数
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct PU_META_DATA
{
/// <summary>
/// 数据容量
/// </summary>
public ushort usCapacity;
/// <summary>
/// 有效数目
/// </summary>
public ushort usValidNumber;
/// <summary>
/// 参考PU_UserData 定义
/// </summary>
public System.IntPtr pstMetaUserData;
}
}
namespace HuaWeiCamera.Struct
{
/// <summary>
/// 元数据用户数据
/// </summary>
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 1)]
public struct PU_UserData
{
/// <summary>
/// 元数据类型
/// </summary>
public LAYER_THREE_TYPE eType;
/// <summary>
/// 用户元数据详情
/// </summary>
public PU_UserData_unMetadata Union1;
}
}
namespace HuaWeiCamera.Struct
{
/// <summary>
/// 用户元数据详情
/// </summary>
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)]
public struct PU_UserData_unMetadata
{
[System.Runtime.InteropServices.FieldOffset(0)]
public int bBoolValue; [System.Runtime.InteropServices.FieldOffset(0)]
public byte charValue; [System.Runtime.InteropServices.FieldOffset(0)]
public byte ucharValue; [System.Runtime.InteropServices.FieldOffset(0)]
public short shortValue; [System.Runtime.InteropServices.FieldOffset(0)]
public ushort ushortValue; [System.Runtime.InteropServices.FieldOffset(0)]
public int IntValue; [System.Runtime.InteropServices.FieldOffset(0)]
public uint uIntValue; [System.Runtime.InteropServices.FieldOffset(0)]
public long longlongValue; [System.Runtime.InteropServices.FieldOffset(0)]
public ulong uLonglongValue;
/// <summary>
/// 元数据二进制颜色
/// </summary>
[System.Runtime.InteropServices.FieldOffset(0)]
public ST_BINARY stBinay;
/// <summary>
/// 元数据矩形
/// </summary>
[System.Runtime.InteropServices.FieldOffset(0)]
public META_RECT_S stRec;
/// <summary>
/// 元数据划点
/// </summary>
[System.Runtime.InteropServices.FieldOffset(0)]
public META_POINT_S stPoint;
/// <summary>
/// 元数据划线
/// </summary>
[System.Runtime.InteropServices.FieldOffset(0)]
public META_LINE_S stLine; [System.Runtime.InteropServices.FieldOffset(0)]
public IntPtr stPolyGon; [System.Runtime.InteropServices.FieldOffset(0)]
public IntPtr stColor; [System.Runtime.InteropServices.FieldOffset(0)]
public IntPtr stHumanAttr;
/// <summary>
/// 人脸信息
/// </summary>
[System.Runtime.InteropServices.FieldOffset(0)]
public META_FACE_INFO stFaceInfo;
/// <summary>
/// 人脸属性
/// </summary>
[System.Runtime.InteropServices.FieldOffset(0)]
public META_FACE_ATTRIBUTES stFaceAttr; [System.Runtime.InteropServices.FieldOffset(0)]
public IntPtr szUserData;
}
}
namespace HuaWeiCamera.Enums
{
/// <summary>
/// 元数据类型以《全网智能接口对接TLV数据详解文档为准》
/// 下载链接:https://support.huawei.com/enterprise/zh/doc/EDOC1100084903
/// </summary>
public enum LAYER_THREE_TYPE
{
/// <summary>
/// 时间戳
/// </summary>
PTS = 0x09000001,
/// <summary>
/// 处理图片宽
/// </summary>
IMG_WIDTH = 0x07000100,
/// <summary>
/// 处理图片高
/// </summary>
IMG_HEIGHT = 0x07000101, // 人脸
/// <summary>
/// 人脸ID
/// </summary>
FACE_ID = 0x07000016,
/// <summary>
/// 人脸全景图片大小
/// </summary>
FACE_PANOPIC_SIZE = 0x07000018,
/// <summary>
/// 人脸抠图产生时间
/// </summary>
FACE_PIC_TIME = 0x08000015,
/// <summary>
/// 人脸抠图设备时区(单位ms 东区为+ 西区为-)
/// </summary>
FACE_PIC_TZONE = 0x08000020,
/// <summary>
/// 人体属性(不建议使用,使用0X070003xx开始的单个人体属性代替)
/// </summary>
HUMAN_FEATURE = 0x10000002,
/// <summary>
/// 人脸属性(不建议使用,使用0X070002xx开始的单个人脸属性代替)
/// </summary>
FACE_FEATURE = 0x11000003,
/// <summary>
/// 全景图片
/// </summary>
PANORAMA_PIC = 0x0A00000A,
/// <summary>
/// 人脸抠图
/// </summary>
FACE_PIC = 0x0A000012,
/// <summary>
/// 人脸抠图kps质量过滤标志位
/// </summary>
FACE_PIC_KPS = 0x07000012,
/// <summary>
/// 人体抠图
/// </summary>
HUMAN_PIC = 0x0A000013,
/// <summary>
/// 人体抠图kps质量过滤标志位
/// </summary>
HUMAN_PIC_KPS = 0x07000013,
/// <summary>
/// 人体抠图中的人体目标框
/// </summary>
HUMAN_PIC_ROI = 0x0B000017,
/// <summary>
/// 人脸全景
/// </summary>
FACE_PANORAMA = 0x0A000017,
/// <summary>
/// 人脸抠图小框位置
/// </summary>
FACE_PIC_POSITION = 0x0B000011,
/// <summary>
/// 人脸位置(实时位置框, 万分比) (开始支持版本:SDC V500R019C30)
/// </summary>
FACE_POS = 0x0B000012,
/// <summary>
/// 人脸数据库中匹配图片
/// </summary>
FACE_MATCH = 0x0A000014,
/// <summary>
/// 名单库中的人脸ID,用来维持特征 record的一致性
/// </summary>
FACELIB_RECORDID = 0x07000017,
/// <summary>
/// 人脸匹配率
/// </summary>
FACE_MATCHRATE = 0x07000020,
/// <summary>
/// 人脸信息,对应数据库中信息
/// </summary>
FACE_INFO = 0x12000001,
/// <summary>
/// 名单库类型
/// </summary>
FACE_LIB_TYPE = 0x07000022,
/// <summary>
/// 名单库名字
/// </summary>
FACE_LIB_NAME = 0x0A000015,
/// <summary>
/// target类型,所有智能的业务类型(开始支持版本:SDC V500R019C30)
/// </summary>
TARGET_TYPE = 0x07000023, /// <summary>
/// 人脸属性, 以FACE开头 0 表示未知 1~n依次对应注释的属性
/// 眼镜{无,有}
/// </summary>
FACE_GLASS = 0X07000200,
/// <summary>
/// 性别{女,男}
/// </summary>
FACE_GENDER = 0X07000201,
/// <summary>
/// 年龄,具体的年龄值1~99
/// </summary>
FACE_AGE = 0X07000202,
/// <summary>
/// 遮档(口罩) {无,是}
/// </summary>
FACE_MOUTHMASK = 0X07000203,
/// <summary>
/// 人脸表情{微笑、愤怒、悲伤、正常、惊讶}
/// </summary>
FACE_EXPRESSION = 0X07000204,
/// <summary>
/// 帽子{无, 有}
/// </summary>
FACE_HAT = 0X07000205,
/// <summary>
/// 胡子{无, 有} (支持版本:SDC 8.0.1)
/// </summary>
FACE_MUSTACHE = 0X07000206,
/// <summary>
/// 发型{长, 短}(支持版本:SDC 8.0.1)
/// </summary>
FACE_HAIR = 0X07000207,
/// <summary>
/// 眼镜{无,普通眼镜,太阳眼镜} (开始支持版本:SDC 8.0.1)
/// </summary>
FACE_GLASS_TYPE = 0X07000208, /// <summary>
/// 人体属性类 以HUMAN开头 0 表示未知 1~n依次对应注释的属性
/// 年龄 {少年,青年,老年}
/// </summary>
HUMAN_AGE = 0X07000300,
/// <summary>
/// 性别{男,女}
/// </summary>
HUMAN_GENDER = 0X07000301,
/// <summary>
/// 上衣款式 {长袖,短袖}
/// </summary>
HUMAN_UPPERSTYLE = 0X07000302,
/// <summary>
/// 上衣颜色 {黑,蓝,绿,白/灰,黄/橙/棕,红/粉/紫}
/// </summary>
HUMAN_UPPERCOLOR = 0X07000303,
/// <summary>
/// 上衣纹理 {纯色,条纹,格子}
/// </summary>
HUMAN_UPPERTEXTURE = 0X07000304,
/// <summary>
/// 下衣款式 {长裤,短裤,裙子}
/// </summary>
HUMAN_LOWSTYLE = 0X07000305,
/// <summary>
/// 下衣颜色 {黑,蓝,绿,白/灰,黄/橙/棕,红/粉/紫}
/// </summary>
HUMAN_LOWERCOLOR = 0X07000306,
/// <summary>
/// 体型{standard, fat, thin}
/// </summary>
HUMAN_SHAPE = 0X07000307,
/// <summary>
/// 口罩{no,yes}
/// </summary>
HUMAN_MOUTHMASK = 0X07000308,
/// <summary>
/// 发型{ long, short }
/// </summary>
HUMAN_HAIR = 0X07000309,
/// <summary>
/// 背包{no,yes}
/// </summary>
HUMAN_BACKPACK = 0X0700030A,
/// <summary>
/// 是否拎东西{no,yes}
/// </summary>
HUMAN_CARRY = 0X0700030B,
/// <summary>
/// 斜挎包{no,yes}
/// </summary>
HUMAN_SATCHEL = 0X0700030C,
/// <summary>
/// 雨伞{no,yes}
/// </summary>
HUMAN_UMBRELLA = 0X0700030D,
/// <summary>
/// 前面背包{no,yes}
/// </summary>
HUMAN_FRONTPACK = 0X0700030E,
/// <summary>
/// 行李箱{no,yes}
/// </summary>
HUMAN_LUGGAGE = 0X0700030F,
/// <summary>
/// 行进方向{forward,backward}
/// </summary>
HUMAN_DIRECT = 0X07000310,
/// <summary>
/// 行进速度{slow,fast}
/// </summary>
HUMAN_SPEED = 0X07000311,
/// <summary>
/// 朝向{frontal, back, leftprofiled, rightprofiled}
/// </summary>
HUMAN_VIEW = 0X07000312,
/// <summary>
/// 眼镜{no,glass, sunglass}
/// </summary>
HUMAN_GLASS = 0X07000313,
/// <summary>
/// 戴帽子{no, yes}
/// </summary>
HUMAN_HAT = 0X07000314, /// <summary>
/// 非机动车属性类 以RIDERMAN开头 0 表示未知 1~n依次对应注释的属性
/// </summary>
RIDERMAN_AGE = 0X07000400, // 年龄 {少年,青年,老年}
RIDERMAN_GENDER = 0X07000401, // 性别{男,女}
RIDERMAN_UPPERSTYLE = 0X07000402, // 上衣款式 {长袖,短袖}
RIDERMAN_UPPERCOLOR = 0X07000403, // 上衣颜色 {黑,蓝,绿,白/灰,黄/橙/棕,红/粉/紫}
RIDERMAN_HELMET = 0X07000404, // 是否戴头盔 {no, yes}
RIDERMAN_HELMETCOLOR = 0X07000405, // 头盔颜色 {黑,蓝,绿,白/灰,黄/橙/棕,红/粉/紫}
APPROACH_LANE_ID = 0x07000605, // 临近车道号(开始支持版本:SDC 8.0.1) // 人体
HUMAN_RECT = 0x0B000013, // 人体位置(实时位置框)
HUMAN_RECT_POSITION = 0x0B000014, // 人体抠图小框位置
SHOULDER_RECT = 0x0B000018, // 头肩位置
SHOULDER_NUM = 0x06000001, // 头肩个数
QUEUE_TIME = 0x06000002, // 排队时长 OBJ_ID = 0x07000021, // 目标ID
OBJ_STATUS = 0x06000022, // 目标状态
OBJ_POS = 0x0B000023, // 目标位置
OBJ_TYPE = 0x06000024, // 目标类型
OBJ_SPEED = 0x0C000025, // 目标速度
OBJ_UPHALF_COLOR = 0x0F000026, // 目标上半部颜色
OBJ_DOWNHALF_COLOR = 0x0F000027, // 目标下半部颜色
RULE_TYPE = 0x07000031, // 规则类型
RULE_LINE_POS = 0x0D000032, // 规则线位置
RULE_LINE_DIR = 0x07000033, // 规则线方向
RULE_AREA_POS = 0x0E000034, // 规则框位置
OBJ_POS_R = 0x0B000035, // 目标位置(相对位置)
OBJ_SPEED_R = 0x0C000036, // 目标速度(相对位置)
RULE_LINE_POS_R = 0x0D000037, // 规则线位置(相对位置)
RULE_AREA_POS_R = 0x0E000038, // 规则框位置(相对位置) LANE_ID = 0x07000002, // 车道号
TRAFFIC_LIGHT_COLOR_ONE = 0x07000106, // 信号灯 1 颜色
TRAFFIC_LIGHT_DIREC_ONE = 0x07000107, // 信号灯1方向
TRAFFIC_LIGHT_COLOR_TWO = 0x07000108, // 信号灯2颜色
TRAFFIC_LIGHT_DIREC_TWO = 0x07000109, // 信号灯2方向
TRAFFIC_LIGHT_COLOR_THREE = 0x07000110, // 信号灯3颜色
TRAFFIC_LIGHT_DIREC_THREE = 0x07000111, // 信号灯3方向
TRAFFIC_LIGHT_COLOR_FOUR = 0x07000112, // 信号灯4颜色
TRAFFIC_LIGHT_DIREC_FOUR = 0x07000113, // 信号灯4方向
VEHICLE_TYPE = 0x07000003, // 车辆类型
VEHICLE_TYPE_EXT = 0x07000406, // 车辆类型扩展(开始支持版本:SDC V500R019C50)
VEHICLE_COLOR = 0x07000004, // 车辆颜色
VEHICLE_DIRECTION = 0x07000005, // 车辆行驶方向
VEHICLE_POS = 0x0B000005, // 车辆位置 (万分比,开始支持版本:SDC V500R019C30)
VEHICLE_POS_ABS = 0x0B000020, // 车辆位置绝对坐标
VEHICLE_POS_COM = 0x0B000021, // 车辆位置相对坐标万分比
PLATE_TYPE = 0x07000006, // 车牌类型
PLATE_POS = 0x0B000007, // 车牌位置(开始支持版本:SDC V500R019C30)
PLATE_POS_ABS = 0x0B000026, // 车牌位置绝对坐标
PLATE_POS_COM = 0x0B000027, // 车牌位置相对坐标万分比
PLATE_CHAR = 0x0A000008, // 车牌字符
PLATE_PIC = 0x0A000009, // 车牌抠图(开始支持版本:SDC V500R019C60)
PLATE_BMP_BIT = 0x0A00000B, // 车牌二值图(开始支持版本:SDC 8.0.1)
PLATE_BMP_BYTE = 0x0A00000C, // 车牌BMP图(开始支持版本:SDC 8.0.1)
PLATE_CONFIDENCE = 0x07000061, // 车牌置信度(开始支持版本:SDC V500R019C60)
PLATE_COLOR = 0x07000062, // 车牌颜色
PLATE_SNAPSHOT_TYPE = 0x07000066, // 车牌抓拍类型
VEHICLE_PIC = 0x0A000067, // 车辆特写图(开始支持版本:SDC V500R019C30)
FACE_FEATURE_PIC = 0x0A000068, // 行人闯红灯人脸特写图(开始支持版本:SDC 8.0.1)
PIC_SNAPSHOT_TIMEMS = 0x09000003, // 抓拍时间(单位ms)(开始支持版本:SDC V500R019C50)
PIC_SNAPSHOT_TIME = 0x07000068, // 抓拍时间
PIC_SNAPSHOT_TZONE = 0x08000069, // 设备时区(单位ms 东区为+ 西区为-)
DEVICE_ID = 0x0A000025, // 设备编号
ROID_ID = 0x0A000026, // 道路编号
DIR_ID = 0x0A000027, // 方向编号
DIR_INFO = 0x0A000028, // 方向信息
REGULATION_CODE = 0x0A000029, // 违章代码字符串(开始支持版本:SDC 8.0.1)
LANE_DESC = 0x070000B2, // 车道描述(开始支持版本:SDC V500R019C30)
LANE_DIR_DESC = 0x070000B3, // 车道方向描述(开始支持版本:SDC V500R019C30)
CAR_DRV_DIR = 0x070000B6, // 车辆行驶方向描述(开始支持版本:SDC V500R019C30)
RADER_CAR_DIR = 0x070000B7, // 雷达测速方向(开始支持版本:SDC V500R019C30)
CUR_SNAP_INDEX = 0x070000B8, // 当前抓拍序列号(开始支持版本:SDC V500R019C30) ITS_COMBINE = 0x01000003, // 违章图片 是否开启合成
ITS_OSD_PIC_OFFSET = 0x06000037, // ITS 六合一卡口osd导致的车辆位置偏移量,正值表示叠加外侧上边缘,
// 负值表示叠加外侧下边缘(开始支持版本:SDC V500R019C30) TRAFFIC_STATISTICS = 0x070000A0, // 车流量统计参数(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_LANE_COUNT = 0x070000A1, // 车流量统计车道数量(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_LANE_INDEX = 0x070000A2, // 车流量统计当前车道(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_VEHICLE_COUNT = 0x070000A3, // 车辆计数(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_AVG_SPEED = 0x070000A4, // 平均速度(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_LANE_TIME_USED_RATIO = 0x070000A5, // 车道时间占有率(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_VEHICLE_DENSITY = 0x070000A6, // 车流密度(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_VEHICLE_HEAD_INTERVAL = 0x070000A7, // 车头时间间隔(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_VEHICLE_HEAD_SPACE_INTERVAL = 0x070000A8, // 车头间隔(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_CONGESTION_DEGREE = 0x070000A9, // 交通状态(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_VEHICLE_TYPE1_COUNT = 0x070000AA, // 大型车数量(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_VEHICLE_TYPE2_COUNT = 0x070000AB, // 中型车数量(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_VEHICLE_TYPE3_COUNT = 0x070000AC, // 小型车数量(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_QUEUE_LENGTH = 0x070000AD, // 排队长度(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_LANE_SPACE_USED_RATIO = 0x070000AE, // 车道空间占有率(开始支持版本:SDC V500R019C30)
ITS_TRAFFIC_LEFT_VEHICLE_COUNT = 0x070000AF, // its左转车数量(开始支持版本:SDC V500R019C30)
ITS_TRAFFIC_STRAIGHT_VHEICLE_COUNT = 0x070000B0, // its直行车数量(开始支持版本:SDC V500R019C30)
ITS_TRAFFIC_RIGHT_VHEICLE_COUNT = 0x070000B1, // its右转车数量(开始支持版本:SDC V500R019C30)
TRAFFIC_STATISTICS_CYCLE = 0x070000B9, // 车流量统计周期(开始支持版本:SDC V500R019C50)
TRAFFIC_STATISTICS_NONMOTOR_COUNT = 0x070000C0, // 非机动车数量(开始支持版本:SDC 8.0.0)
TRAFFIC_STATISTICS_PEDESTRIAN_COUNT = 0x070000C1, // 行人数量(开始支持版本:SDC 8.0.0)
TRAFFIC_STATISTICS_TOTAL_VEHICLE_COUNT = 0x070000C2, // 断面流量(开始支持版本:SDC 8.0.0)
VEHICLE_SPEED = 0x07000075, // 车辆速度
REGULATION_TYPE = 0x07000076, // 违章类型 MFR_MAIN_CALL = 0x06000025, // 主驾驶打电话(开始支持版本:SDC V500R019C30)
MFR_MAIN_BELT = 0x06000026, // 主驾驶安全带(开始支持版本:SDC V500R019C30)
MFR_VICE_EXIST = 0x06000027, // 是否有副驾驶(开始支持版本:SDC V500R019C30)
MFR_VICE_BELT = 0x06000035, // 副驾驶安全带(开始支持版本:SDC V500R019C30)
MFR_YEAR_LOG = 0x06000036, // 年检标(开始支持版本:SDC V500R019C30)
MFR_MAIN_SUN_VISOR = 0x06000030, // 主驾驶遮阳板(开始支持版本:SDC V500R019C30)
MFR_VICE_SUN_VISOR = 0x06000031, // 副驾驶遮阳板(开始支持版本:SDC V500R019C30)
MFR_NAP_KIN_BOX = 0x06000032, // 纸巾盒(开始支持版本:SDC V500R019C30)
MFR_CAR_PENDANT = 0x06000034, // 挂件(开始支持版本:SDC V500R019C30) VEHICLE_BODY_RECT = 0x0B000008, // 车身位置
NOMOTOR_BODY_RECT = 0x0B000009, // 非机动车车身位置
MOTOR_COLOR = 0X07000600, // 非机动车颜色 {黑(1),蓝(2),绿(3),白/灰(4),黄/橙/棕(5),红/粉/紫(6)} (开始支持版本:SDC 8.0.1)
MOTOR_SUNSHADE = 0X07000601, // 是否有遮阳伞{否(1),是(2)} (开始支持版本:SDC 8.0.1)
MOTOR_SUNSHADE_COLOR = 0X07000602, // 遮阳伞颜色 {黑(1),蓝(2),绿(3),白/灰(4),黄/橙/棕(5),红/粉/紫(6)} (开始支持版本:SDC 8.0.1)
MOTOR_MOTOR_CARRY = 0X07000603, // 是否有携带物 {否(1),是(2)} (开始支持版本:SDC 8.0.1)
MOTOR_LICENSE_PLATE = 0X07000604, // 是否有车牌{否(1),是(2)} (开始支持版本:SDC 8.0.1) CAR_PRE_BRAND = 0x0A000007, // 品牌字符 (大 众)(开始支持版本:SDC V500R019C60 )
CAR_SUB_BRAND = 0x0A000022, // 子款字符 (桑塔纳)(开始支持版本:SDC V500R019C60 )
CAR_YEAR_BRAND = 0x0A000024, // 年款字符 (2011)(开始支持版本:SDC V500R019C60 )
VHD_OBJ_ID = 0x09000006, // 机非人ID
CAR_PRE_BRAND_INDEX = 0x06000028, // 品牌字符索引 (大 众)(开始支持版本:SDC V500R019C30 )
CAR_SUB_BRAND_INDEX = 0x06000029, // 子款字符索引 (桑塔纳)(开始支持版本:SDC V500R019C30 ) /// <summary>
/// 设备数
/// </summary>
DEV_CNT = 0x03000070,
/// <summary>
/// 通道号
/// </summary>
CHAN_ID = 0x03000071, /// <summary>
/// 人群密度检测算法人数
/// </summary>
PEOPLE_NUM = 0X07000087,
/// <summary>
/// 人群密度检测算法返回框的地址
/// </summary>
HEADSHOULDER_POS = 0X0B000088,
/// <summary>
/// 人群密度检测算法人群密度
/// </summary>
AREARATIO = 0X07000089,
/// <summary>
/// 跟踪目标id (开始支持版本:SDC V500R019C30)
/// </summary>
TRACK_OBJECT = 0x07000028,
/// <summary>
/// 相机通道号(开始支持版本:SDC V500R019C30)
/// </summary>
CHANNEL_ID = 0x09000078
}
}
定时器事件中处理捕获到的人脸数据(存为本地图片)
#region 处理人脸数据
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (_concurrentQueue.Count == 0)
{
Console.WriteLine(@"暂无人脸图片");
return;
} if (!_concurrentQueue.TryDequeue(out CaptureInfo face))
{
Console.WriteLine(@"读取队列错误");
return;
} if (face._dataFacePic != null && face._dataFacePic.Length > 0)
{
Console.WriteLine(@"人脸存储中");
Task.Run(async () =>
{
var saveFaceFile = Path.Combine($"{AppDomain.CurrentDomain.BaseDirectory}", "jpg", $"face_{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.jpg"); await YuvHelper.Byte2Jpg(face._dataFacePic, saveFaceFile).ConfigureAwait(false);
});
} if (face._dataFacePanorama != null && face._dataFacePanorama.Length > 0)
{
Console.WriteLine(@"全景图片存储中");
Task.Run(async () =>
{
var savePanoramaFile = Path.Combine($"{AppDomain.CurrentDomain.BaseDirectory}", "jpg", $"Panorama_{DateTime.Now:yyyy-MM-dd-HH-mm-ss}.jpg"); await YuvHelper.Byte2Jpg(face._dataFacePanorama, savePanoramaFile).ConfigureAwait(false);
});
}
}
#endregion
在人脸捕获按钮事件中启动人脸捕获回调
#region 人脸捕获
private void ButtonFace_OnClick(object sender, RoutedEventArgs e)
{
if (0 == _ulIdentifyId)
{
HuaWeiSdkHelper.InitAndLogin("192.168.2.250", 6060, "ApiAdmin", "HuaWei123", out _ulIdentifyId,
out string errMsg); if (0 == _ulIdentifyId)
{
MessageBox.Show(errMsg);
return;
}
} var prpInfos = new PU_REAL_PLAY_INFO_S[1];
var clientInfo = new PU_REAL_PLAY_INFO_S
{
ulChannelId = 101,
hPlayWnd = IntPtr.Zero,
enProtocolType = PU_PROTOCOL_TYPE.PU_PROTOCOL_TYPE_TCP,
enStreamType = PU_STREAM_TYPE.PU_VIDEO_MAIN_STREAM,
enVideoType = PU_VIDEO_TYPE.PU_VIDEO_TYPE_META,//这里需要设置为视频类型为元数据
enMediaCryptoType = PU_MEDIA_CRYPTO_TYPE.PU_MEDIA_CRYPTO_NONE,
enMediaCallbackType = PU_MEDIA_CALLBACK_TYPE.PU_MEDIA_CALLBACK_TYPE_META_FRAME,//回调方式为智能元数据
bKeepLive = true,
szLocalIp = null,
szReserved = new byte[32]
};
clientInfo.szReserved[22] = 1;//szReserved[22]表示智能分析数据打包格式 0:XML,1:元数据
prpInfos[0] = clientInfo;
var loginUserId = _ulIdentifyId;
IntPtr pUsrData = (IntPtr)loginUserId;
_fedRealPlayCallbackFaceCapture = FaceCaptureReaplayCallbackWithMetaFrame;
var ulRealHandleCapture = HuaWeiSdkHelper.IVS_PU_RealPlay(_ulIdentifyId, prpInfos, _fedRealPlayCallbackFaceCapture, ref pUsrData);
if (0 == ulRealHandleCapture)
{
MessageBox.Show(HuaWeiSdkHelper.GetLastErrorInfo());
return;
} _timer.Enabled = true;
} #region 人脸捕获数据回调 private static void FaceCaptureReaplayCallbackWithMetaFrame(IntPtr szBuffer, int lSize, IntPtr pUsrData)
{
var ptrstMetaTargetData = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PU_META_DATA)));
try
{
var bRet = HuaWeiSdkHelper.IVS_User_GetMetaData(szBuffer, lSize, LAYER_TWO_TYPE.TARGET, ref ptrstMetaTargetData);
if (false == bRet)
{
return;
} if ((IntPtr)0 == ptrstMetaTargetData)
{
return;
} //将数据从非托管内存块封送到新分配的指定类型的托管对象
var pstMetaData = (PU_META_DATA)Marshal.PtrToStructure(ptrstMetaTargetData, typeof(PU_META_DATA));
//数据处理
if (0 == pstMetaData.usValidNumber)
{
return;
} PU_UserData pstMetaUserData = new PU_UserData();
int nSizeofPuUserDataInC = Marshal.SizeOf(pstMetaUserData);
byte[] dataFacePic = null;//人脸图片,如果捕获到人脸,会转成byte[]数组填充进来
byte[] dataFacePanorama = null;//检测到人脸的时候的全景图片
var faceFeature = new META_FACE_ATTRIBUTES();//附加的人脸上的数据
bool hasFaceFeature = false;
int target = 0;
for (int uIndex = 0; uIndex < pstMetaData.usValidNumber; ++uIndex)
{
IntPtr ptr2 = new IntPtr(pstMetaData.pstMetaUserData.ToInt32() + nSizeofPuUserDataInC * uIndex);
pstMetaUserData = (PU_UserData)Marshal.PtrToStructure(ptr2, typeof(PU_UserData));//数据转成元用户数据结构
switch (pstMetaUserData.eType)
{
case LAYER_THREE_TYPE.TARGET_TYPE:
target = pstMetaUserData.Union1.IntValue;
break;
case LAYER_THREE_TYPE.FACE_PIC://人脸抠图
dataFacePic = new byte[pstMetaUserData.Union1.stBinay.ulBinaryLenth];
//使用地址data来获取需要的内存块中的数据
Marshal.Copy(pstMetaUserData.Union1.stBinay.pBinaryData, dataFacePic, 0, (int)pstMetaUserData.Union1.stBinay.ulBinaryLenth);
break;
case LAYER_THREE_TYPE.FACE_PANORAMA://人脸全景
dataFacePanorama = new byte[pstMetaUserData.Union1.stBinay.ulBinaryLenth];
//使用地址data来获取需要的内存块中的数据
Marshal.Copy(pstMetaUserData.Union1.stBinay.pBinaryData, dataFacePanorama, 0, (int)pstMetaUserData.Union1.stBinay.ulBinaryLenth);
break;
case LAYER_THREE_TYPE.FACE_FEATURE://人脸属性
hasFaceFeature = true;
faceFeature = pstMetaUserData.Union1.stFaceAttr;
break;
default:
break;
}
}
if ((int)Target.FaceCapture == target)
{
CaptureInfo info =
new CaptureInfo
{
_dataFacePanorama = dataFacePanorama,
_dataFacePic = dataFacePic,
_faceFeature = faceFeature,
_hasFaceFeature = hasFaceFeature
};
_concurrentQueue.Enqueue(info);//加入到待处理队列中
}
HuaWeiSdkHelper.IVS_User_FreeMetaData(out ptrstMetaTargetData);//释放数据占用空间
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
finally
{
Marshal.FreeHGlobal(ptrstMetaTargetData);//释放内存
}
} #endregion
#endregion
在程序退出时,去释放资源
private void MainWindow_OnClosed(object sender, EventArgs e)
{
_isExit = true;
if (_timer.Enabled) _timer.Enabled = false;
if (_ulRealHandleId > 0)
{
HuaWeiSdkHelper.IVS_PU_StopRealPlay(_ulIdentifyId, _ulRealHandleId);
}
if (_ulIdentifyId > 0)
{
HuaWeiSdkHelper.IVS_PU_Logout(_ulIdentifyId);
}
HuaWeiSdkHelper.IVS_PU_Cleanup();
VideoFileStream.Close();
}
SDK把人脸抓拍注册成功后,摄像头本身带的有人脸识别算法,捕获到人脸后,会把数据回调给注册事件,注册事件中根据回调中给的人脸数据的内存地址取出数据,实例化成C#的数据结构,把图片转换成byte[]写入到队列里,定时处理队列时取出数据写成图片,即完成了摄像头人脸识别抓拍(有的摄像头带人脸比对算法,可直接进行人脸比对)。
使用C#对华为IPC摄像头二次开发(二)的更多相关文章
- 使用C#对华为IPC摄像头二次开发(一)
开发环境: 操作系统:Win10 x64专业版2004 开发工具:VS2019 16.7.2 目标平台:x86 首先去下载IPC SDK(点击下载,需要华为授权账户.) 新建一个WPF的项目,Fram ...
- Linux基于webRTC的二次开发(二) 实现远程桌面共享
webRTC中的desktop_capture模块提供了捕获桌面和捕获窗口的相关功能,而实现远程桌面共享功能需要将desktop_capture捕获的画面作为peerconnection的视频源,下面 ...
- EasyDSS点播与直播服务器软件-二次开发接口对接说明示列
EasyDSS流媒体服务器软件,提供一站式的转码.点播.直播.时移回放服务,极大地简化了开发和集成的工作.其中,点播版本主要包含:上传.转码.分发.直播版本,主要包含:直播.录像, 直播支持RTMP输 ...
- EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器软件二次开发接口对接说明示列
EasyDSS相关功能 EasyDSS流媒体服务器软件,提供一站式的转码.点播.直播.时移回放服务,极大地简化了开发和集成的工作.其中,点播版本主要包含:上传.转码.分发.直播版本主要包含:直播.录像 ...
- Jmeter二次开发——基于Java请求
简述 这近几年,越来越多非http的协议需要进行性能测试,包括不仅限于各类rpc.mq.缓存等.对于这些协议,市面上可能没有现成的工具可以直接使用,这个时候,我们可以自己动手,通过编写相应的JavaS ...
- Linux进程间通信IPC学习笔记之同步二(SVR4 信号量)
Linux进程间通信IPC学习笔记之同步二(SVR4 信号量)
- Linux进程间通信IPC学习笔记之同步二(Posix 信号量)
Linux进程间通信IPC学习笔记之同步二(Posix 信号量)
- Linux下onvif客户端关于ipc摄像头的搜索
设备搜索:要访问一个IPC摄像头,或者说要调用IPC摄像头提供的WEB服务接口,就要先知道其IP地址,这就是设备发现的过程,或者叫设备搜索的过程.IPC摄像头用的是239.255.255.250(端口 ...
- 基于EasyNVR二次开发实现自己的摄像机IPC/NVR无插件化直播解决方案
在之前的博客中<基于EasyNVR实现RTSP/Onvif监控摄像头Web无插件化直播监控>,我们已经比较多的描述EasyNVR所实现的功能,这些也在方案地址:http://www.eas ...
- 基于EasyNVR摄像机网页无插件直播服务二次开发实现H5播放页面的简单集成方案
我们通常在构架一套视频SaaS应用的过程中,将平台设计为3层:视频硬件层(视频源).视频能力平台(vPaaS).视频应用平台(vSaaS),视频硬件包括各种IPC.NVR.编码器等视频生成设备,vPa ...
随机推荐
- 80x86汇编—寻址方式
文章目录 术语解释 8086寻址方式 直数寻址 寄存器间接寻址 寄存器相对寻址 基址变址寻址 比例变址寻址方式 基址比例变址寻址方式 术语解释 EA:有效地址,通过段地址:偏移地址组合得到的Effec ...
- apisix~authz-keycloak插件介绍
参考:https://apisix.apache.org/docs/apisix/plugins/authz-keycloak/ kc插件源码梳理及原理说明 如果只是进行keycloak颁发的toke ...
- SimpleHTTPServer模块详解
SimpleHTTPServer实现文件的展示和下载 可以用python2.7直接启动一个进程.以命令执行的当前目录为页面根目录,如果不存在index.html,默认展示当前目录的所有文件. pyth ...
- MyBatis抛出BindingException异常可能是你忘了配置资源拷贝
最近博主在搭建Mybatis项目时遇到了一问题,在一切配置妥当后,开始运行测试代码,但是此时控制台无情的抛出了异常: 开始寻找问题根源 咦?难道是我哪里写错,我的第一反应是我的xml配置文件哪里写错了 ...
- Django——自定义前端上传文件
from django.db import models class Mytb(models.Model): file = models.FileField(upload_to='uploads/') ...
- SwiftUI(一)- VStack、HStack、ZStack布局
SwiftUI是什么 懒得写,直接找了一篇博客: 初识 SwiftUI 三种布局 SwiftUI包括三种布局: VStack: 纵向布局,默认居中对齐 HStack: 横向布局,默认居中对齐 ZSta ...
- 【Azure App Service】.NET代码实验App Service应用中获取TLS/SSL 证书 (App Service Windows)
在使用App Service服务部署业务应用,因为有些第三方的接口需要调用者携带TLS/SSL证书(X509 Certificate),在官方文档中介绍了两种方式在代码中使用证书: 1) 直接使用证书 ...
- golang开发 gorilla websocket的使用
很多APP都需要主动向用户推送消息,这就需要用到长连接的服务,即我们通常提到的websocket,同样也是使用socket服务,通信协议是基本类似的,在go中用的最多的.也是最简单的socket服务就 ...
- Java 中 hashCode 和 equals 方法是什么?它们和 == 各有什么区别?
在 Java 中,hashCode 和 equals 方法都是 Object 类的方法.它们的作用分别如下: hashCode 方法返回对象的哈希码,用于支持基于哈希表的集合,如 HashMap.Ha ...
- umask永久修改用户创建文件权限
Linux里永久设置用户创建文件权限的配置文件是/etc/profile.可以在该文件中添加umask命令来设置默认权限.具体操作步骤如下: 打开/etc/profile文件:sudo vi /etc ...