1. 程式人生 > >darknet-yolo執行攝像頭測試分析及過程主要程式碼梳理

darknet-yolo執行攝像頭測試分析及過程主要程式碼梳理

本人是在JESON TK1開發板上實現yolo的視訊實時執行測試

darknet的安裝很簡單,從官網上克隆程式碼即可:

git clone https://github.com/pjreddie/darknet.git

修改makefile檔案,使用opencv和cuda

GPU=1
OPENCV=1

切換目錄
cd darknet
make通過就安裝成功,若出現如下錯誤:

obj/avgpool_layer_kernels.o -o libdarknet.so -lm -pthreadpkg-config –libs OpenCV-L/usr/local/cuda/lib64 -lcuda
-lcudart -lcublas -lcurand -lstdc++ /usr/bin/ld: cannot find -lcudart /usr/bin/ld: cannot find -lcublas /usr/bin/ld: cannot find -lcurand

下面進行視訊測試
權重檔案請自行在darknet官網下載,本部落格使用了tiny-yolo-voc.weights
tiny-yolo-coco.weights (考慮到TK1開發板效能速度問題,只使用了小模型)

VOC資料集測試,連線攝像頭,執行命令

cd darknet
#voc webcam test
.
/darknet detector demo cfg/voc.data cfg/tiny-yolo-voc.cfg tiny-yolo-voc.weights

測試速度不夠快,修改網路輸入圖片大小到208x208,修改tiny-yolo-voc.cfg第四行

width=208
height=208

速度達到16幀左右,基本滿足實時要求

同理:
coco資料集測試,連線攝像頭,執行命令

cd darknet
#coco webcam test
./darknet detector demo cfg/coco.data cfg/tiny-yolo.cfg tiny-yolo-coco.weights

速度在15幀左右

本測試主要程式碼梳理:

./darknet detector demo cfg/voc.data cfg/tiny-yolo-voc.cfg tiny-yolo-voc.weights

上述命令的意思是進入darknet.c檔案,這個檔案在examples資料夾中,然後進入darknet.c的main函式,main函式主要是判斷輸入的引數,判斷的時候以空格左鍵分隔符,根據輸入引數執行程式碼,main函式的主要程式碼:

