Linux下基于百度智能云平台人脸识别

1.百度智能云接口及简介

https://cloud.baidu.com/product/face
在这里插入图片描述
  接口技术文档:
在这里插入图片描述

2.人脸检测属性分析项目示例

硬件平台: ubuntu18.04、USB免驱摄像头
图像渲染: SDL库
开发语言: C语言

  效果展示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.摄像头应用框架V4L2示例

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#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 * %d\n",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("缓冲区个数:%d\n",video_requestbuffers.count);
	/*4.将缓冲映射到进程空间*/
	int i=0;
	struct v4l2_buffer video_buffer;
	for(i=0;i<video_requestbuffers.count;i++)
	{
		memset(&video_buffer,0,sizeof(struct v4l2_buffer));
		video_buffer.index=i;//
		video_buffer.memory=V4L2_MEMORY_MMAP;//内存映射
		video_buffer.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//V4L2捕获框架格式
		if(ioctl(video_fd,VIDIOC_QUERYBUF,&video_buffer))return -4;
		video_info->mmap_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<video_requestbuffers.count;i++)
	{
		memset(&video_buffer,0,sizeof(struct v4l2_buffer));
		video_buffer.index=i;//
		video_buffer.memory=V4L2_MEMORY_MMAP;//内存映射
		video_buffer.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//V4L2V4L2捕获框架格式
		if(ioctl(video_fd,VIDIOC_QBUF,&video_buffer))return -5;
	}     
	/*开启摄像头*/
	int type=V4L2_BUF_TYPE_VIDEO_CAPTURE;//V4L2V4L2捕获框架格式
	if(ioctl(video_fd,VIDIOC_STREAMON,&type))
	{
		printf("摄像头开启失败\n");
		return -6;
	}
	return video_fd;    
}

4.调用百度人家属性分析接示例与base64图像编码

#include "connect.h"
// libcurl库下载链接:https://curl.haxx.se/download.html
// jsoncpp库下载链接:https://github.com/open-source-parsers/jsoncpp/
char platform_data[2048];
size_t callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
    strncpy(platform_data,(char *)ptr, size * nmemb);
    printf("\n--------------------------------\n");
    printf("platform_data=%s\n",platform_data);
    return size * nmemb;
}
/**
 * 人脸检测与属性分析
 * @return 调用成功返回0,发生错误返回其他错误码
 */
int faceDetect(const char *request_url,const char *access_token,const char *image_base64,const char *format_data) 
{   
    char url[200];
    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*2];
    snprintf(iamge,sizeof(iamge),"{\"image\":\"%s\",\"image_type\":\"BASE64\",%s",image_base64,format_data);                                                                                      
                                                                    
    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url);/*存放http地址*/
        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);//设置HTTP头字段的数组
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS,iamge);/*向服务器post出去一段数据*/
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback); //设置回调函数
        result_code=curl_easy_perform(curl);//访问数据
        if (result_code != CURLE_OK) {
            fprintf(stderr, "curl_easy_perform() failed: %s",curl_easy_strerror(result_code));
            is_success = 1;
            return is_success;
        }
        curl_easy_cleanup(curl);
        is_success = 0;	
    } else {
        fprintf(stderr, "curl_easy_init() failed.");
        is_success = 1;
    }
    return is_success;
}
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] = '\0';
    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] != '\0' ; 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;
}

5.人脸注册

