---
# System prepended metadata

title: Data Processing

---

# Data Processing
`by 許承壹`
# 1. NAS上相關資源與上傳之路徑
* camera rosbag ***(找恕康哥要當初Thermal/RGB的raw bag，做完步驟1之後上傳到NAS)***
    `/bag/bag/Share/ADV/Rosbag/Testcar/類別_日期`
    * Note - 類別分為 ITRI(院內)/HSR(竹北)_Clear/RainyDay/Night
                       - 日期為原始rosbag錄製時間
* 傳給III之原影像 ＆ 預標記資料
    `/Data_1/Dataset/label_data_for_III/1.2/2d label/HSR/預標記資料/日期1_類別_日期2`
    * Note: - ***日期1為原始rosbag錄製時間***
            - ***日期2為當天上傳時間(=傳送給III之時間)***
            - 類別同上
* yolo images & labels
    `/Data_1/Dataset/DriveNet/Labeled/日期/YOLO/分類資料夾/FOVxxx/ ---> 正確標記檔 (.txt, .jpg)`
    `/Data_1/Dataset/DriveNet/Labeled/日期/III ---> III回傳的(.xml)`
    * Note: 日期為原bag錄製之時間
* label problem 
    `/Data_1/Dataset/DriveNet/Labeled/Label problem`

* Dataset ***(上傳Dataset)***
    `/Data_1/Dataset/DriveNet/DatasetAll/產生日期`
    `/Data_1/Dataset/DriveNet/Dataset_Fov120/產生日期`
    `/Data_1/Dataset/DriveNet/Dataset_Fov60/產生日期 *Note: Fov30和Fov60合併一起`

* 最新版 weight, darknet等備份 
    `/bag/bag/Share/ADV/Camera_Model/2D Object Detection/yolov3/`
    * Yolov3 Github:https://github.com/amtommy/yolov3_offline
    * Yolov4 Github:https://github.com/amtommy/yolov4_offline


* SSD相關資源 ***(目前沒使用到)***
    `/Data_1/Dataset/Drivenet/SSD`
    