int main(int argc, char **argv)
{
    //test_resize("data/bad.jpg");
    //test_box();
    //test_convolutional_layer();
    if(argc < 2){
        fprintf(stderr, "usage: %s <function>\n", argv[0]);
        return 0;
    }
    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

    if (0 == strcmp(argv[1], "average")){
        average(argc, argv);
    } else if (0 == strcmp(argv[1], "yolo")){
        run_yolo(argc, argv);
    } else if (0 == strcmp(argv[1], "voxel")){
        run_voxel(argc, argv);
    } else if (0 == strcmp(argv[1], "super")){
        run_super(argc, argv);
    } else if (0 == strcmp(argv[1], "lsd")){
        run_lsd(argc, argv);
    } else if (0 == strcmp(argv[1], "detector")){
        run_detector(argc, argv);
    } else if (0 == strcmp(argv[1], "detect")){
        float thresh = find_float_arg(argc, argv, "-thresh", .24);
        char *filename = (argc > 4) ? argv[4]: 0;
        char *outfile = find_char_arg(argc, argv, "-out", 0);
        int fullscreen = find_arg(argc, argv, "-fullscreen");
        test_detector("cfg/coco.data", argv[2], argv[3], filename, thresh, .5, outfile, fullscreen);
    } else if (0 == strcmp(argv[1], "cifar")){
        run_cifar(argc, argv);
    } else if (0 == strcmp(argv[1], "go")){
        run_go(argc, argv);
    } else if (0 == strcmp(argv[1], "rnn")){
        run_char_rnn(argc, argv);
    } else if (0 == strcmp(argv[1], "vid")){
        run_vid_rnn(argc, argv);
    } else if (0 == strcmp(argv[1], "coco")){
        run_coco(argc, argv);
    } else if (0 == strcmp(argv[1], "classify")){
        predict_classifier("cfg/imagenet1k.data", argv[2], argv[3], argv[4], 5);
    } else if (0 == strcmp(argv[1], "classifier")){
        run_classifier(argc, argv);
    } else if (0 == strcmp(argv[1], "regressor")){
        run_regressor(argc, argv);
    } else if (0 == strcmp(argv[1], "segmenter")){
        run_segmenter(argc, argv);
    } else if (0 == strcmp(argv[1], "art")){
        run_art(argc, argv);
    } else if (0 == strcmp(argv[1], "tag")){
        run_tag(argc, argv);
    } else if (0 == strcmp(argv[1], "compare")){
        run_compare(argc, argv);
    } else if (0 == strcmp(argv[1], "dice")){
        run_dice(argc, argv);
    } else if (0 == strcmp(argv[1], "writing")){
        run_writing(argc, argv);
    } else if (0 == strcmp(argv[1], "3d")){
        composite_3d(argv[2], argv[3], argv[4], (argc > 5) ? atof(argv[5]) : 0);
    } else if (0 == strcmp(argv[1], "test")){
        test_resize(argv[2]);
    } else if (0 == strcmp(argv[1], "captcha")){
        run_captcha(argc, argv);
    } else if (0 == strcmp(argv[1], "nightmare")){
        run_nightmare(argc, argv);
    } else if (0 == strcmp(argv[1], "rgbgr")){
        rgbgr_net(argv[2], argv[3], argv[4]);
    } else if (0 == strcmp(argv[1], "reset")){
        reset_normalize_net(argv[2], argv[3], argv[4]);
    } else if (0 == strcmp(argv[1], "denormalize")){
        denormalize_net(argv[2], argv[3], argv[4]);
    } else if (0 == strcmp(argv[1], "statistics")){
        statistics_net(argv[2], argv[3]);
    } else if (0 == strcmp(argv[1], "normalize")){
        normalize_net(argv[2], argv[3], argv[4]);
    } else if (0 == strcmp(argv[1], "rescale")){
        rescale_net(argv[2], argv[3], argv[4]);
    } else if (0 == strcmp(argv[1], "ops")){
        operations(argv[2]);
    } else if (0 == strcmp(argv[1], "speed")){
        speed(argv[2], (argc > 3 && argv[3]) ? atoi(argv[3]) : 0);
    } else if (0 == strcmp(argv[1], "oneoff")){
        oneoff(argv[2], argv[3], argv[4]);
    } else if (0 == strcmp(argv[1], "oneoff2")){
        oneoff2(argv[2], argv[3], argv[4], atoi(argv[5]));
    } else if (0 == strcmp(argv[1], "partial")){
        partial(argv[2], argv[3], argv[4], atoi(argv[5]));
    } else if (0 == strcmp(argv[1], "average")){
        average(argc, argv);
    } else if (0 == strcmp(argv[1], "visualize")){
        visualize(argv[2], (argc > 3) ? argv[3] : 0);
    } else if (0 == strcmp(argv[1], "mkimg")){
        mkimg(argv[2], argv[3], atoi(argv[4]), atoi(argv[5]), atoi(argv[6]), argv[7]);
    } else if (0 == strcmp(argv[1], "imtest")){
        test_resize(argv[2]);
    } else {
        fprintf(stderr, "Not an option: %s\n", argv[1]);
    }
    return 0;
}

本部落格測試輸入引數為detector,因此你執行main的以下程式碼:

