首页 > 代码库 > 实战小项目之基于yolo的目标检测web api实现

实战小项目之基于yolo的目标检测web api实现

  上个月,对微服务及web service有了一些想法,看了一本app后台开发及运维的书,主要是一些概念性的东西,对service有了一些基本了解。互联网最开始的构架多是cs构架,浏览器兴起以后,变成了bs,最近几年,随着移动互联网的兴起,cs构架再次火了起来,有了一个新的概念,web service。

  最近两天,想结合自己这段时间学的东西,实现一个cs构架的service接口。说一下大体流程,client上传图片到http服务器,http后台使用yolo进行图片的检测,之后将检测结果封装成json返回到client,client进行解析显示。

技术分享

client

  使用libcurl作为http请求工具,使用rapidjson进行结果json数据的解析

  上传图片时,没有使用标准的http多媒体方式,而是使用post 二进制流的方式,比较笨,有待改进。

server

  物体检测识别使用yolo c语言版本,修改原工程darknet的main,引入自己的main,实现直接检测的功能,main的流程:

导入yolo参数--必要初始化--fork子进程--安装信号--初始化fifo--sleep等待图片上传           接收信号唤醒--读取图像--预测-写入json文件--fifo写唤醒子进程

             |                             |                   |

           执行libevent实现的http server--eventloop监听--有文件上传结束--signal 父进程--阻塞在fifo读                         读取json,http返回

 

具体代码

client

