hans

hans

【Shell】從ILSVRC_DET資料集中單獨拿出某一類圖片和註釋檔案


最近在研究 ILSVRC_DET 的資料集,想只訓練檢測某些指定類別的模型。寫了下面 shell 腳本用來提取 2011-2014 年比賽 train sets 和 val
sets 中所有有關指定類別的圖片和註釋檔案。

#!/bin/sh

stage=val   #我把訓練集和驗證集分在不同資料夾下面了
classes=(person)
nums=(n00007846) #ILSVRC對應的編碼
years=(2011 2012 2013)
root="/media/hans/000DABD1000BEFA8/ImageNet" #存放所有檔案的第一層目錄
i=0  #遞迴編碼用

for class in ${classes[@]}; 
do
    all_path="$root/Home/${class}/all" 
    mkdir -p $all_path/Annotations/ #最後所有檔案集中放在一起的目錄
    mkdir -p $all_path/JPEGImages/

    num=${nums[$i]} #配合class,遞迴編碼用,使它們保持指定同一類別

    for year in ${years[@]};
    do
        data_path="$root/ILSVRC$year/$stage" #指定原始資料位置
        year_path="$root/Home/${class}/${year}" #指定每一年資料位置

        name="${class}_${year}_name.txt" #每一年所有檔案名目錄,無副檔名
        path="${class}_${year}_path.txt" #絕對路徑


        mkdir -p $year_path/Annotations/
        mkdir -p $year_path/JPEGImages/

        echo 創建 $path ...
        find $data_path/xml/ . -type f | xargs grep -l "<name>$num</name>" > $year_path/$path 
#在原始xml資料檔案下遞迴搜索所有目錄,尋找包含指定編碼的檔案,並把該檔案絕對路徑保存到path.txt檔案中

        echo 創建 $name ...
        cd $year_path/
        cat $path | awk -F '/' '{print $NF}' > $name #把包含副檔名的檔案名提取出來
        find -name $name | xargs perl -pi -e 's|.xml||g' #刪掉副檔名

        echo 創建 temp.txt ...
        cat $name >> $all_path/temp.txt #把所有檔案名不覆蓋的保存到臨時文件中

        # copy .xml documents
        echo 複製 ${class}_${year}.xml 文件 ...
        cat $path | xargs -i cp -r {} $year_path/Annotations/ 
#根據絕對路徑複製原始資料到每一年目錄中

        /bin/cp -rf $year_path/Annotations/*.xml $all_path/Annotations/ # cp without prompt 
#根據檔案名搜索每一年指定.xml檔案,整合所有年份資料到一個目錄中,覆蓋重複項

        #copy .JPEG images
        echo 複製 ${class}_${year}.JPEG 圖片 ...
        cat $name | xargs -i find $data_path/img/ . -name {}.JPEG | xargs -i cp {} $year_path/JPEGImages/ 
#根據檔案名和指定的副檔名搜索原始資料,並保存到每一年的目錄中
        /bin/cp -rf $year_path/JPEGImages/*.JPEG $all_path/JPEGImages/ 
#根據檔案名和指定副檔名搜索每一年資料,整合所有年份資料到一個目錄中,覆蓋重複項

        echo 
    done

    echo 創建 ${class}_all_name.txt ...
    cd $all_path/
    cat temp.txt |sort|uniq > ${class}_all_name.txt 
#將包含所有年份的資料名排序,刪除重複檔案名,保存到新文件中。

    echo 刪除 temp.txt ...
    rm temp.txt

    let i+=1 #配合class,遞迴編碼用,使它們保持指定同一類別    #i=$i+1
done

剛開始接觸並嘗試寫腳本,在網上查了很多資料。發現腳本的世界很大,很多不同的命令可以實現相同的效果。慢慢學。

目錄設計比較多,因為這樣可以大大縮短遞迴搜索所用的時間。另外壓縮檔案是放到每一年份目錄下的,解壓後的東西放到對應子目錄中。上面腳本是放到 Home 目錄下。

下面是目錄設置樹

ImageNet -|

|- Home

|- ILSVRC2011 -|

| |- train -|

| | |- img

| | |- xml

| |- val -|

| |- img

| |- xml

|- ILSVRC2012 -|

| |- train -|

| | |- img

| | |- xml

| |- val -|

| |- img

| |- xml

|- ILSVRC2013 -|

| |- train -|

| | |- img

| | |- xml

| |- val -|

| |- img

| |- xml

|- ILSVRC2014 -|

| |- train -|

| | |- img

| | |- xml

| |- val -|

| |- img

| |- xml

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。