参考)YOLOv2训练自己的数据集(voc格式)进行实验,基本上是正确的,但其初始给出的代码并非是在linux下可以运行的,因此参考部分博客写了下面的程序,可以实现对文件夹内图片的批量读取以及更改名称符合VOC数据集习惯。另原文有部分小错误,本文已经修改,但后文属于转载,版权属原作者所有,本文仅为记录和交流用。如下文所示。
1 准备数据
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <opencv2/opencv.hpp>
#define img_num 2000
char img_file[img_num][1000];
int list_dir_name(char* dirname, int tabs)
{
DIR* dp;
struct dirent* dirp;
struct stat st;
char tab[tabs + 1];
char img_count=0;
/* open dirent directory */
if((dp = opendir(dirname)) == NULL)
{
perror("opendir");
return -1;
}
/* fill tab array with tabs */
memset(tab, '\t', tabs);
tab[tabs] = 0;
/**
* read all files in this dir
**/
while((dirp = readdir(dp)) != NULL)
{
char fullname[255];
memset(fullname, 0, sizeof(fullname));
/* ignore hidden files */
if(dirp->d_name[0] == '.')
continue;
/* display file name */
//printf("img_name:%s\n", dirp->d_name);
strncpy(fullname, dirname, sizeof(fullname));
strncat(fullname, dirp->d_name, sizeof(fullname));
strcat(img_file[img_count++], fullname);
printf("Image %3d path:%s\n",img_count-1,img_file[img_count-1]);//fullname=dir+file name,the absolute path of the image file
/* get dirent status */
if(stat(fullname, &st) == -1)
{
perror("stat");
fputs(fullname, stderr);
return -1;
}
/* if dirent is a directory, call itself */
if(S_ISDIR(st.st_mode) && list_dir_name(fullname, tabs + 1) == -1)
return -1;
}
return img_count;
}
int main(int argc, char* argv[])
{
char* dir="/home/robot/Downloads/mark_recognition/car_img/simple_3class/";
printf("%s\n", dir);
char sum=list_dir_name(dir, 1);
printf("Img total num:%d\n",sum);
int i;
char order[1000];
char txt_path[1000];
char* txt_name="train.txt";
memset(txt_path, 0, sizeof(txt_path));
strcat(txt_path,dir);
strcat(txt_path,txt_name);
FILE *fp = fopen(txt_path, "w");
for (i = 0; i<sum; ++i)
{
char img_path[1000];
memset(img_path, 0, sizeof(img_path));
printf("Source %s\n", img_file[i]);
IplImage *pSrc = cvLoadImage(img_file[i]);
sprintf(order, "%05d.jpg", i);
strcat(img_path,dir);
strcat(img_path,order);
cvSaveImage(img_path, pSrc);
fprintf(fp, "%05d\n", i);
printf("Save as%s\n", img_path);
cvReleaseImage(&pSrc);
}
fclose(fp);
return 0;
}
准备好了自己的图像后,需要按VOC数据集的结构放置图像文件。VOC的结构如下
--VOC
--Annotations
--ImageSets
--Main
--Layout
--Segmentation
--JPEGImages
--SegmentationClass
--SegmentationObject
这里面用到的文件夹是 Annotations、ImageSets和JPEGImages。其中文件夹 Annotation中主要存放xml文件,每一个xml对应一张图像,并且每个xml中存放的是标记的各个目标的位置和类别信息,命名通常与对应的原始图像一样;而ImageSets我们只需要用到Main文件夹,这里面存放的是一些文本文件,通常为train.txt、test.txt等,该文本文件里面的内容是需要用来训练或测试的图像的名字(无后缀无路径);JPEGImages文件夹中放我们已按统一规则命名好的原始图像。
因此,首先
1.新建文件夹VOC2007(通常命名为这个,也可以用其他命名,但一定是名字+年份,例如MYDATA2016,无论叫什么后面都需要改相关代码匹配这里,本例中以 VOC2007为例)
2.在VOC2007文件夹下新建三个文件夹 Annotations、ImageSets和JPEGImages,并把准备好的自己的原始图像放在JPEGImages文件夹下
3.在ImageSets文件夹中,新建三个空文件夹Layout、Main、Segmentation,然后把写了训练或测试的图像的名字的文本拷到Main文件夹下,按目的命名,我这里所 有图像用来训练,故而Main文件夹下只有train.txt文件。上面代码运行后会在图片文件夹内生成该文件,把它拷进去即可。
评论(0)
您还未登录,请登录后发表或查看评论