* NAS伺服器網址: http://140.96.109.23:32110/cgi-bin/
* Data processing tool之github: 
# 2.完整操作流程
## 步驟一: rosbag資料轉換成image檔
1. 取出原始rosbag中camera部份, 存成新的rosbag(檔名為當下日期時間)
* 以下為 training machine上操作指令與路徑
    1-1.進入itriadv 路徑：`~/itriadv`
    -`rm -r build/ devel/`
    -`catkin_make -DCAR_MODEL=B1_V3 --only-pkg=image_compressor`
    (terminal 1）
        -`roscore`
    (terminal 2)
    -`source ./devel/setup.bash`
    -`roslaunch image_compressor decmpr.launch`
    1-2.進入rosbag 存放路徑：`/your path to the bags/`
    (terminal 1)
    -`rosbag record -e "(.*)cam(.*)"`
    (terminal 2)
    -`rosbag play *.bag`
* Note: 執行完後,要將新的rosbag上傳至NAS

2. 按照以下樹狀結構建立資料夾,並把剛才產生的 新rosbag 放入 bags 資料夾
├── `資料夾1/` 
		│   ├── `allExtractCameraFromBag.py` (八顆相機)
		│   ├── `ExtractCameraFromBag.py` (單顆相機)
		│   ├── `bags/` 
		│   ├── `extract/`
		│   │   ├── `resize.py (extract下一層)`
		│   │   ├── `分類資料夾 (不一定,依需求建立)`
		│   │   │   ├── `back_top_120/`
		│   │   │   ├── `front_bottom_60/`
		│   │   │   ├── `front_top_close_120/`
		│   │   │   ├── `front_top_far_30/`
		│   │   │   ├── `left_back_60/`
		│   │   │   ├── `left_front_60/`
		│   │   │   ├── `right_back_60/`
		│   │   │   ├── `right_front_60/`
		│   │   │   ├── `80class/`
		│   │   │   │   ├── `同上相機資料夾*8`
        
3. 新rosbag擷取成image並分類成8顆相機
3-1. 修改 `allExtractCameraFromBag.py` 內之路徑及檔名
    * time_stamp = extract內, 若又再加一層(分類資料夾)的資料夾名, 若沒有可mark掉
    * name = rosbag檔名(不用.bag)
    * input_path = rosbag存放路徑(e.g. /bags/)
    * output_path = extract路徑(e.g. /extract/front_bottom_60)

    3-2. 執行指令：`python allExtractCameraFromBag.py`
4. 擷取出之image重新resize符合III需求之大小(1920*1208)
    4-1.修改resize.py檔案內的time_step(=分類資料夾名)
    4-2.執行指令：`python resize.py`
    
5. 刪除停等紅綠燈等場景未變換的資料


## 步驟二: 產生預標記檔
1. 在欲產生欲標記檔案的照片資料夾下(resize過後的照片),執行指令
`find $PWD -iname "*.jpg" > valid.txt`
2. 利用yolov3 model產生預標記檔:
    2-1.進入darknet路徑：`/<your path to darknet>/darknet`
    執行指令 `./darknet detector test /<your path to>/coco.data /<your path to>/yolov3.cfg /<your path to>/model weights -dont_show -save_labels 1 <  /<your path to>/valid.txt`
    純指令範例：
    ./darknet detector test /media/owo/PATRIOT/NewDataset/Exp20210525/coco.data /media/owo/PATRIOT/NewDataset/Exp20210525/yolov3.cfg /media/owo/PATRIOT/NewDataset/Exp20210525/yolov3_436100_0.239114.weights -dont_show -save_labels 1 < /media/owo/PATRIOT/HSR_rosbag/0503/extract/valid.txt
3. 將照片以及預標記檔依照以下資料夾路徑包裝好後傳給資策會:
            ├── `資料夾(要傳給資策會的照片與預標記檔)`
            │   ├── `images`(內含該次的所有照片)
            |	│   ├── `相機名稱(e.g. front_bottom_60)`(內含該次的所有照片)
            │   ├── `labels`(內含該次產生的所有預標記檔)
            |	│   ├── `相機名稱(e.g. front_bottom_60)`(內含該次的所有照片)
* Note
    * 若要產生7 class的預標記結果，則必須使用7 class的model weight，以及7 class的config(coco_class7.data、yolov3_7class.cfg)檔
    * .data檔以及.cfg檔等yolo model相關的設定檔放在NAS的該路徑下:
        * /bag/bag/Share/ADV/Camera_Models/2D Object Detection/yolov3/10_classes/
    * 執行後會在原圖檔(原相機資料夾)旁邊產生.txt檔=預標記的結果, 將它搬至對應的7/80class資料夾
    * 產生預標記圖檔後, 建議先用label_tool.py執行驗證(步驟三-3.)(不用執行xmltoYolo), 確認辨識的結果
    * 步驟二執行完後,相關檔案上傳至NAS,並傳給III進行標記
        - 選取 image的相機*8資料夾 壓縮成日期_類別.zip (日期為原始rosbag時間)
		- 選取 80class 壓縮成日期_類別_label.zip 
	    - NAS上傳路徑如下:`/Data_1/Dataset/label_data_for_III/1.2/2d label/HSR/預標記資料/日期1_類別_日期2`
    - 記得更新圖檔統計(***excel檔***)
	- III回傳標記圖檔後, 進行步驟三
## 步驟三: 確認III回傳之標記影像正確性
1. 根據以下樹狀圖建立資料夾/放置檔案
		├── `資料夾2/ (個別相機資料夾)(根據III回傳的內容)`
		│   ├── `FOV60/ (or FOV30 or FOV120)(根據相機名稱最後一個數字)`
		│   │   ├──` FOV60的相機資料夾/`
		│   │   │   ├── `images/`
		│   │   │   ├── `labels /` 
		│   ├── `images/ <--- 原影像`
		│   ├── `labels/ <--- III回傳之標記影像 (xml file)`
		│   ├── `label_tool.py`
		│   ├── `transparent.xbm`
		│   ├── `xml_Config.conf`
		│   ├── `xmltoYolo.py`

2. 資料轉為yolo格式
    2-1. 修改 xml_Config.conf 內之路徑
    * inputITRI/xmlDir: labels 資料夾路徑
    - inputITRI/jpegDir: images 資料夾路徑
    - outputYolo/outputcocoGTDir: FOV60/labels 資料夾路徑
    - outputYolo/outputcocoImgDir: FOV60/images 資料夾路徑

    2-2.執行指令：`python xmltoYolo.py`
    * ***執行該指令前務必先改好orig_h和orig_w為輸入照片的長寬***
    * Note:注意以下程式片段!
    ![](https://i.imgur.com/gGpSmwS.png)
    * orig_h代表輸入照片的長度
    * orig_w代表輸入照片的寬度
    * 竹北場域的照片為1920*1208(w x h)
    * 熱感應項目的RGB照片為608*342(w x h)
    * 熱感應項目的thermal照片為640*512(w x h)

3. 進行驗證
    3-1. 修改 label_tool.py 內之路徑 
    * 範例
        (line ～224) self.inDir ---> FOV60/front_bottom_60/images
        (line ～235) self.outDir ---> FOV60/front_bottom_60/labels
        
    3-2. 執行指令`python label_tools`
    * label_tool相關資訊
        - 前製作業: 安裝ImageTk
            - sudo apt-get update
            - sudo apt-get install python-pil.imagetk
        - 類別/顏色
                # person --> blue
                # bicycle --> yellow
                # car --> red
                # motorbike --> purple
                # bus --> orange
                # truck --> green
                # trafficcone --> black
        - 操作指令(在tool的圖形介面上操作)
            - m: 進入drag模式 ***default是draw模式, 務必先按'm'做切換!***
            - \>: 下一張圖片
            - <: 上一張圖片
            - k: 刪除物件框 (先進入drag模式, 點在該框上按k即可)
        (***補一張實際跑起來的圖***)

* Note: 
    - 將驗證結果整理成label_problem投影片 (記得要上傳至 NAS)
    - 檔名： ITRI_U300_label_problem_III回傳資料的時間
    - 首頁副標題註記 單位姓名 + 投影片撰寫日期 + 投影片涵蓋之III標記檔名
    - 傳給III修正回傳後重新執行步驟三, 直到沒有標記錯誤為止, 再進行第四步驟
    - 確認無誤後上傳至 NAS
        /Data_1/Dataset/DriveNet/Labeled/原robag日期/
        
## 步驟四: 資料分集

1. 根據以下樹狀圖建立資料夾 (方便上傳至NAS)
		├── `資料夾3/` 
		│   ├── `train/`
		│   ├── `valid/`
		│   ├── `Test_Dataset/ ----> 統計/確認個別場景的圖片張數,再放入all`
		│   ├── `Train_Dataset/`
		│   ├── `separate.sh`
		│   ├── `FOV30_60/ ----> 本次新增的 FOV30跟60`
		│   │   ├── `Test_Dataset/`
		│   │   ├── `Train_Dataset/`
		│   ├── `FOV120/ ----> 本次新增的 FOV120`
		│   │   ├── `Test_Dataset/`
		│   │   ├── `Train_Dataset/`
		│   ├── `All/ ----> 本次新增的全部`
		│   │   ├── `Test_Dataset/`
		│   │   ├── `Train_Dataset/`
        
* Note: 依需求可以再增加 ITRI_Day, ITRI_Night, ITRI_Rainy, HSR_ClearNight, HSR_RainyNight, HSR_ClearDay 資料夾

2. 將本次要新增之場景, 一次一顆相機, 將已確認無誤的標記檔(.txt)與圖檔(.jpg), 貼到'資料夾3'底下
3. 建議可以更改檔名, 避免資料龐大的 Dataset 中有名字重複造成錯誤
    * 可在terminal執行以下指令
			i=0; \\
			for f in *; do \\
			 new_f=原rosbag日期_場景_相機_${i}.jpg; \\
			 echo ${new_f}; \\
			 mv ${f} ${new_f}; \\
 			 i=\`expr $i + 1`; \\
			done
    * 純指令範例
    i=0; for f in *; do new_f=${i}\_0622_HSRRainyNight_rf60_\`echo ${f}\`;echo ${new_f}; mv ${f} ${new_f}; done
4. 執行 `sh seperate.sh`
    * Note:
        - 執行後會依照4:1的比例將目前在'資料夾3'底下的檔案隨機分配至 train 與 valid 資料夾
        - 一次一顆相機分配較平均, 可避免同顆相機在train/test資料集的比例過高

5. 把照片放到先前創好的分類資料夾中：
    * 執行指令：
    `cp valid/* 分類資料夾/Test_Dataset`
    `cp train/* 分類資料夾/Train_Dataset`
* Note:
    - 將新增的結果統計更新至 excel表
        * 可透過以下指令計算該資料夾底下新增的標記檔張數
            find "$PWD"/ -iname '*.jpg' | wc -l
    - 將新增的 Dataset上傳至 NAS
        FOV30-60上傳至: /10T-2/Dataset/DriveNet/Dataset_Fov60/更新日期
        FOV120上傳至: /10T-2/Dataset/DriveNet/Dataset_Fov120/更新日期
    - 將本次新增的Dataset加上過去的Dataset合併後上傳至 NAS
        /10T-2/Dataset/DriveNet/DatasetAll/更新日期
    - 將本次的 Dataset 加入對應 Dataset
        /media/owo/PATRIOT/NewDataset/Dataset_場景(day, night, rainy, hsr_rainynight, hsr_clearnight)

## Extra: 80 class資料與 7 class資料轉換 (***NAS上面抓tool資料夾，以及重寫該檔案***)：
利用changeLabelNumber.py可將80 class類別轉為7 class
* 執行指令：`python changLabelNumber.py /<your path to txt label files>`
* Note: 
    * 將replace函數的條件與return值交換即可將7 class寫回80 class。
    * replace以及replace_cone這兩個函數當中會去判定`s==9`的原因是因為當初有一些三角錐的資料被誤植為9了，但它在7 class中應該要是6，在80 class中應該要是8。