/*注册人脸*/
int face_register(const char *image_base64,char *format_data,SDL_Window *window,SDL_Renderer *rend,TTF_Font *ttffont)
{
    SDL_Color color={0,0,0,255};/*字体颜色 RGBA*/
    char data[50];
    char name[50];
    char phone[20];
    SDL_Rect rect;
    rect.x=640;
    rect.y=0;
    rect.w=160;
    rect.h=300;
    SDL_SetRenderDrawColor(rend, 255, 255, 255, 255);
    SDL_RenderFillRect(rend, &rect);/*清空指定区域*/
    int text1_width,text2_width;
	SDL_SetRenderDrawColor(rend, 255, 0, 0, 255);
    text1_width=SDL_ttfDisplayFont(650,100,window,ttffont,14,color,"姓名:",rend);
	SDL_RenderDrawLine(rend,650+(text1_width&0xff),103+(text1_width>>8),800-10,103+(text1_width>>8));
    text2_width=SDL_ttfDisplayFont(650,150,window,ttffont,14,color,"手机号:",rend);
	SDL_SetRenderDrawColor(rend, 0, 0, 0, 255);
	SDL_RenderDrawLine(rend,650+(text2_width&0xff),153+(text1_width>>8),800-10,153+(text2_width>>8));
    SDL_RenderPresent(rend); // 渲染
    SDL_Event event;
    int x=(text1_width&0xff)+ 650;
    int y=100;
	int x0=x;
    int font_size=0;
    char font_w[100];/*保存每个字符的宽度*/
    int cnt=0;
    int stat=0;
    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_KEYDOWN)//键盘事件
            {
                if(event.key.keysym.sym==SDLK_RETURN)/*回车键*/
				{
					data[cnt]='\0';
                    cnt=0;
                    stat++;
                    if(stat!=2)
                    {
                        printf("请输入手机号\n");
                        strncpy(name,data,sizeof(name));
                        printf("name=%s\n",name);
						SDL_SetRenderDrawColor(rend, 255, 0, 0, 255);
						SDL_RenderDrawLine(rend,650+(text2_width&0xff),153+(text1_width>>8),800-10,153+(text2_width>>8));
						SDL_RenderPresent(rend);
                        cnt=0;/*下标清零*/
                        y+=50;
                        x=655+(text2_width&0xff);
                        x0=x;
                    }
                    else if(stat==2)
                    {
                        strncpy(phone,data,sizeof(phone));
                        printf("phone=%s\n",phone);
                        quit=false;
                        continue;
                    }
				}
                else if(event.key.keysym.sym==SDLK_TAB)/*TAB键*/
                {
                    stat++;
                    data[cnt]='\0';
                    if(stat==1)
                    {
                       strncpy(name,data,sizeof(name));
                       printf("name=%s\n",name);
					   SDL_SetRenderDrawColor(rend, 255, 0, 0, 255);
					   SDL_RenderDrawLine(rend,650+(text2_width&0xff),153+(text1_width>>8),800-10,153+(text2_width>>8));
					   SDL_RenderPresent(rend);
                    }
                    else if(stat==2)
                    {
                        strncpy(phone,data,sizeof(name));
                        printf("phone=%s\n",phone);
                    }
                    cnt=0;/*下标清零*/
                    y+=50;
                    x=655+(text2_width&0xff);
                    x0=x;
                }
                else if(event.key.keysym.sym==SDLK_BACKSPACE)/*退格键*/
                {
                    if(cnt>0)
                    {
                        cnt--;
                        x0-=font_w[cnt];
                    }
                    SDL_Rect rect;
                    rect.x=x0;
                    rect.y=y;
                    rect.w=font_w[cnt];
                    rect.h=(font_size>>8)&0xff;
                    SDL_SetRenderDrawColor(rend, 255, 255, 255, 255);
					SDL_RenderFillRect(rend, &rect);
					SDL_RenderPresent(rend);
                }
            }
            else if(event.type == SDL_TEXTINPUT)/*文本输入*/
            {
                font_size=SDL_ttfDisplayFont(x0,y,window,ttffont,12,color,event.text.text,rend);
                data[cnt]=event.text.text[0];
                x0+=font_size&0xff;
                font_w[cnt++]=font_size&0xff;/*保存每个字符宽度*/
                SDL_RenderPresent(rend);
            }
        }
    }
    if(stat==2)quit=true;
    int res=0;
    snprintf(format_data,512,"\"group_id\":\"wbyq\",\"user_id\":\"%s\",\"user_info\":\"%s\",\"quality_control\":\"LOW\",\"liveness_control\":\"NORMAL\"}",phone,name);
    faceDetect(request_url,access_token,image_base64,format_data);
    if(res)return -1;/*访问服务器失败*/
    /*
        {"error_code":0,"error_msg":"SUCCESS","log_id":9465001899925,"timestamp":1641801995,"cached":0,"result":{"face_token":"66d2d1512ec57835ec4ef25ed95bec77",
        "location":{"left":265.38,"top":251.49,"width":201,"height":192,"rotation":0}}}
    
    */
    if(JsonData_analysis(platform_data,"\"error_msg\"",format_data))return -3;/*注册失败*/
    printf("format_data=%s\n",format_data);
    if(strcmp(format_data,"SUCCESS"))return -4;/*注册失败*/
    return 0;
}

6.人脸识别和主函数