extern "C"{#include <unistd.h>#include <sys/types.h>#include <time.h>#include <errno.h>#include <stdio.h>#include <signal.h>#include <arpa/inet.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/time.h>#include <fcntl.h>//iso#include <stdio.h>#include <stdlib.h>#include <string.h>//others#include "curl/curl.h"}//c++#include <iostream>#include <string>#include <fstream>#include "rapidjson/document.h"#include "rapidjson/stringbuffer.h"#include "rapidjson/writer.h"#define psln(x) std::cout << #x " = " << (x) << std::endlusing namespace std;size_t WriteFunction(void *input, size_t uSize, size_t uCount, void *arg) {    size_t uLen = uSize * uCount;    string *pStr = (string*) (arg);    pStr->append((char*) (input), uLen);    return uLen;}int main(int argc,char **argv){    if(argc<3){        printf("usage:./a.out uri pic\n");        exit(-1);    }    CURL *pCurl = NULL;    CURLcode code;    code = curl_global_init(CURL_GLOBAL_DEFAULT);    if (code != CURLE_OK) {        cout << "curl global init err" << endl;        return -1;    }    pCurl = curl_easy_init();    if (pCurl == NULL) {        cout << "curl easy init err" << endl;        return -1;    }    curl_slist *pHeaders = NULL;    string sBuffer;    string header = "username:tla001";    pHeaders = curl_slist_append(pHeaders, header.c_str());    ifstream in;    in.open(argv[2], ios::in | ios::binary);    if (!in.is_open()) {        printf("open err\n");        exit(-1);    }    in.seekg(0, ios_base::end);    const size_t maxSize = in.tellg();    in.seekg(0);    char * picBin = new char[maxSize];    in.read(picBin, maxSize);    in.close();    cout << maxSize << endl;    size_t sendSize = maxSize + sizeof(size_t);    char *sendBuff = new char[sendSize];    //    sprintf(sendBuff, "%d", maxSize);    memcpy(sendBuff, &maxSize, sizeof(size_t));    //    size_t tmp = 0;    //    memcpy(&tmp, sendBuff, sizeof(size_t));    //    cout << "tmp=" << tmp << endl;    memcpy(sendBuff + sizeof(size_t), picBin, maxSize);    curl_easy_setopt(pCurl, CURLOPT_URL, argv[1]);    curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pHeaders);    curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, 20);    //    curl_easy_setopt(pCurl, CURLOPT_HEADER, 1);    curl_easy_setopt(pCurl, CURLOPT_POST, 1L);    curl_easy_setopt(pCurl, CURLOPT_POSTFIELDS, sendBuff);    curl_easy_setopt(pCurl, CURLOPT_POSTFIELDSIZE, sendSize);    curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, &WriteFunction);    curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, &sBuffer);    code = curl_easy_perform(pCurl);    if (code != CURLE_OK) {        cout << "curl perform err,retcode="<<code << endl;        return -1;    }    long retcode = 0;    code = curl_easy_getinfo(pCurl, CURLINFO_RESPONSE_CODE, &retcode);    if (code != CURLE_OK) {        cout << "curl perform err" << endl;        return -1;    }    //cout << "[http return code]: " << retcode << endl;    //cout << "[http context]: " << endl << sBuffer << endl;    using rapidjson::Document;    Document doc;    doc.Parse<0>(sBuffer.c_str());    if (doc.HasParseError()) {        rapidjson::ParseErrorCode code = doc.GetParseError();        psln(code);        return -1;    }    using rapidjson::Value;    Value &content = doc["content"];    if (content.IsArray()) {        for (int i = 0; i < content.Size(); i++) {            Value &v = content[i];            assert(v.IsObject());            cout<<"object "<<"["<<i+1<<"]"<<endl;            if (v.HasMember("class") && v["class"].IsString()) {                cout <<"\t[class]:"<<v["class"].GetString()<<endl;            }            if (v.HasMember("prob") && v["prob"].IsDouble()) {                cout <<"\t[prob]:"<<v["prob"].GetDouble()<<endl;            }            cout<<"\t***************************"<<endl;            if (v.HasMember("left") && v["left"].IsInt()) {                cout <<"\t[left]:"<<v["left"].GetInt()<<endl;            }            if (v.HasMember("right") && v["right"].IsInt()) {                cout <<"\t[right]:"<<v["right"].GetInt()<<endl;            }            if (v.HasMember("top") && v["top"].IsInt()) {                cout <<"\t[top]:"<<v["top"].GetInt()<<endl;            }            if (v.HasMember("bot") && v["bot"].IsInt()) {                cout <<"\t[bot]:"<<v["bot"].GetInt()<<endl;            }            cout<<endl;        }    }    delete[] picBin;    delete[] sendBuff;    curl_easy_cleanup(pCurl);    curl_global_cleanup();    return 0;}

 

server

main.c

#include <time.h>#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <signal.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include "parser.h"#include "utils.h"#include "cuda.h"#include "blas.h"#include "connected_layer.h"extern void predict_classifier(char *datacfg, char *cfgfile, char *weightfile, char *filename, int top);extern void test_detector(char *datacfg, char *cfgfile, char *weightfile, char *filename, float thresh, float hier_thresh, char *outfile, int fullscreen);extern void run_voxel(int argc, char **argv);extern void run_yolo(int argc, char **argv);extern void run_detector(int argc, char **argv);extern void run_coco(int argc, char **argv);extern void run_writing(int argc, char **argv);extern void run_captcha(int argc, char **argv);extern void run_nightmare(int argc, char **argv);extern void run_dice(int argc, char **argv);extern void run_compare(int argc, char **argv);extern void run_classifier(int argc, char **argv);extern void run_regressor(int argc, char **argv);extern void run_char_rnn(int argc, char **argv);extern void run_vid_rnn(int argc, char **argv);extern void run_tag(int argc, char **argv);extern void run_cifar(int argc, char **argv);extern void run_go(int argc, char **argv);extern void run_art(int argc, char **argv);extern void run_super(int argc, char **argv);extern void run_lsd(int argc, char **argv);void average(int argc, char *argv[]){    char *cfgfile = argv[2];    char *outfile = argv[3];    gpu_index = -1;    network net = parse_network_cfg(cfgfile);    network sum = parse_network_cfg(cfgfile);    char *weightfile = argv[4];       load_weights(&sum, weightfile);    int i, j;    int n = argc - 5;    for(i = 0; i < n; ++i){        weightfile = argv[i+5];           load_weights(&net, weightfile);        for(j = 0; j < net.n; ++j){            layer l = net.layers[j];            layer out = sum.layers[j];            if(l.type == CONVOLUTIONAL){                int num = l.n*l.c*l.size*l.size;                axpy_cpu(l.n, 1, l.biases, 1, out.biases, 1);                axpy_cpu(num, 1, l.weights, 1, out.weights, 1);                if(l.batch_normalize){                    axpy_cpu(l.n, 1, l.scales, 1, out.scales, 1);                    axpy_cpu(l.n, 1, l.rolling_mean, 1, out.rolling_mean, 1);                    axpy_cpu(l.n, 1, l.rolling_variance, 1, out.rolling_variance, 1);                }            }            if(l.type == CONNECTED){                axpy_cpu(l.outputs, 1, l.biases, 1, out.biases, 1);                axpy_cpu(l.outputs*l.inputs, 1, l.weights, 1, out.weights, 1);            }        }    }    n = n+1;    for(j = 0; j < net.n; ++j){        layer l = sum.layers[j];        if(l.type == CONVOLUTIONAL){            int num = l.n*l.c*l.size*l.size;            scal_cpu(l.n, 1./n, l.biases, 1);            scal_cpu(num, 1./n, l.weights, 1);                if(l.batch_normalize){                    scal_cpu(l.n, 1./n, l.scales, 1);                    scal_cpu(l.n, 1./n, l.rolling_mean, 1);                    scal_cpu(l.n, 1./n, l.rolling_variance, 1);                }        }        if(l.type == CONNECTED){            scal_cpu(l.outputs, 1./n, l.biases, 1);            scal_cpu(l.outputs*l.inputs, 1./n, l.weights, 1);        }    }    save_weights(sum, outfile);}void speed(char *cfgfile, int tics){    if (tics == 0) tics = 1000;    network net = parse_network_cfg(cfgfile);    set_batch_network(&net, 1);    int i;    time_t start = time(0);    image im = make_image(net.w, net.h, net.c*net.batch);    for(i = 0; i < tics; ++i){        network_predict(net, im.data);    }    double t = difftime(time(0), start);    printf("\n%d evals, %f Seconds\n", tics, t);    printf("Speed: %f sec/eval\n", t/tics);    printf("Speed: %f Hz\n", tics/t);}void operations(char *cfgfile){    gpu_index = -1;    network net = parse_network_cfg(cfgfile);    int i;    long ops = 0;    for(i = 0; i < net.n; ++i){        layer l = net.layers[i];        if(l.type == CONVOLUTIONAL){            ops += 2l * l.n * l.size*l.size*l.c * l.out_h*l.out_w;        } else if(l.type == CONNECTED){            ops += 2l * l.inputs * l.outputs;        }    }    printf("Floating Point Operations: %ld\n", ops);    printf("Floating Point Operations: %.2f Bn\n", (float)ops/1000000000.);}void oneoff(char *cfgfile, char *weightfile, char *outfile){    gpu_index = -1;    network net = parse_network_cfg(cfgfile);    int oldn = net.layers[net.n - 2].n;    int c = net.layers[net.n - 2].c;    scal_cpu(oldn*c, .1, net.layers[net.n - 2].weights, 1);    scal_cpu(oldn, 0, net.layers[net.n - 2].biases, 1);    net.layers[net.n - 2].n = 9418;    net.layers[net.n - 2].biases += 5;    net.layers[net.n - 2].weights += 5*c;    if(weightfile){        load_weights(&net, weightfile);    }    net.layers[net.n - 2].biases -= 5;    net.layers[net.n - 2].weights -= 5*c;    net.layers[net.n - 2].n = oldn;    printf("%d\n", oldn);    layer l = net.layers[net.n - 2];    copy_cpu(l.n/3, l.biases, 1, l.biases +   l.n/3, 1);    copy_cpu(l.n/3, l.biases, 1, l.biases + 2*l.n/3, 1);    copy_cpu(l.n/3*l.c, l.weights, 1, l.weights +   l.n/3*l.c, 1);    copy_cpu(l.n/3*l.c, l.weights, 1, l.weights + 2*l.n/3*l.c, 1);    *net.seen = 0;    save_weights(net, outfile);}void oneoff2(char *cfgfile, char *weightfile, char *outfile, int l){    gpu_index = -1;    network net = parse_network_cfg(cfgfile);    if(weightfile){        load_weights_upto(&net, weightfile, 0, net.n);        load_weights_upto(&net, weightfile, l, net.n);    }    *net.seen = 0;    save_weights_upto(net, outfile, net.n);}void partial(char *cfgfile, char *weightfile, char *outfile, int max){    gpu_index = -1;    network net = parse_network_cfg(cfgfile);    if(weightfile){        load_weights_upto(&net, weightfile, 0, max);    }    *net.seen = 0;    save_weights_upto(net, outfile, max);}#include "convolutional_layer.h"void rescale_net(char *cfgfile, char *weightfile, char *outfile){    gpu_index = -1;    network net = parse_network_cfg(cfgfile);    if(weightfile){        load_weights(&net, weightfile);    }    int i;    for(i = 0; i < net.n; ++i){        layer l = net.layers[i];        if(l.type == CONVOLUTIONAL){            rescale_weights(l, 2, -.5);            break;        }    }    save_weights(net, outfile);}void rgbgr_net(char *cfgfile, char *weightfile, char *outfile){    gpu_index = -1;    network net = parse_network_cfg(cfgfile);    if(weightfile){        load_weights(&net, weightfile);    }    int i;    for(i = 0; i < net.n; ++i){        layer l = net.layers[i];        if(l.type == CONVOLUTIONAL){            rgbgr_weights(l);            break;        }    }    save_weights(net, outfile);}void reset_normalize_net(char *cfgfile, char *weightfile, char *outfile){    gpu_index = -1;    network net = parse_network_cfg(cfgfile);    if (weightfile) {        load_weights(&net, weightfile);    }    int i;    for (i = 0; i < net.n; ++i) {        layer l = net.layers[i];        if (l.type == CONVOLUTIONAL && l.batch_normalize) {            denormalize_convolutional_layer(l);        }        if (l.type == CONNECTED && l.batch_normalize) {            denormalize_connected_layer(l);        }        if (l.type == GRU && l.batch_normalize) {            denormalize_connected_layer(*l.input_z_layer);            denormalize_connected_layer(*l.input_r_layer);            denormalize_connected_layer(*l.input_h_layer);            denormalize_connected_layer(*l.state_z_layer);            denormalize_connected_layer(*l.state_r_layer);            denormalize_connected_layer(*l.state_h_layer);        }    }    save_weights(net, outfile);}layer normalize_layer(layer l, int n){    int j;    l.batch_normalize=1;    l.scales = calloc(n, sizeof(float));    for(j = 0; j < n; ++j){        l.scales[j] = 1;    }    l.rolling_mean = calloc(n, sizeof(float));    l.rolling_variance = calloc(n, sizeof(float));    return l;}void normalize_net(char *cfgfile, char *weightfile, char *outfile){    gpu_index = -1;    network net = parse_network_cfg(cfgfile);    if(weightfile){        load_weights(&net, weightfile);    }    int i;    for(i = 0; i < net.n; ++i){        layer l = net.layers[i];        if(l.type == CONVOLUTIONAL && !l.batch_normalize){            net.layers[i] = normalize_layer(l, l.n);        }        if (l.type == CONNECTED && !l.batch_normalize) {            net.layers[i] = normalize_layer(l, l.outputs);        }        if (l.type == GRU && l.batch_normalize) {            *l.input_z_layer = normalize_layer(*l.input_z_layer, l.input_z_layer->outputs);            *l.input_r_layer = normalize_layer(*l.input_r_layer, l.input_r_layer->outputs);            *l.input_h_layer = normalize_layer(*l.input_h_layer, l.input_h_layer->outputs);            *l.state_z_layer = normalize_layer(*l.state_z_layer, l.state_z_layer->outputs);            *l.state_r_layer = normalize_layer(*l.state_r_layer, l.state_r_layer->outputs);            *l.state_h_layer = normalize_layer(*l.state_h_layer, l.state_h_layer->outputs);            net.layers[i].batch_normalize=1;        }    }    save_weights(net, outfile);}void statistics_net(char *cfgfile, char *weightfile){    gpu_index = -1;    network net = parse_network_cfg(cfgfile);    if (weightfile) {        load_weights(&net, weightfile);    }    int i;    for (i = 0; i < net.n; ++i) {        layer l = net.layers[i];        if (l.type == CONNECTED && l.batch_normalize) {            printf("Connected Layer %d\n", i);            statistics_connected_layer(l);        }        if (l.type == GRU && l.batch_normalize) {            printf("GRU Layer %d\n", i);            printf("Input Z\n");            statistics_connected_layer(*l.input_z_layer);            printf("Input R\n");            statistics_connected_layer(*l.input_r_layer);            printf("Input H\n");            statistics_connected_layer(*l.input_h_layer);            printf("State Z\n");            statistics_connected_layer(*l.state_z_layer);            printf("State R\n");            statistics_connected_layer(*l.state_r_layer);            printf("State H\n");            statistics_connected_layer(*l.state_h_layer);        }        printf("\n");    }}void denormalize_net(char *cfgfile, char *weightfile, char *outfile){    gpu_index = -1;    network net = parse_network_cfg(cfgfile);    if (weightfile) {        load_weights(&net, weightfile);    }    int i;    for (i = 0; i < net.n; ++i) {        layer l = net.layers[i];        if (l.type == CONVOLUTIONAL && l.batch_normalize) {            denormalize_convolutional_layer(l);            net.layers[i].batch_normalize=0;        }        if (l.type == CONNECTED && l.batch_normalize) {            denormalize_connected_layer(l);            net.layers[i].batch_normalize=0;        }        if (l.type == GRU && l.batch_normalize) {            denormalize_connected_layer(*l.input_z_layer);            denormalize_connected_layer(*l.input_r_layer);            denormalize_connected_layer(*l.input_h_layer);            denormalize_connected_layer(*l.state_z_layer);            denormalize_connected_layer(*l.state_r_layer);            denormalize_connected_layer(*l.state_h_layer);            l.input_z_layer->batch_normalize = 0;            l.input_r_layer->batch_normalize = 0;            l.input_h_layer->batch_normalize = 0;            l.state_z_layer->batch_normalize = 0;            l.state_r_layer->batch_normalize = 0;            l.state_h_layer->batch_normalize = 0;            net.layers[i].batch_normalize=0;        }    }    save_weights(net, outfile);}void mkimg(char *cfgfile, char *weightfile, int h, int w, int num, char *prefix){    network net = load_network(cfgfile, weightfile, 0);    image *ims = get_weights(net.layers[0]);    int n = net.layers[0].n;    int z;    for(z = 0; z < num; ++z){        image im = make_image(h, w, 3);        fill_image(im, .5);        int i;        for(i = 0; i < 100; ++i){            image r = copy_image(ims[rand()%n]);            rotate_image_cw(r, rand()%4);            random_distort_image(r, 1, 1.5, 1.5);            int dx = rand()%(w-r.w);            int dy = rand()%(h-r.h);            ghost_image(r, im, dx, dy);            free_image(r);        }        char buff[256];        sprintf(buff, "%s/gen_%d", prefix, z);        save_image(im, buff);        free_image(im);    }}void visualize(char *cfgfile, char *weightfile){    network net = parse_network_cfg(cfgfile);    if(weightfile){        load_weights(&net, weightfile);    }    visualize_network(net);#ifdef OPENCV    cvWaitKey(0);#endif}int running=0;int exitFlag=0;void sigHandle(int signal){    if(signal==SIGUSR1){        printf("rec SIGUSR1\n");        running=1;    }     if(signal==SIGINT){        printf("rec SIGINT\n");        exitFlag=1;    }}int main(int argc, char **argv){    gpu_index = find_int_arg(argc, argv, "-i", 0);    if(find_arg(argc, argv, "-nogpu")) {        gpu_index = -1;    }#ifndef GPU    gpu_index = -1;#else    if(gpu_index >= 0){        cuda_set_device(gpu_index);    }#endif    float thresh = find_float_arg(argc, argv, "-thresh", .24);    char *filename ="test.jpg";    char *outfile = find_char_arg(argc, argv, "-out", 0);    int fullscreen = find_arg(argc, argv, "-fullscreen");    char *cfgfile="cfg/yolo.cfg";    char *weightfile="yolo.weights";    char *datacfg="cfg/coco.data";    float hier_thresh=0.5;     list *options = read_data_cfg(datacfg);    char *name_list = option_find_str(options, "names", "data/names.list");    char **names = get_labels(name_list);    image **alphabet = load_alphabet();    network net = parse_network_cfg(cfgfile);    if(weightfile){        load_weights(&net, weightfile);    }    set_batch_network(&net, 1);    srand(2222222);    clock_t time;    char buff[256];    char *input = buff;    int j;    float nms=.4;    int ret;    int childPid=0;    if((ret=fork())<0)        exit(-1);    else if(ret==0){        printf("child pid :%d\n",childPid=getpid());        printf("parent pid:%d\n",getppid());        ServerRun();    }    if(signal(SIGUSR1,sigHandle)==SIG_ERR){        perror("set signal err");    }     if(signal(SIGINT,sigHandle)==SIG_ERR){        perror("set signal err");    }    const char * FIFO_NAME="/tmp/myfifo";    if(access(FIFO_NAME,F_OK)==-1){        int res=mkfifo(FIFO_NAME,0777);        if(res!=0){            printf("could not create fifo\n");            exit(-1);        }    }    int fifo_fd=open(FIFO_NAME,O_WRONLY);        layer l = net.layers[net.n-1];    box *boxes = calloc(l.w*l.h*l.n, sizeof(box));    float **probs = calloc(l.w*l.h*l.n, sizeof(float *));    for(j = 0; j < l.w*l.h*l.n; ++j) probs[j] = calloc(l.classes + 1, sizeof(float *));    while(!exitFlag){        while(!running){            if(exitFlag)                break;            sleep(1);        }        if(exitFlag)            break;        if(filename){            strncpy(input, filename, 256);        }         image im = load_image_color(input,0,0);        image sized = letterbox_image(im, net.w, net.h);        //image sized = resize_image(im, net.w, net.h);        //image sized2 = resize_max(im, net.w);        //image sized = crop_image(sized2, -((net.w - sized2.w)/2), -((net.h - sized2.h)/2), net.w, net.h);        //resize_network(&net, sized.w, sized.h);               float *X = sized.data;        time=clock();        network_predict(net, X);        printf("%s: Predicted in %f seconds.\n", input, sec(clock()-time));        get_region_boxes(l, im.w, im.h, net.w, net.h, thresh, probs, boxes, 0, 0, hier_thresh, 1);        if (nms) do_nms_obj(boxes, probs, l.w*l.h*l.n, l.classes, nms);        //else if (nms) do_nms_sort(boxes, probs, l.w*l.h*l.n, l.classes, nms);        draw_detections(im, l.w*l.h*l.n, thresh, boxes, probs, names, alphabet, l.classes);        if(outfile){            save_image(im, outfile);        }        else{            save_image(im, "predictions");#ifdef OPENCV            cvNamedWindow("predictions", CV_WINDOW_NORMAL);             if(fullscreen){                cvSetWindowProperty("predictions", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);            }            show_image(im, "predictions");            cvWaitKey(2000);            cvDestroyAllWindows();#endif        }        free_image(im);        free_image(sized);               // if (filename) break;        running=0;        int res=write(fifo_fd,"1",1);        if(res==-1){            printf("write fifo err\n");            // exit(-1);        }    }    if(kill(childPid,9)==0){        waitpid(childPid,NULL,0);    }    close(fifo_fd);    free(boxes);    free_ptrs((void **)probs, l.w*l.h*l.n);    return 0;}

eventserver.c

/* * eventserver.c * *  Created on: Jun 13, 2017 *      Author: tla001 */#include <unistd.h>#include <sys/types.h>#include <time.h>#include <errno.h>#include <stdio.h>#include <signal.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/time.h>#include <fcntl.h>#include <netinet/in.h>#include <arpa/inet.h>//iso#include <stdio.h>#include <stdlib.h>#include <string.h>//others#include <event2/event-config.h>#include <event2/bufferevent.h>#include <event2/buffer.h>#include <event2/listener.h>#include <event2/util.h>#include <event2/event.h>#include <event2/http.h>#include <event2/keyvalq_struct.h>#include <event2/http_struct.h>#include <event2/buffer_compat.h>#include "cJSON.h"void test_request_cb(struct evhttp_request *req, void *arg) {    int ppid=getppid();    int type = evhttp_request_get_command(req);    const char *requestUri = evhttp_request_get_uri(req);    if (EVHTTP_REQ_GET == type) {        printf("method:GET uri:%s\n", requestUri);    } else if (EVHTTP_REQ_POST == type) {        printf("method:POST uri:%s\n", requestUri);    }    char *post_data = http://www.mamicode.com/(char *) EVBUFFER_DATA(req->input_buffer);//    printf("post data: %s", post_data);    size_t maxSize = 0;    memcpy(&maxSize, post_data, sizeof(size_t));    FILE *fp = fopen("test.jpg", "wb");    fwrite(post_data + sizeof(size_t), 1, maxSize, fp);    fclose(fp);    kill(ppid,SIGUSR1);    const char *FIFO_NAME="/tmp/myfifo";    int fifo_fd=open(FIFO_NAME,O_RDONLY);    char tmp=0;    int res=read(fifo_fd,&tmp,1);    if(res==-1){        printf("read err\n");        goto THISEXIT;    }    close(fifo_fd);    printf("fifo tmp=%c\n", tmp);    char *resData=http://www.mamicode.com/"rec";    if(tmp==1){        FILE *fp=fopen("res.json","rb");        if(fp==NULL)            goto THISEXIT;        fseek(fp,0,SEEK_END);        size_t size=ftell(fp);        rewind(fp);        resData=NULL;        resData=(char*)malloc(sizeof(char)*size+1);        int readSize=fread(resData,1,size,fp);        if(readSize!=size){            printf("read err\n");        }        resData[sizeof(char)*size]=\0;        printf("%s\n", resData);        fclose(fp);    }        printf("rec data len:%d\n", strlen(resData));    struct evbuffer *buf1 = evbuffer_new();    evbuffer_add_printf(buf1, resData);    evhttp_send_reply(req, 200, "OK", buf1);    if(resData&&tmp==1)        free(resData);    return ;THISEXIT:    kill(ppid,SIGINT);            exit(-1);}void ServerRun() {    int port = 5555;    struct event_base *base;    struct evhttp *http;    struct evhttp_bound_socket *handle;    if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {        printf("signal error,error[%d],error[%s]", errno, strerror(errno));        exit(-1);    }    base = event_base_new();    if (!base) {        printf("create an event_base err\n");        exit(-1);    }    http = evhttp_new(base);    if (!http) {        printf("create evhttp err\n");        exit(-1);    }    evhttp_set_cb(http, "/test", test_request_cb, NULL);    handle = evhttp_bind_socket_with_handle(http, "0.0.0.0", port);    if (!handle) {        printf("bind to port[%d] err\n", port);        exit(-1);    }    {        struct sockaddr_storage ss;        evutil_socket_t fd;        ev_socklen_t socklen = sizeof(ss);        char addrbuf[128];        void *inaddr;        const char *addr;        int got_port = -1;        fd = evhttp_bound_socket_get_fd(handle);        memset(&ss, 0, sizeof(ss));        if (getsockname(fd, (struct sockaddr*) &ss, &socklen)) {            perror("getsockname failed");            exit(-1);        }        if (ss.ss_family == AF_INET) {            got_port = ntohs(((struct sockaddr_in*) &ss)->sin_port);            inaddr = &((struct sockaddr_in*) &ss)->sin_addr;        } else if (ss.ss_family == AF_INET6) {            got_port = ntohs(((struct sockaddr_in6*) &ss)->sin6_port);            inaddr = &((struct sockaddr_in6*) &ss)->sin6_addr;        } else {            printf("Weird address family\n");            exit(1);        }        addr = evutil_inet_ntop(ss.ss_family, inaddr, addrbuf, sizeof(addrbuf));        if (addr) {            printf("Listening on %s:%d\n", addr, got_port);        } else {            printf("evutil_inet_ntop failed\n");            exit(-1);        }    }    event_base_dispatch(base);}

image.c修改一下函数

void draw_detections(image im, int num, float thresh, box *boxes, float **probs, char **names, image **alphabet, int classes){    int i;    cJSON *res=cJSON_CreateObject();    cJSON *content,*rec;    cJSON_AddItemToObject(res,"content",content=cJSON_CreateArray());    for(i = 0; i < num; ++i){        int class = max_index(probs[i], classes);        float prob = probs[i][class];        if(prob > thresh){            int width = im.h * .012;            if(0){                width = pow(prob, 1./2.)*10+1;                alphabet = 0;            }            //printf("%d %s: %.0f%%\n", i, names[class], prob*100);            // printf("%s: %.0f%%\n", names[class], prob*100);            int offset = class*123457 % classes;            float red = get_color(2,offset,classes);            float green = get_color(1,offset,classes);            float blue = get_color(0,offset,classes);            float rgb[3];            //width = prob*20+2;            rgb[0] = red;            rgb[1] = green;            rgb[2] = blue;            box b = boxes[i];            int left  = (b.x-b.w/2.)*im.w;            int right = (b.x+b.w/2.)*im.w;            int top   = (b.y-b.h/2.)*im.h;            int bot   = (b.y+b.h/2.)*im.h;            if(left < 0) left = 0;            if(right > im.w-1) right = im.w-1;            if(top < 0) top = 0;            if(bot > im.h-1) bot = im.h-1;            cJSON_AddItemToObject(content,"rec",rec=cJSON_CreateObject());            cJSON_AddStringToObject(rec,"class",names[class]);            cJSON_AddNumberToObject(rec,"prob",prob*100);            cJSON_AddNumberToObject(rec,"left",left);            cJSON_AddNumberToObject(rec,"right",right);            cJSON_AddNumberToObject(rec,"top",top);            cJSON_AddNumberToObject(rec,"bot",bot);            draw_box_width(im, left, top, right, bot, width, red, green, blue);            if (alphabet) {                image label = get_label(alphabet, names[class], (im.h*.03)/10);                draw_label(im, top + width, left, label, rgb);                free_image(label);            }        }    }    char *resStr=cJSON_Print(res);    cJSON_Delete(res);    // printf("%s\n", resStr);    FILE *fp=fopen("res.json","wb");    fwrite(resStr,1,strlen(resStr),fp);    fclose(fp);}

Makefile做了必要的修改

GPU=1CUDNN=1OPENCV=1DEBUG=0ARCH= -gencode arch=compute_20,code=[sm_20,sm_21]       -gencode arch=compute_30,code=sm_30       -gencode arch=compute_35,code=sm_35       -gencode arch=compute_50,code=[sm_50,compute_50]       -gencode arch=compute_52,code=[sm_52,compute_52]# This is what I use, uncomment if you know your arch and want to specify# ARCH=  -gencode arch=compute_52,code=compute_52VPATH=./src/EXEC=myappOBJDIR=./obj/CC=gccNVCC=nvcc OPTS=-OfastLDFLAGS= -lm -pthread -L/usr/local/libevent/lib -leventCOMMON=-I/usr/local/libevent/include CFLAGS=-Wall -Wfatal-errors ifeq ($(DEBUG), 1) OPTS=-O0 -gendifCFLAGS+=$(OPTS)ifeq ($(OPENCV), 1) COMMON+= -DOPENCVCFLAGS+= -DOPENCVLDFLAGS+= `pkg-config --libs opencv` COMMON+= `pkg-config --cflags opencv` endififeq ($(GPU), 1) COMMON+= -DGPU -I/usr/local/cuda/include/CFLAGS+= -DGPULDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurandendififeq ($(CUDNN), 1) COMMON+= -DCUDNN CFLAGS+= -DCUDNNLDFLAGS+= -lcudnnendifOBJ=main.o eventserver.o cJSON.o gemm.o utils.o cuda.o deconvolutional_layer.o convolutional_layer.o list.o image.o activations.o im2col.o col2im.o blas.o crop_layer.o dropout_layer.o maxpool_layer.o softmax_layer.o data.o matrix.o network.o connected_layer.o cost_layer.o parser.o option_list.o detection_layer.o captcha.o route_layer.o writing.o box.o nightmare.o normalization_layer.o avgpool_layer.o coco.o dice.o yolo.o detector.o layer.o compare.o regressor.o classifier.o local_layer.o swag.o shortcut_layer.o activation_layer.o rnn_layer.o gru_layer.o rnn.o rnn_vid.o crnn_layer.o demo.o tag.o cifar.o go.o batchnorm_layer.o art.o region_layer.o reorg_layer.o lsd.o super.o voxel.o tree.oifeq ($(GPU), 1) LDFLAGS+= -lstdc++ OBJ+=convolutional_kernels.o deconvolutional_kernels.o activation_kernels.o im2col_kernels.o col2im_kernels.o blas_kernels.o crop_layer_kernels.o dropout_layer_kernels.o maxpool_layer_kernels.o network_kernels.o avgpool_layer_kernels.oendifOBJS = $(addprefix $(OBJDIR), $(OBJ))DEPS = $(wildcard src/*.h) Makefileall: obj backup results $(EXEC)$(EXEC): $(OBJS)	$(CC) $(COMMON) $(CFLAGS) $^ -o $@ $(LDFLAGS)$(OBJDIR)%.o: %.c $(DEPS)	$(CC) $(COMMON) $(CFLAGS) -c $< -o $@$(OBJDIR)%.o: %.cu $(DEPS)	$(NVCC) $(ARCH) $(COMMON) --compiler-options "$(CFLAGS)" -c $< -o $@obj:	mkdir -p objbackup:	mkdir -p backupresults:	mkdir -p results.PHONY: cleanclean:	rm -rf $(OBJS) $(EXEC)

  

  在使用进程控制的时候,有一些防止出错的机制。

 

本项目涉及的技术yolo检测  --libevent http server --libcurl http client --http json

实战小项目之基于yolo的目标检测web api实现