else if (0 == strcmp(argv[1], "detector")){
        run_detector(argc, argv);

run_detector函式位於examples資料夾中detector.c檔案,程式碼如下:

void run_detector(int argc, char **argv)
{
    char *prefix = find_char_arg(argc, argv, "-prefix", 0);
    float thresh = find_float_arg(argc, argv, "-thresh", .24);
    float hier_thresh = find_float_arg(argc, argv, "-hier", .5);
    int cam_index = find_int_arg(argc, argv, "-c", 0);
    int frame_skip = find_int_arg(argc, argv, "-s", 0);
    int avg = find_int_arg(argc, argv, "-avg", 3);
    if(argc < 4){
        fprintf(stderr, "usage: %s %s [train/test/valid] [cfg] [weights (optional)]\n", argv[0], argv[1]);
        return;
    }
    char *gpu_list = find_char_arg(argc, argv, "-gpus", 0);
    char *outfile = find_char_arg(argc, argv, "-out", 0);
    int *gpus = 0;
    int gpu = 0;
    int ngpus = 0;
    if(gpu_list){
        printf("%s\n", gpu_list);
        int len = strlen(gpu_list);
        ngpus = 1;
        int i;
        for(i = 0; i < len; ++i){
            if (gpu_list[i] == ',') ++ngpus;
        }
        gpus = calloc(ngpus, sizeof(int));
        for(i = 0; i < ngpus; ++i){
            gpus[i] = atoi(gpu_list);
            gpu_list = strchr(gpu_list, ',')+1;
        }
    } else {
        gpu = gpu_index;
        gpus = &gpu;
        ngpus = 1;
    }

    int clear = find_arg(argc, argv, "-clear");
    int fullscreen = find_arg(argc, argv, "-fullscreen");
    int width = find_int_arg(argc, argv, "-w", 0);
    int height = find_int_arg(argc, argv, "-h", 0);
    int fps = find_int_arg(argc, argv, "-fps", 0);

    char *datacfg = argv[3];
    char *cfg = argv[4];
    char *weights = (argc > 5) ? argv[5] : 0;
    char *filename = (argc > 6) ? argv[6]: 0;
    if(0==strcmp(argv[2], "test")) test_detector(datacfg, cfg, weights, filename, thresh, hier_thresh, outfile, fullscreen);
    else if(0==strcmp(argv[2], "train")) train_detector(datacfg, cfg, weights, gpus, ngpus, clear);
    else if(0==strcmp(argv[2], "valid")) validate_detector(datacfg, cfg, weights, outfile);
    else if(0==strcmp(argv[2], "valid2")) validate_detector_flip(datacfg, cfg, weights, outfile);
    else if(0==strcmp(argv[2], "recall")) validate_detector_recall(cfg, weights);
    else if(0==strcmp(argv[2], "demo")) {
        list *options = read_data_cfg(datacfg);
        int classes = option_find_int(options, "classes", 20);
        char *name_list = option_find_str(options, "names", "data/names.list");
        char **names = get_labels(name_list);
        demo(cfg, weights, thresh, cam_index, filename, names, classes, frame_skip, prefix, avg, hier_thresh, width, height, fps, fullscreen);
    }
}

命令列輸入第二個引數為demo,因此上述程式碼關鍵函式是demo(),demo函式位於src資料夾的demo.c檔案中,用於實現檢測和顯示檢測結果。程式碼如下:

void demo(char *cfgfile, char *weightfile, float thresh, int cam_index, const char *filename, char **names, int classes, int delay, char *prefix, int avg_frames, float hier, int w, int h, int frames, int fullscreen)
{
    demo_delay = delay;
    demo_frame = avg_frames;
    predictions = calloc(demo_frame, sizeof(float*));
    image **alphabet = load_alphabet();
    demo_names = names;
    demo_alphabet = alphabet;
    demo_classes = classes;
    demo_thresh = thresh;
    demo_hier = hier;
    printf("Demo\n");
    net = parse_network_cfg(cfgfile);
    if(weightfile){
        load_weights(&net, weightfile);
    }
    set_batch_network(&net, 1);
    pthread_t detect_thread;
    pthread_t fetch_thread;

    srand(2222222);

    if(filename){
        printf("video file: %s\n", filename);
        cap = cvCaptureFromFile(filename);
    }else{
        cap = cvCaptureFromCAM(cam_index);

        if(w){
            cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_WIDTH, w);
        }
        if(h){
            cvSetCaptureProperty(cap, CV_CAP_PROP_FRAME_HEIGHT, h);
        }
        if(frames){
            cvSetCaptureProperty(cap, CV_CAP_PROP_FPS, frames);
        }
    }

    if(!cap) error("Couldn't connect to webcam.\n");

    layer l = net.layers[net.n-1];
    demo_detections = l.n*l.w*l.h;
    int j;

    avg = (float *) calloc(l.outputs, sizeof(float));
    last_avg  = (float *) calloc(l.outputs, sizeof(float));
    last_avg2 = (float *) calloc(l.outputs, sizeof(float));
    for(j = 0; j < demo_frame; ++j) predictions[j] = (float *) calloc(l.outputs, sizeof(float));

    boxes = (box *)calloc(l.w*l.h*l.n, sizeof(box));
    probs = (float **)calloc(l.w*l.h*l.n, sizeof(float *));
    for(j = 0; j < l.w*l.h*l.n; ++j) probs[j] = (float *)calloc(l.classes+1, sizeof(float));

    buff[0] = get_image_from_stream(cap);
    buff[1] = copy_image(buff[0]);
    buff[2] = copy_image(buff[0]);
    buff_letter[0] = letterbox_image(buff[0], net.w, net.h);
    buff_letter[1] = letterbox_image(buff[0], net.w, net.h);
    buff_letter[2] = letterbox_image(buff[0], net.w, net.h);
    ipl = cvCreateImage(cvSize(buff[0].w,buff[0].h), IPL_DEPTH_8U, buff[0].c);

    int count = 0;
    if(!prefix){
        cvNamedWindow("Demo", CV_WINDOW_NORMAL); 
        if(fullscreen){
            cvSetWindowProperty("Demo", CV_WND_PROP_FULLSCREEN, CV_WINDOW_FULLSCREEN);
        } else {
            cvMoveWindow("Demo", 0, 0);
            cvResizeWindow("Demo", 1352, 1013);
        }
    }

    demo_time = get_wall_time();

    while(!demo_done){
        buff_index = (buff_index + 1) %3;
        if(pthread_create(&fetch_thread, 0, fetch_in_thread, 0)) error("Thread creation failed");
        if(pthread_create(&detect_thread, 0, detect_in_thread, 0)) error("Thread creation failed");
        if(!prefix){
            if(count % (demo_delay+1) == 0){
                fps = 1./(get_wall_time() - demo_time);
                demo_time = get_wall_time();
                float *swap = last_avg;
                last_avg  = last_avg2;
                last_avg2 = swap;
                memcpy(last_avg, avg, l.outputs*sizeof(float));
            }
            display_in_thread(0);
        }else{
            char name[256];
            sprintf(name, "%s_%08d", prefix, count);
            save_image(buff[(buff_index + 1)%3], name);
        }
        pthread_join(fetch_thread, 0);
        pthread_join(detect_thread, 0);
        ++count;
    }
}
#else
void demo(char *cfgfile, char *weightfile, float thresh, int cam_index, const char *filename, char **names, int classes, int delay, char *prefix, int avg, float hier, int w, int h, int frames, int fullscreen)
{
    fprintf(stderr, "Demo needs OpenCV for webcam images.\n");
}

相關推薦

darknet-yolo執行攝像頭測試分析過程主要程式碼梳理

本人是在JESON TK1開發板上實現yolo的視訊實時執行測試 darknet的安裝很簡單,從官網上克隆程式碼即可: git clone https://github.com/pjreddie/darknet.git 修改makefile檔案,使用o

Android多程序app中Application回撥onCreate()方法被執行多次分析解決

最近工作中碰到一個問題,在優化app,使用DDMS檢視Application log過程中看到,app啟動了三個程序,一個主程序,兩個附帶的程序。如下圖可看到一個app啟動的三個程序。  自定義Application回撥方法onCreate()被執行了3次。開始不知是何原因。 相

Spring Boot 初級入門教程(十二) —— 執行測試、打包過程中碰到的各種錯誤

錯誤一:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project test-springboot: Compilation fail

效能測試分析調優原理

效能測試的目的就評估當前系統性能的指標,分析定位解決效能瓶頸,預防規避效能風險。效能分析是為了確定導致效能瓶頸的原因,而調優就是用來解決效能瓶頸。通過某些手段讓系統性能得到提高,是效能調優的主要目的。效能分析主要有兩種方法:1.將測試結果與使用者需求做比較,如果達到使用者需求

門戶類網站效能測試分析調優

轉自阿里雲:https://help.aliyun.com/document_detail/pts/test-case/PTS-TC08-ProtalWebSites.html?pos=1 1 背景   前段時間,效能測試團隊經歷了一個規模較大的入口網站的效能優化工作,該網

快速排序的分析c語言程式碼

快速排序(Quicksort)是對氣泡排序的一種改進。它的基本思想是:通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。

DispatcherServlet程式碼分析執行過程

1    首先該類有一靜態語塊,用以載入預設策略。static {ClassPathResource resource =new ClassPathResource(DEFAULT_STRATEGIES_PATH,DispatcherServlet.class);defaul

Vivotek 攝像頭遠程棧溢出漏洞分析利用

-418 環境搭建 目標 bin 無法 查看 攝像 遠程調試 鏡像 Vivotek 攝像頭遠程棧溢出漏洞分析及利用 近日,Vivotek 旗下多款攝像頭被曝出遠程未授權棧溢出漏洞,攻擊者發送特定數據可導致攝像頭進程崩潰。 漏洞作者@bashis 放出了可造成攝像頭 Cras

Spring Boot(3):加載DataSource過程的源碼分析yml中DataSource的配置

conf apache JD asi 其中 ase providers ram nconf Spring Boot實現了自動加載DataSource及相關配置。當然,使用時加上@EnableAutoConfiguration註解是必須的。下面就是對這一部分的源碼分析。 (1

機器學習(一)梯度下降算法的實現過程分析

回歸 vnc 分布 AC HA 向量 med mar size 機器學習(一)梯度下降算法 因為算法最好能應用到實際問題中才會讓讀者感到它的真實的用處,因此首先我來描述一個實際問題(梯度下降算法用以幫助解決該問題):給定一個指定的數據集,比如由若幹某一

某系統單點登錄性能測試診斷分析優化過程

ack 16px sqlio packet 協助 sqli 通過 查看 新增 某系統單點登錄性能測試診斷分析優化過程原因說明 下面描述的是前段時間協助本地一家上市IT公司做產品技術選型時對他們的技術框架進行性能測試與優化過程記錄,因測試過程中涉及數據庫選型和各類問題的監

MongoDB 執行mongoexport時異常分析

-type pytho -c 語句 推斷 轉換 The 3.4 not 今天在用mongoexport導出滿足一定條件下的數據時,遇到了一個報錯,現紀錄下來,並且針對此錯誤對MongoDB 的?數字類型?做了進一步的學習。 背景及報錯信息?今天接到一個業務需求,需要從Mon

Darknet+YOLO的安裝和測試指南

Darknet是Joseph維護的開源的神經網路框架,使用C語言編寫。 官網地址 Darknet快速,易於安裝,同時支援CPU和GPU計算。 專案原始碼可以在github pjreddie/darknet 看到。 1 初步使用darknet進行預測 1.1 安裝框架 git

轉載:oracle執行update語句時卡住問題分析解決辦法

oracle執行update語句時卡住問題分析及解決辦法  這篇文章主要介紹了oracle執行update語句時卡住問題分析及解決辦法,涉及記錄鎖等相關知識,具有一定參考價值,需要的朋友可以瞭解。 問題 開發的時候debug到一條update的sql語句時程式就不動了,然後我就

Android相容性測試GTS-環境搭建、測試執行、結果分析

GTS的全稱是Google Mobile Services Test Suite,所謂的Google Mobile Services即谷歌移動服務,是谷歌開發並推動Android的動力,也是Android系統的靈魂所在。GMS目前提供有Search、Search by Voice、Gmai

ORACLE中查詢語句的執行where部分條件執行順序測試 Oracle中的一些查詢語句及其執行順序 Select 語句執行順序以及如何提高Oracle 基本查詢效率

Oracle中的一些查詢語句及其執行順序 原文地址:https://www.cnblogs.com/likeju/p/5039115.html 查詢條件:1)LIKE:模糊查詢,需要藉助兩個萬用字元,%:表示0到多個字元;_:標識單個字元。2)IN(list):用來取出符合列表範圍中的資料。3)NOT I

大資料技術學習筆記之Hadoop框架基礎3-網站日誌分析MapReduce過程詳解

一、回顧     -》Hadoop啟動方式         -》單個程序             sbin/h

MFC單文件框架分析執行流程(轉)

原文轉自 https://blog.csdn.net/u011619422/article/details/40402705   首先來分析一下MFC單文件類的結構: 它包括如下幾個類: CAboutDlg :  對話方塊框類,對應應用程式的“幫助”->“關於”選單,彈出“關

CVE-2017-7269 IIS6.0遠端程式碼執行漏洞分析Exploit

原帖地址:http://whereisk0shl.top/cve-2017-7269-iis6-interesting-exploit.html 感謝仙果和Wingdbg,我將我部落格的這篇分析轉到看雪和大家一起分享。我的部落格會長期更新二進位制分析的文章,希望能與

安裝SQL Server 2012過程中出現“啟用windows功能NetFx3時出錯”(錯誤原因、詳細分析解決方法)以及在Windows Server2012上安裝.NET Framework

  問題:在伺服器(作業系統為Windows server 2012)上安裝SQL Server 2012的過程中,安裝停留在下圖所示的介面上,顯示”正在啟用作業系統功能NetFx3”隨後出現提示框,告知啟用windows功能NetFx3時出錯。    分析:NetFx3指的