如何随机抽取样本集

来源:互联网 发布:python microservice 编辑:程序博客网 时间:2024/05/08 15:25

        最近在做人脸检测分类器的训练,当你手上拥有从互联网搜集的数量庞大的图片库时,随机抽取样本成为了做测试的必要步骤,下面是我用来做随机抽取样本的土方法。

        最终所有操作都将被写进一个批处理文件(.bat),只需通过下面第2步中的c++代码生成可执行文件,并将下面几个步骤中的批处理代码拼接起来即可。

  1.         首先需要一个图片库中图片的描述文件,这是一个文本文件(.txt),里面每行记录着图片的绝对路径。
    例如:
            D:\Image\00\1.jpg
            D:\Image\02\222.jpg
            ……
            假设我所有图片共同根目录是D:\Image,且最终生成的描述文件命名为ImageList.txt。
    批处理代码:
            setlocal enabledelayedexpansion
            for /r D:\Image %%i in (*.jpg) do (
            set temp=%%~fi
            echo !temp!>>D:\ImageList.txt
            )
    说明:
            for循环的参数/r会遍历指定目录(D:\Image)下的所有子目录中的文件。
            如果根目录D:\Image下有不同格式的图片并且没有非图片文件,可把*.jpg改成*.*。
            如果只想从指定几种格式的图片中进行随机抽取,将上面的for循环重复几次,每次将*.jpg改成对应的格式后缀名即可。
  2.         用c++编写随机抽取程序,以生成的随机数作为表示图片绝对路径的字符串的键值的方法建立索引表,使用STL map,这样元素会按键值序存储,直接取出前面N个元素即可达到随机抽取的目的。程序以上一步生成的图片库描述文件为输入,以随机抽取的指定数目的图片描述文件(ImageList_rand.txt)为输出。
    c++代码:
            #include<iostream>
            #include<fstream>
            #include<cmath>
            #include<ctime>
            #include<cstdlib>
            #include<map>
            #include<cstring>
            using namespace std;
            
            int main()
            {
                    fstream imagelist;
                    imagelist.open("ImageList.txt",ios::in);//输入文件名
                    fstream randpick;
                    randpick.open("ImageList_rand.txt",ios::out);//输出文件名
                    srand((unsigned) time(NULL));
                    map<int,string> loc_map;
                    char loc_name[100]={};//图片绝对路径长度
                    while(imagelist.getline(loc_name,100))
                    {
                            string temp(loc_name);
                            loc_map.insert(pair<int,string>(rand(),temp));
                            memset(loc_name,0,100);
                    }
                    map<int,string>::iterator iter;
                    int i;//抽取的图片数,在下一行中间(i<5)可以改变数目
                    for(i=0,iter=loc_map.begin();i<5&&iter!=loc_map.end();iter++,i++)
                    {
                            string temp;
                            temp=iter->second;
                            temp+='\n';
                            randpick.write(temp.c_str(),temp.length());
                    }
                    return 0;
            }
    说明:
            将上面的c++代码生成可执行文件(.exe),假设命名为RandomPick.exe,将它和用于输入的图片库描述文件放在同一个目录下。
            接着通过批处理调用它,代码如下。
    批处理代码:
            start "" ""E:\RandomPick.exe"
  3.         在同一个目录下(E:)会生成描述文件ImageList_rand.txt,最后一步就是将里面随机抽取出来的图片复制出来。
    批处理代码:
            setlocal enabledelayedexpansion
            mkdir E:\RandomPick
            for /f %%j in (ImageList_rand.txt) do (
                    copy %%j E:\RandomPick\
            )
            exit
    说明:
            最终指定数目的随机抽取的样本集将位于E:\RandomPick目录下。

        将3段批处理代码整理到一起,同整个图片库的描述文件以及第2步中的可执行文件放在一个目录下,执行即可。

原创粉丝点击