zoukankan      html  css  js  c++  java
  • 实战小项目之基于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::endl
    
    using 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
    ");
            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
    ");
            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 <<"	[class]:"<<v["class"].GetString()<<endl;
                }
                if (v.HasMember("prob") && v["prob"].IsDouble()) {
                    cout <<"	[prob]:"<<v["prob"].GetDouble()<<endl;
                }
                cout<<"	***************************"<<endl;
                if (v.HasMember("left") && v["left"].IsInt()) {
                    cout <<"	[left]:"<<v["left"].GetInt()<<endl;
                }
                if (v.HasMember("right") && v["right"].IsInt()) {
                    cout <<"	[right]:"<<v["right"].GetInt()<<endl;
                }
                if (v.HasMember("top") && v["top"].IsInt()) {
                    cout <<"	[top]:"<<v["top"].GetInt()<<endl;
                }
                if (v.HasMember("bot") && v["bot"].IsInt()) {
                    cout <<"	[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("
    %d evals, %f Seconds
    ", tics, t);
        printf("Speed: %f sec/eval
    ", t/tics);
        printf("Speed: %f Hz
    ", 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
    ", ops);
        printf("Floating Point Operations: %.2f Bn
    ", (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
    ", 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
    ", i);
                statistics_connected_layer(l);
            }
            if (l.type == GRU && l.batch_normalize) {
                printf("GRU Layer %d
    ", i);
                printf("Input Z
    ");
                statistics_connected_layer(*l.input_z_layer);
                printf("Input R
    ");
                statistics_connected_layer(*l.input_r_layer);
                printf("Input H
    ");
                statistics_connected_layer(*l.input_h_layer);
                printf("State Z
    ");
                statistics_connected_layer(*l.state_z_layer);
                printf("State R
    ");
                statistics_connected_layer(*l.state_r_layer);
                printf("State H
    ");
                statistics_connected_layer(*l.state_h_layer);
            }
            printf("
    ");
        }
    }
    
    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
    ");
            running=1;
        }
         if(signal==SIGINT){
            printf("rec SIGINT
    ");
            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
    ",childPid=getpid());
            printf("parent pid:%d
    ",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
    ");
                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.
    ", 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
    ");
                // 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
    ", requestUri);
        } else if (EVHTTP_REQ_POST == type) {
            printf("method:POST uri:%s
    ", requestUri);
        }
    
        char *post_data = (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
    ");
            goto THISEXIT;
        }
        close(fifo_fd);
        printf("fifo tmp=%c
    ", tmp);
        char *resData="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
    ");
            }
            resData[sizeof(char)*size]='';
            printf("%s
    ", resData);
            fclose(fp);
        }
        
    
    
        printf("rec data len:%d
    ", 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
    ");
            exit(-1);
        }
        http = evhttp_new(base);
        if (!http) {
            printf("create evhttp err
    ");
            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
    ", 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
    ");
                exit(1);
            }
    
            addr = evutil_inet_ntop(ss.ss_family, inaddr, addrbuf, sizeof(addrbuf));
            if (addr) {
                printf("Listening on %s:%d
    ", addr, got_port);
            } else {
                printf("evutil_inet_ntop failed
    ");
                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%%
    ", i, names[class], prob*100);
                // printf("%s: %.0f%%
    ", 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
    ", resStr);
        FILE *fp=fopen("res.json","wb");
        fwrite(resStr,1,strlen(resStr),fp);
        fclose(fp);
    }

    Makefile做了必要的修改

    GPU=1
    CUDNN=1
    OPENCV=1
    DEBUG=0
    
    ARCH= -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_52
    
    VPATH=./src/
    EXEC=myapp
    OBJDIR=./obj/
    
    CC=gcc
    NVCC=nvcc 
    OPTS=-Ofast
    LDFLAGS= -lm -pthread -L/usr/local/libevent/lib -levent
    COMMON=-I/usr/local/libevent/include 
    CFLAGS=-Wall -Wfatal-errors 
    
    ifeq ($(DEBUG), 1) 
    OPTS=-O0 -g
    endif
    
    CFLAGS+=$(OPTS)
    
    ifeq ($(OPENCV), 1) 
    COMMON+= -DOPENCV
    CFLAGS+= -DOPENCV
    LDFLAGS+= `pkg-config --libs opencv` 
    COMMON+= `pkg-config --cflags opencv` 
    endif
    
    ifeq ($(GPU), 1) 
    COMMON+= -DGPU -I/usr/local/cuda/include/
    CFLAGS+= -DGPU
    LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand
    endif
    
    ifeq ($(CUDNN), 1) 
    COMMON+= -DCUDNN 
    CFLAGS+= -DCUDNN
    LDFLAGS+= -lcudnn
    endif
    
    OBJ=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.o
    ifeq ($(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.o
    endif
    
    OBJS = $(addprefix $(OBJDIR), $(OBJ))
    DEPS = $(wildcard src/*.h) Makefile
    
    all: 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 obj
    backup:
    	mkdir -p backup
    results:
    	mkdir -p results
    
    .PHONY: clean
    
    clean:
    	rm -rf $(OBJS) $(EXEC)
    

      

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

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

  • 相关阅读:
    prototype.js超强的javascript类库
    MySQL Server Architecture
    Know more about RBA redo block address
    MySQL无处不在
    利用Oracle Enterprise Manager Cloud Control 12c创建DataGuard Standby
    LAMP Stack
    9i中DG remote archive可能导致Primary Database挂起
    Oracle数据库升级与补丁
    Oracle为何会发生归档日志archivelog大小远小于联机重做日志online redo log size的情况?
    Oracle Ksplice如何工作?How does Ksplice work?
  • 原文地址:https://www.cnblogs.com/tla001/p/7008230.html
Copyright © 2011-2022 走看看