/*
token值获取:

#!/bin/bash
curl -i -k 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=【百度云应用的AK】&client_secret=【百度云应用的SK】'
*/  
const static char * request_url = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add"; //人脸注册
const static char * face_search= "https://aip.baidubce.com/rest/2.0/face/v3/search"; //人脸搜索
const static char *access_token="24.3839bfa18d023457841cd083bfcd9057d55.2592000.1644480673.282335-25497897";       
#define CAMERA_DEV "/dev/video0" //摄像头设备节点
int video_fd;/*摄像头描述符*/
struct video video_info;/*摄像头结构体信息*/
u8 *rgb_buff=NULL;
int video_flag;/*摄像头采集线程状态*/
pthread_t pthid;/*线程ID*/
pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;//互斥锁
pthread_mutex_t fastmutex2 = PTHREAD_MUTEX_INITIALIZER;//互斥锁
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;//条件变量
typedef enum
{
	false=0,
	true,
}bool;
bool quit=true;
/*ttf显示字符串*/
int SDL_ttfDisplayFont(int x,int y,SDL_Window *window,TTF_Font *ttffont,int size,SDL_Color color,const char *str,SDL_Renderer *rend);
void *Video_CollectImage(void *arg);/*图像采集线程*/
u8 JsonData_analysis(u8* buff,u8 *flag,u8 *data);/*JSON数据解析*/
int Josn_faceSearch(const char *buff,char *user_info);/*人脸搜索数据解析*/
int face_register(const char *image_base64,char *format_data,SDL_Window *window,SDL_Renderer *rend,TTF_Font *ttffont);/*注册人脸*/
int main()
{
    int w,h;
    
    SDL_Event event;
    /*TTF 初始化*/
	TTF_Init();
    /*打开字库*/
	TTF_Font *ttffont=TTF_OpenFont("方正粗黑宋简体.ttf",30);
	if(ttffont==NULL)
	{
		printf("字库打开失败\n");
		return 0;
	}  
    /*创建窗口 */
	SDL_Window *window=SDL_CreateWindow("人脸识别", SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,800,480,SDL_WINDOW_ALLOW_HIGHDPI|SDL_WINDOW_SHOWN);
    if(window==NULL)
    {
        printf("创建创建失败\n");
        return 0;
    }
    SDL_GetWindowSize(window,&w,&h);
    /*创建渲染器*/
	SDL_Renderer *render=SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED);
    int cnt=200;
    /*检查设备头设备*/
    SDL_Color color={255,255,255,255};/*字体颜色 RGBA*/
    while(quit)
    {
        while(SDL_PollEvent(&event))/*事件监测*/
        {
            if(event.type==SDL_QUIT)/*退出事件*/
            {
                quit=false;
                continue;
            }
        }
        SDL_Delay(10);
        cnt++;
        if(cnt>=200)
        {
            cnt=0;
             /*初始化摄像头*/
            video_fd=Video_Init(CAMERA_DEV,video_fd,&video_info);
            if(video_fd<=0)
            {
				SDL_RenderClear(render);
                printf("摄像头打开失败,请接入摄像头\n");
                SDL_ttfDisplayFont(-1,200,window,ttffont,30,color,"摄像头打开失败,请检查摄像头设备!",render);
                SDL_RenderPresent(render); // 渲染
            }
            else break;
        }
    }   
    if(quit==false)
    {
        SDL_DestroyRenderer(render);/*销毁渲染器*/
        SDL_DestroyWindow(window);/*销毁窗口 */
        SDL_Quit();/*关闭SDL*/
        return 0;
    }
    SDL_SetRenderDrawColor(render,255, 255, 255,255);
    /*清空渲染器*/
	SDL_RenderClear(render);
    printf("设备打开成功\n");
    printf("图像尺寸:%d * %d\n",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);/*base64编码后数据*/
    int jpg_size;/*jpg图像大小*/
    video_flag=1;/*摄像头采集标志*/
    int  display_stat=1;
    int count=0;
    pthread_create(&pthid,NULL,Video_CollectImage, NULL);
    SDL_Surface *imgsurface=IMG_Load("button.jpg");
    if(imgsurface==NULL)
    {
        printf("图标加载失败\n");
        pthread_cancel(pthid);/*杀死指定线程*/
        quit=false;
    }
    SDL_Texture *imgsdltext=SDL_CreateTextureFromSurface(render, imgsurface);
    SDL_Rect rect;
    SDL_Rect image_rect;
    rect.x=w-imgsurface->w-30;/*注册按钮坐标位置x*/
    rect.y=h-3*imgsurface->h-20;/*注册按钮坐标位置y*/
    SDL_Rect rect2;
    rect2.x=w-imgsurface->w-30;/*注册按钮坐标位置x*/
    rect2.y=h-2*imgsurface->h;/*注册按钮坐标位置y*/
    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)/*点击事件*/
            {
                SDL_Color color={255,0,0,255};/*字体颜色 RGBA*/
                if(event.button.button==SDL_BUTTON_LEFT)/*左键*/
                {
                    char format_data[512];
                    if((event.motion.x>=rect.x && event.motion.x<=rect.x+imgsurface->w) && 
                        (event.motion.y>=rect.y && event.motion.y<=rect.y+imgsurface->h))
                    {
                        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);
                        base64_encode(jpg_data, imagebase64_data, jpg_size);
                        //face_register(imagebase64_data,format_data);
                        int res=face_register(imagebase64_data,format_data,window,render,ttffont);
                        if(res)
                        {
                            SDL_Rect rect={640,200,160,100};
							SDL_SetRenderDrawColor(render, 255, 255, 255, 255);
                            SDL_RenderFillRect(render,&rect);/*矩形填充*/
                            snprintf(format_data,sizeof(format_data),"注册失败");
                        }
                        else
                        {
                            SDL_Rect rect={640,200,160,100};
							SDL_SetRenderDrawColor(render, 255, 255, 255, 255);
                            SDL_RenderFillRect(render,&rect);/*矩形填充*/
                            snprintf(format_data,sizeof(format_data),"注册成功");
                        }
                        SDL_ttfDisplayFont(650,260,window,ttffont,25,color,format_data,render);
                        SDL_RenderPresent(render); // 渲染
                    }
                    if((event.motion.x>=rect2.x && event.motion.x<=rect2.x+imgsurface->w) && 
                        (event.motion.y>=rect2.y && event.motion.y<=rect2.y+imgsurface->h))
                    {
                        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);
                        base64_encode(jpg_data, imagebase64_data, jpg_size);
                        snprintf(format_data,sizeof(format_data),"\"group_id_list\":\"wbyq\",\"quality_control\":\"LOW\",\"liveness_control\":\"NORMAL\"}");
                        int res=0;
                        res=faceDetect(face_search,access_token,imagebase64_data,format_data);
                        if(res)continue;
                        if(Josn_faceSearch(platform_data,format_data))
                        {
                            SDL_Rect rect={640,0,160,300};
							SDL_SetRenderDrawColor(render, 255, 255, 255, 255);
                            SDL_RenderFillRect(render,&rect);/*矩形填充*/
                            strcpy(format_data,"请重试\n");
                        }
                        else 
                        {
                            display_stat=0;
                            count=0;  
							SDL_SetRenderDrawColor(render, 255, 255, 255, 255);
                            SDL_Rect rect={640,0,160,300};
                            SDL_RenderFillRect(render,&rect);/*矩形填充*/
                            SDL_ttfDisplayFont(650,250,window,ttffont,25,color,"识别成功",render);
                        }
                        SDL_ttfDisplayFont(650,200,window,ttffont,20,color,format_data,render);
                        SDL_RenderPresent(render); // 渲染
                        printf("人脸识别\n");
                      
                    }
                }
            } 
        }
        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); // 拷贝纹理到渲染器
        image_rect.x=0;
        image_rect.y=0;
        image_rect.w=640;
        image_rect.h=480;
		SDL_RenderCopyEx(render, sdltext,NULL,&image_rect,0,NULL,SDL_FLIP_HORIZONTAL);
        rect.w=imgsurface->w;
        rect.h=imgsurface->h;
        SDL_RenderCopyEx(render,imgsdltext,NULL,&rect,0,NULL,SDL_FLIP_NONE);
        SDL_ttfDisplayFont(rect.x,rect.y+5,window,ttffont,18,color,"人脸注册",render);
        rect2.w=imgsurface->w;
        rect2.h=imgsurface->h;
        SDL_RenderCopyEx(render,imgsdltext,NULL,&rect2,0,NULL,SDL_FLIP_NONE);
        SDL_ttfDisplayFont(rect2.x,rect2.y+5,window,ttffont,18,color,"人脸识别",render);
        if(display_stat)SDL_RenderPresent(render); // 渲染
        else count++;
        SDL_Delay(1);
        if(count>=30)/*自动恢复图像监控状态*/
        {
          count=0;  
          display_stat=1;
        }
    }
    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); 
}
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