1.百度智能云接口及简介
云平台接口
接口技术文档:
网页功能演示:
2.人脸检测属性分析项目示例
硬件平台: ubuntu18.04、USB免驱摄像头 图像渲染: SDL库 开发语言: C语言
3.摄像头应用框架V4L2示例
#include #include #include #include #include #include "video.h" /*摄像头应用编程框架*/ int Video_Init(u8 *dev,int video_fd,struct video *video_info) { /*1.打开摄像设备文件*/ video_fd=open(dev,O_RDWR); if(video_fd<0)return -1; /*2.图像数据格式*/ struct v4l2_format video_format; memset(&video_format,0,sizeof(struct v4l2_format)); video_format.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//捕获格式 video_format.fmt.pix.width=800; video_format.fmt.pix.height=480; video_format.fmt.pix.pixelformat=V4L2_PIX_FMT_YUYV; if(ioctl(video_fd,VIDIOC_S_FMT,&video_format))return -2; video_info->width=video_format.fmt.pix.width; video_info->height=video_format.fmt.pix.height; printf("图像尺寸:%d * %dn",video_info->width,video_info->height); /*3.申请空间*/ struct v4l2_requestbuffers video_requestbuffers; memset(&video_requestbuffers,0,sizeof(struct v4l2_requestbuffers)); video_requestbuffers.count=4;//缓冲区个数 video_requestbuffers.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//V4L2捕获框架格式 video_requestbuffers.memory=V4L2_MEMORY_MMAP;//内存映射 if(ioctl(video_fd,VIDIOC_REQBUFS,&video_requestbuffers))return -3; printf("缓冲区个数:%dn",video_requestbuffers.count); /*4.将缓冲映射到进程空间*/ int i=0; struct v4l2_buffer video_buffer; for(i=0;immap_size=video_buffer.length;/*映射大小*/ video_info->mmapbuf[i]=mmap(NULL,video_buffer.length,PROT_READ|PROT_WRITE,MAP_SHARED,video_fd,video_buffer.m.offset); } /*5.将缓冲区添加到采集队列*/ for(i=0;i
4.调用百度人家属性分析接示例
// libcurl库下载链接:https://curl.haxx.se/download.html // jsoncpp库下载链接:https://github.com/open-source-parsers/jsoncpp/ const static char * request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"; char faceDetect_result[1024]; char faceDetect_result[1024]; /** * 人脸检测与属性分析 * @return 调用成功返回0,发生错误返回其他错误码 */ int faceDetect(char *json_result, const char *access_token,const char *image_base64) { //std::string url = request_url + "?access_token=" + access_token; char url[1024]; snprintf(url,sizeof(url),"%s?access_token=%s",request_url,access_token); CURL *curl = NULL; CURLcode result_code; int is_success=0; char iamge[1024*1024]; snprintf(iamge,sizeof(iamge),"{"image":"%s","image_type":"BASE64","face_field":"age,beauty,gender,glasses,eye_status,emotion,race,mask,facetype"}",image_base64); curl = curl_easy_init(); if (curl) { curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_POST, 1); struct curl_slist *headers = NULL; headers = curl_slist_append(headers, "Content-Type:application/json;charset=UTF-8"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_POSTFIELDS,iamge); result_code = curl_easy_perform(curl); FILE *outfile; outfile = fopen("test.cmd", "wb"); curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile); result_code=curl_easy_perform(curl); fclose(outfile); if (result_code != CURLE_OK) { fprintf(stderr, "curl_easy_perform() failed: %s",curl_easy_strerror(result_code)); is_success = 1; return is_success; } strcpy(json_result,faceDetect_result); curl_easy_cleanup(curl); is_success = 0; } else { fprintf(stderr, "curl_easy_init() failed."); is_success = 1; } return is_success; }
5.base64图片编码示例
static const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; char * base64_encode( const unsigned char * bindata, char * base64, int binlength ) { int i, j; unsigned char current; for ( i = 0, j = 0 ; i < binlength ; i += 3 ) { current = (bindata[i] >> 2) ; current &= (unsigned char)0x3F; base64[j++] = base64char[(int)current]; current = ( (unsigned char)(bindata[i] << 4 ) ) & ( (unsigned char)0x30 ) ; if ( i + 1 >= binlength ) { base64[j++] = base64char[(int)current]; base64[j++] = '='; base64[j++] = '='; break; } current |= ( (unsigned char)(bindata[i+1] >> 4) ) & ( (unsigned char) 0x0F ); base64[j++] = base64char[(int)current]; current = ( (unsigned char)(bindata[i+1] << 2) ) & ( (unsigned char)0x3C ) ; if ( i + 2 >= binlength ) { base64[j++] = base64char[(int)current]; base64[j++] = '='; break; } current |= ( (unsigned char)(bindata[i+2] >> 6) ) & ( (unsigned char) 0x03 ); base64[j++] = base64char[(int)current]; current = ( (unsigned char)bindata[i+2] ) & ( (unsigned char)0x3F ) ; base64[j++] = base64char[(int)current]; } base64[j] = '�'; return base64; } int base64_decode( const char * base64, unsigned char * bindata ) { int i, j; unsigned char k; unsigned char temp[4]; for ( i = 0, j = 0; base64[i] != '�' ; i += 4 ) { memset( temp, 0xFF, sizeof(temp) ); for ( k = 0 ; k < 64 ; k ++ ) { if ( base64char[k] == base64[i] ) temp[0]= k; } for ( k = 0 ; k < 64 ; k ++ ) { if ( base64char[k] == base64[i+1] ) temp[1]= k; } for ( k = 0 ; k < 64 ; k ++ ) { if ( base64char[k] == base64[i+2] ) temp[2]= k; } for ( k = 0 ; k < 64 ; k ++ ) { if ( base64char[k] == base64[i+3] ) temp[3]= k; } bindata[j++] = ((unsigned char)(((unsigned char)(temp[0] << 2))&0xFC)) | ((unsigned char)((unsigned char)(temp[1]>>4)&0x03)); if ( base64[i+2] == '=' ) break; bindata[j++] = ((unsigned char)(((unsigned char)(temp[1] << 4))&0xF0)) | ((unsigned char)((unsigned char)(temp[2]>>2)&0x0F)); if ( base64[i+3] == '=' ) break; bindata[j++] = ((unsigned char)(((unsigned char)(temp[2] << 6))&0xF0)) | ((unsigned char)(temp[3]&0x3F)); } return j; }
6.JOSN数据格式解析示例
/*josn数据解析*/ int Josn_Get(const char *buff,struct Faceinfo *face_info) { /*创建cJSON对象*/ cJSON *root=cJSON_CreateObject(); char *p=strstr(buff,"{"error_code""); root=cJSON_Parse(p);/*载入JSON数据*/ if(root==NULL)return -1; /*2.解析字段*/ cJSON *item; int i=0; item=cJSON_GetObjectItem(root,"error_code"); if(item) { printf("error_code:%dn",item->valueint); if(item->valueint)return -2; } item=cJSON_GetObjectItem(root,"error_msg"); if(item) { printf("error_code:%sn",item->valuestring); } item=cJSON_GetObjectItem(root,"result"); if(item) { cJSON *obj; obj=cJSON_GetObjectItem(item, "face_num"); printf("face_num:%dn",obj->valueint); item=cJSON_GetObjectItem(item,"face_list"); if(item) { int arraysize=cJSON_GetArraySize(item);/*获取数组成员个数*/ for(i=0;ivaluestring); obj=cJSON_GetObjectItem(array_item,"location"); if(obj) { cJSON *data; data=cJSON_GetObjectItem(obj, "left"); printf("left:%fn",data->valuedouble); face_info->x=data->valuedouble; data=cJSON_GetObjectItem(obj, "top"); printf("top:%fn",data->valuedouble); face_info->y=data->valuedouble; data=cJSON_GetObjectItem(obj, "width"); printf("width:%fn",data->valuedouble); face_info->w=data->valuedouble; data=cJSON_GetObjectItem(obj, "height"); printf("height:%fn",data->valuedouble); face_info->h=data->valuedouble; data=cJSON_GetObjectItem(obj, "face_probability"); } obj=cJSON_GetObjectItem(array_item,"face_probability"); //printf("probability=%dn",obj->valueint); obj=cJSON_GetObjectItem(array_item,"age"); //printf("年龄=%dn",obj->valueint); face_info->age=obj->valueint; obj=cJSON_GetObjectItem(array_item,"beauty"); if(obj!=NULL) { //printf("颜值=%fn",obj->valuedouble); face_info->beauty=obj->valuedouble; } obj=cJSON_GetObjectItem(array_item,"gender");//性别 if(obj) { cJSON *data; data=cJSON_GetObjectItem(obj,"type"); if(strcmp(data->valuestring,"male")==0) { //printf("性别:男n"); strcpy(face_info->gender,"男"); } else if(strcmp(data->valuestring,"female")==0) { //printf("性别:女n"); strcpy(face_info->gender,"女"); } } obj=cJSON_GetObjectItem(array_item,"glasses");//是否带眼镜 if(obj) { cJSON *data; data=cJSON_GetObjectItem(obj,"type"); if(strcmp(data->valuestring,"none")==0) { //printf("眼镜:无n"); strcpy(face_info->glasses,"无"); } else if(strcmp(data->valuestring,"common")==0) { //printf("眼镜:普通眼镜n"); strcpy(face_info->glasses,"普通眼镜"); } else if(strcmp(data->valuestring,"sun")==0) { //printf("眼镜:墨镜n"); strcpy(face_info->glasses,"墨镜"); } } obj=cJSON_GetObjectItem(array_item,"emotion");//表情 if(obj) { cJSON *data; data=cJSON_GetObjectItem(obj,"type"); if(strcmp(data->valuestring,"angry")==0) { //printf("表情:愤怒n"); strcpy(face_info->emotion,"愤怒"); } else if(strcmp(data->valuestring,"disgust")==0) { //printf("表情:厌恶n"); strcpy(face_info->emotion,"厌恶"); } else if(strcmp(data->valuestring,"fear")==0) { //printf("表情:恐惧n"); strcpy(face_info->emotion,"恐惧"); } else if(strcmp(data->valuestring,"happy")==0) { //printf("表情:高兴n"); strcpy(face_info->emotion,"高兴"); } else if(strcmp(data->valuestring,"sad")==0) { //printf("表情:伤心n"); strcpy(face_info->emotion,"伤心"); } else if(strcmp(data->valuestring,"surprise")==0) { //printf("表情:惊讶n"); strcpy(face_info->emotion,"惊讶"); } else if(strcmp(data->valuestring,"neutral")==0) { //printf("表情:无表情n"); strcpy(face_info->emotion,"无表情"); } else if(strcmp(data->valuestring,"pouty")==0) { //printf("表情:噘嘴n"); strcpy(face_info->emotion,"噘嘴"); } else if(strcmp(data->valuestring,"grimace")==0) { //printf("表情:鬼脸n"); strcpy(face_info->emotion,"鬼脸"); } } obj=cJSON_GetObjectItem(array_item,"mask");//是否带口罩 if(obj) { cJSON *data; data=cJSON_GetObjectItem(obj,"type"); //printf("是否带口罩:%dn",data->valueint); if(data->valueint)strcpy(face_info->mask,"是"); else strcpy(face_info->mask,"否"); } obj=cJSON_GetObjectItem(array_item,"face_type"); if(obj) { cJSON *data; data=cJSON_GetObjectItem(obj,"type"); if(strcmp(data->valuestring,"human")==0) { printf("真实人脸n"); } else if(strcmp(data->valuestring," cartoon")==0) { printf("卡通人脸n"); } } } } } cJSON_Delete(root);//释放空间 return 0; }
7.调用SDL库图像渲染
int main() { struct Faceinfo face_info={0}; int w,h; /*初始化摄像头*/ video_fd=Video_Init(CAMERA_DEV,video_fd,&video_info); if(video_fd<=0) { printf("摄像头初始化失败,res=%dn",video_fd); return 0; } /*TTF 初始化*/ TTF_Init(); /*打开字库*/ TTF_Font *ttffont=TTF_OpenFont("方正粗黑宋简体.ttf",30); if(ttffont==NULL) { printf("字库打开失败n"); return 0; } SDL_Color color={255,0,128,255};/*字体颜色 RGBA*/ /*创建窗口 */ SDL_Window *window=SDL_CreateWindow("人脸检测分析", SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,800,480,SDL_WINDOW_ALLOW_HIGHDPI|SDL_WINDOW_SHOWN); SDL_GetWindowSize(window,&w,&h); /*创建渲染器*/ SDL_Renderer *render=SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED); /*清空渲染器*/ SDL_RenderClear(render); printf("图像尺寸:%d * %dn",video_info.width,video_info.height); /*创建纹理*/ SDL_Texture*sdltext=SDL_CreateTexture(render,SDL_PIXELFORMAT_RGB24,SDL_TEXTUREACCESS_STREAMING,video_info.width,video_info.height); /*创建摄像头采集线程*/ u8 *rgb_data=malloc(video_info.height*video_info.width*3); rgb_buff=malloc(video_info.height*video_info.width*3);//保存RGB颜色数据 u8 *jpg_data=malloc(video_info.height*video_info.width*3);//保存RGB颜色数据 u8 *imagebase64_data=malloc((video_info.height*video_info.width*3)*8/6);//保存RGB颜色数据 int jpg_size; //printf("size=%dn",video_info.mmap_size); video_flag=1;/*摄像头采集标志*/ pthread_t pthid; pthread_create(&pthid,NULL,Video_CollectImage, NULL); bool quit=true; SDL_Event event; SDL_Rect rect; int display_stat=1; char buff[100]; while(quit) { while(SDL_PollEvent(&event))/*事件监测*/ { if(event.type==SDL_QUIT)/*退出事件*/ { quit=false; video_flag=0; pthread_cancel(pthid);/*杀死指定线程*/ continue; } else if(event.type==SDL_MOUSEBUTTONDOWN)/*点击事件*/ { if(event.button.button==SDL_BUTTON_LEFT)/*左键*/ { pthread_mutex_lock(&fastmutex);//互斥锁上锁 pthread_cond_wait(&cond,&fastmutex); memcpy(rgb_data,rgb_buff,video_info.height*video_info.width*3); pthread_mutex_unlock(&fastmutex);//互斥锁解锁 jpg_size=rgb_to_jpeg(video_info.width,video_info.height,video_info.height*video_info.width*3,rgb_data,jpg_data, 80);//RGB转JPG base64_encode(jpg_data, imagebase64_data, jpg_size); char json_result[1024]; int res=0; res=faceDetect(json_result,access_token,imagebase64_data); FILE *fp=fopen("test.cmd","rb"); if(fp==NULL)continue; struct stat statbuf; int size=0; stat("test.cmd", &statbuf); char *data=malloc(statbuf.st_size+1); size=fread(data,1,statbuf.st_size,fp); data[size]='�'; fclose(fp); //SDL_ttfDisplayFont(10,10,window,ttffont,45,color,"字库测试",render); display_stat=0; if(Josn_Get(data,&face_info)) { display_stat=1; continue; } printf("年龄:%dn",face_info.age); printf("颜值:%fn",face_info.beauty); printf("性别:%sn",face_info.gender); printf("表情:%sn",face_info.emotion); printf("是否戴眼镜:%sn",face_info.glasses); printf("是否戴口罩:%sn",face_info.mask); SDL_SetRenderDrawColor(render,255,0,0, 255);// 透明值 SDL_Rect rect; rect.x=face_info.x; rect.y=face_info.y; rect.w=face_info.w; rect.h=face_info.h; SDL_UpdateTexture(sdltext,NULL,rgb_data, video_info.width*3); SDL_RenderCopyEx(render, sdltext,NULL,NULL,0,NULL,SDL_FLIP_HORIZONTAL); SDL_RenderDrawRect(render,&rect); int y=80; snprintf(buff,sizeof(buff),"年龄:%d",face_info.age); size=SDL_ttfDisplayFont(w-300,y,window,ttffont,30,color,buff,render); y+=size; snprintf(buff,sizeof(buff),"颜值:%.2f",face_info.beauty); size=SDL_ttfDisplayFont(w-300,y,window,ttffont,30,color,buff,render); y+=size+10; snprintf(buff,sizeof(buff),"性别:%s",face_info.gender); size=SDL_ttfDisplayFont(w-300,y,window,ttffont,30,color,buff,render); y+=size+10; snprintf(buff,sizeof(buff),"表情:%s",face_info.emotion); size=SDL_ttfDisplayFont(w-300,y,window,ttffont,30,color,buff,render); y+=size+10; snprintf(buff,sizeof(buff),"是否戴眼镜:%s",face_info.glasses); size=SDL_ttfDisplayFont(w-300,y,window,ttffont,30,color,buff,render); y+=size+10; snprintf(buff,sizeof(buff),"是否戴口罩:%s",face_info.mask); size=SDL_ttfDisplayFont(w-300,y,window,ttffont,30,color,buff,render); SDL_RenderPresent(render); // 渲染 free(data); } else if(event.button.button==SDL_BUTTON_RIGHT)/*右键*/ { printf("右键按下n"); display_stat=1; } } } if(!video_flag) { quit=false; continue; } pthread_mutex_lock(&fastmutex);//互斥锁上锁 pthread_cond_wait(&cond,&fastmutex); memcpy(rgb_data,rgb_buff,video_info.height*video_info.width*3); pthread_mutex_unlock(&fastmutex);//互斥锁解锁 SDL_UpdateTexture(sdltext,NULL,rgb_data, video_info.width*3); //SDL_RenderCopy(render, sdltext, NULL,NULL); // 拷贝纹理到渲染器 SDL_RenderCopyEx(render, sdltext,NULL,NULL,0,NULL,SDL_FLIP_HORIZONTAL); if(display_stat)SDL_RenderPresent(render); // 渲染 } SDL_DestroyTexture(sdltext);/*销毁纹理*/ SDL_DestroyRenderer(render);/*销毁渲染器*/ SDL_DestroyWindow(window);/*销毁窗口 */ SDL_Quit();/*关闭SDL*/ pthread_mutex_destroy(&fastmutex);/*销毁互斥锁*/ pthread_cond_destroy(&cond);/*销毁条件变量*/ free(rgb_buff); free(rgb_data); }
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !