Windows环境下yolov3+darknet批量处理图片

前言

作为一名大四狗,在生产实习的时候老师叫我们做关于图像处理的课题,要求处理500张图片,还要求美观。AB大神的darknet识别出来的图像很美观,因此我用darknet做。但老师要求要提交500张图片的成果,我不可能一张一张去处理,但在网上搜索也没有很好的批处理教程,经过自己的努力,我做出来了,并将这个方法分享给大家,由于是第一次发博客,有什么不足的地方希望大家多批评。

windows环境下,需要用到VS

1.下载Darknet和yolov3

下载Darknet

如果有git的话 git clone https://github.com/AlexeyAB/darknet

没有的话打开 https://github.com/AlexeyAB/darknet 下载

下载yolov3

https://pjreddie.com/media/files/yolov3.weights

放到EXE同目录下,如图

每个人的文件夹路径都不一样

2.修改代码

因为要进行批量处理,所以要修改darknet的代码。

首先打开darknet_no_gpu.sln,如图
在这里插入图片描述
打开后修改detector.c
在这里插入图片描述

找到test_detector函数,对其进行修改
在这里插入图片描述
修改代码如下,其核心思想是增加一个for循环。建立一个文本文件,文本文件里面存放所需要处理照片的绝对路径。修改这个函数读取这个文件,用for循环一个一个获取文件绝对路径进行处理。直至结束。

注意下面代码有一处需要改的地方。即你新建一个文件夹,将目录放到代码里,生成的图片会保存在那,作者的文件夹是pictest2

    double time;
    char buff[256];
    char *input = buff;
    int j,i;
    float nms = .45;    // 0.4F
if (filename) {
            strncpy(input, filename, 256);
            list *plist = get_paths(input);
            char **paths = (char **)list_to_array(plist);
            printf("Start Testing!\n");
            int m = plist->size;

            for (i = 0; i < m; ++i) {
                char *path = paths[i];
                image im = load_image(path, 0, 0, net.c);
                int letterbox = 0;
                image sized = resize_image(im, net.w, net.h);
                //image sized = letterbox_image(im, net.w, net.h); letterbox = 1;
                layer l = net.layers[net.n - 1];
                float *X = sized.data;
                double time = get_time_point();
                network_predict(net, X);
                printf("%s: Predicted in %lf milli-seconds.\n", input, ((double)get_time_point() - time) / 1000);
                printf("Try Very Hard:");
                printf("%s: Predicted in %lf milli-seconds.\n", path, ((double)get_time_point() - time) / 1000);
                 int nboxes = 0;
                detection *dets = get_network_boxes(&net, im.w, im.h, thresh, hier_thresh, 0, 1, &nboxes, letterbox);
                if (nms) do_nms_sort(dets, nboxes, l.classes, nms);
                draw_detections_v3(im, dets, nboxes, thresh, names, alphabet, l.classes, ext_output);
                
                char b[2048];
                sprintf(b, "D:\\Ctext\\pictest2\\%d", i);这里换上自己的路径,即你希望生成图片所保存的位置
                save_image(im, b);
                printf("save %s successfully!\n", b);
                
                if (save_labels)
                {
                    char labelpath[4096];
                    replace_image_to_label(input, labelpath);
                    FILE* fw = fopen(labelpath, "wb");
                    int i;
                    for (i = 0; i < nboxes; ++i) {
                        char buff[1024];
                        int class_id = -1;
                        float prob = 0;
                        for (j = 0; j < l.classes; ++j) {
                                if (dets[i].prob[j] > thresh && dets[i].prob[j] > prob) {
                                prob = dets[i].prob[j];
                                class_id = j;
                            }
                        }
                        if (class_id >= 0) {
                            sprintf(buff, "%d %2.4f %2.4f %2.4f %2.4f\n", class_id, dets[i].bbox.x, dets[i].bbox.y, dets[i].bbox.w, dets[i].bbox.h);
                            fwrite(buff, sizeof(char), strlen(buff), fw);
                        }
                          }
                    fclose(fw);
                }

                free_detections(dets, nboxes);
                free_image(im);
                free_image(sized);
                //free(boxes);
                //free_ptrs((void **)probs, l.w*l.h*l.n);
     }
        }	
        
        printf("All Done!\n");
        system("pause");
        exit(0);
        
         free_ptrs(names, net.layers[net.n - 1].classes);
         free_list_contents_kvp(options);
         free_list(options);

        const int nsize = 8;
    for (j = 0; j < nsize; ++j) {
        for (i = 32; i < 127; ++i) {
            free_image(alphabet[j][i]);
        }
        free(alphabet[j]);
    }

    free(alphabet);
    free_network(net);
    printf("All Done!\n");
    system("pause");

      

3.建立处理图像目录文本

首先将待处理的图像放入一个文件夹,例如作者将其放入

D盘的Ctext的picture下,作者只放了四张,如果有很多的话,可以用bat命令快速命名一下,方便处理。

在这里插入图片描述

步骤为,在当前文件夹下新建一个文本文件,复制粘贴以下代码,然后将后缀名改成bat,双击运行便可,效果为当前目录下所有jpg文件会从1开始自动排序。

@echo off
set a=00
setlocal EnableDelayedExpansion
for %%n in (*.jpg) do (
set /A a+=1
ren "%%n" "!a!.jpg"
)

接下来建立目标图片的绝对路径文本文件,编写一个小程序来快速建立。

#include <iostream>
#include <fstream>

using namespace std;
int main()
{
 ofstream fout("D:\\Ctext\\input_image_list.txt");
 int n;
 printf("请输入数量:");
 cin >> n;
 for (int i = 1; i <= n; i++)
 {
  fout << "D:\\Ctext\\picture\\" <<i<<".jpg"<<endl;
 }
 printf("输出成功\n");
  system("pause");
 fout.close();
 }

把生成的exe文件拖到生成的文本旁边方便,并更改名称,日后方便使用。

效果如图所示:

在这里插入图片描述

在这里插入图片描述

4.最后一步,开始处理图像

回到darknet工程目录下面(记得第二步改完代码之后要运行哦!)

在这里插入图片描述

随便新建一个文本文件,里面写:

darknet_no_gpu.exe detector test cfg/coco.data cfg/yolov3.cfg yolov3.weights D:\Ctext\input_image_list.txt  

保存,更改后缀为cmd,双击运行即开始处理。(作者的是tttttt.cmd)

代码解释:前面的darknet_no_gpu.exe,是我们更改代码后运行生成的程序,最后的D:\Ctext\input_image_list.txt 是我们第三步生成的目标图片绝对路径文本

最后效果如下:
在这里插入图片描述
在这里插入图片描述
picture文件夹是原本图片,pictest2是生成的图片

在这里插入图片描述
可以看到效果很不错。

到这里就全部结束了,有什么问题可以留下评论,作者会在能力范围之内讨论,哈哈,我也不是什么大神,继续学习,与诸君共勉!

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值