# python 腳本整理
---
# 頁首
https://hackmd.io/@cssmiley/SJ4MDTPLj
檔案位置: https://drive.google.com/drive/folders/1ORXhxrOXyHKQ9HvkS0dvmKb4rn5SgCg5?usp=sharing
|-[使用 kivy ,Camera + autopredictor 拍照後傳回辨識檔案,使用 python kivy套件寫 iOS 和 Android APP](https://hackmd.io/@cssmiley/rk3T64_l3)
|- [打包作業: .py打包成.pyd 動態連接檔和.exe 執行檔交給客戶](#打包作業)
<details><summary>打包作業推薦寫法</summary>
推薦使用方法1. ,不用一個一個--follow-import-to=xxx 導入第三方模組
1. 生成 .pyd 時不匯入第三方模組((python IDLE內可匯入 .pyd 使用), 所有import加入到 main.py 再生成 .exe
```
nuitka --module data_analysis.py
=> 產生 data_analysis.pyd
nuitka --module auto_predictor.py
=> 產生 auto_predictor.pyd
在 main.py 加入 import requests,tqdm,lxml (auto_predictor.py 和 data_analysis.py所需的第三方模組)
nuitka --standalone --onefile main.py
=> 產生 main.exe (不依賴於python3x.dll)
```
</details>
|- jpg_xml_rename.py
<details><summary>jpg_xml_rename.py寫法</summary>
</details>
|- [files_dispatch.py 資料夾比對](#資料夾比對)
<details><summary>資料夾比對 寫法</summary>
- 執行 python:
```
下面指令會把 [path 資料夾]內.jpg .xml 檔, 比對 [cpath 資料夾] 內的檔案,符合的放到 matched 資料夾,不符合的放到 unmatched 資料夾,剩下的放到 other 資料夾
> python3 files_dispatch.py --path "現在資料夾路徑" --cpath "對照資料夾路徑"
例如.
> python3 files_dispatch.py --path D:\labelImg提交檔案 --cpath D:\labelImg提交檔案\對照資料夾
可以把上面的 --path --cpath 換成簡寫的 -p -c ,如下所示(空格是為了和上面清楚對照可以不需要這麼多空格)
> python3 files_dispatch.py -p "現在資料夾路徑" -c "對照資料夾路徑"
例如.
> python3 files_dispatch.py -p D:\labelImg提交檔案 -c D:\labelImg提交檔案\對照資料夾
```
</details>
|- [xml_node_move.py 置換劣化節點](#置換劣化節點)
<details><summary>置換劣化節點 寫法</summary>
- 執行 python:
```
@ 置換劣化類別:
下面指令會使用 [new_folder 資料夾]內的[deteriorate指定劣化類別節點],替代掉 [old_folder 資料夾]內的指定劣化類別節點
> python3 xml_node_move.py --deteriorate crack efflorescence --old_folder "要被置換的舊節點資料夾路徑" --new_folder "新節點資料夾路徑"
> python3 xml_node_move.py --deteriorate
簡寫
> python3 xml_node_move.py -d crack efflorescence -o "要被置換的舊節點資料夾路徑" -n "新節點資料夾路徑"
@ 保留劣化類別:
下面指令會使用 --new_folder 資料夾內的指定保留劣化類別以外的所有節點 --keep_deteriorate , 替代掉 --old_folder 內的指定劣化類別節點
> python3 xml_node_move.py --keep_deteriorate crack efflorescence --old_folder "要被置換的舊節點資料夾路徑" --new_folder "新節點資料夾路徑"
簡寫
> python3 xml_node_move.py -k crack efflorescence -o "要被置換的舊節點資料夾路徑" -n "新節點資料夾路徑"
```
</details>
|- [xml_node_rename.py 更改標註名稱](#更改標註名稱)
<details><summary>更改標註名稱 寫法</summary>
```
把[path資料夾]內的[old_tag舊劣化名稱]置換成[new_tag新劣化名稱]
> python3 xml_node_rename.py --path "資料夾路徑" --old_tag "舊劣化名稱" --new_tag "新名稱"
> python3 xml_node_rename.py --path D:\labelImg提交檔案 --old_tag crack_01 water_gain --new_tag crack_fissures infiltration_crack
可以把上面的 --path --old_tag --new_tag 換成簡寫的 -p -o -n ,如下所示
> python3 xml_node_rename.py -p D:\labelImg提交檔案 -o crack_01 water_gain -n crack_fissures infiltration_crack
```
</details>
|- [xml_parse_count.py 計算劣化數量](#計算劣化數量)
<details><summary>計算劣化數量 寫法</summary>
- 執行 python檔:
```
> python3 xml_parse_count_csv.py -p "要處理的資料夾路徑"
> python3 xml_parse_count_csv.py -p D:\labelImg提交檔案\測試
> python3 xml_parse_count_csv.py -r "要處理的遞迴資料夾路徑"
> python3 xml_parse_count_csv.py -r D:\labelImg提交檔案\
```
- 印出總數及各劣化數量如下範例:
```
Total xml : 6, defaultdict(<class 'int'>, {'crack_00': 3, 'rusty_water': 1, 'spalling': 4, 'crack_AC': 1, 'crack': 1, 'corrosion': 1})
```
</details>
|- [xml_parse_count_csv.py 計算劣化數量](#計算劣化數量)
<details><summary>寫法</summary>
- 執行 python檔:
```
`> python3 xml_parse_count_csv.py "要處理的資料夾路徑"`
- 印出總數及各劣化數量如下範例:
`Total xml : 6, defaultdict(<class 'int'>, {'crack_00': 3, 'rusty_water': 1, 'spalling': 4, 'crack_AC': 1, 'crack': 1, 'corrosion': 1})`
- 輸出 .csv 檔包含劣化數量資訊方便匯入到 excel 處理
(_csvfile.csv 存放處理一個資料夾的結果)
(_csvtotal.csv 存放處理多個資料夾的結果,用excel 匯入來加總所有處理資料夾的結果)
```
</details>
|- [xml_parse_split_deteriorate.py 分離劣化資料](#分離劣化資料)
<details><summary>分離劣化資料 寫法</summary>
- 執行 python檔:
```
> python3 xml_parse_split_deteriorate.py -p "要處理的資料夾路徑"
e.g. python3 xml_parse_split_deteriorate.py -p D:\labelImg提交檔案\測試xml_parse_split_deteriorate\檔案重複bug測試
> python3 xml_parse_split_deteriorate.py -r "要遞迴處理的資料夾路徑"
e.g. python3 xml_parse_split_deteriorate.py -r D:\labelImg提交檔案\測試xml_parse_split_deteriorate\檔案重複bug測試
```
輸出單一劣化資料到對應的資料夾,複製.jpg 圖片檔並抽取單一劣化 .xml 檔進資料夾
</details>
|- python_image_upload.py
<details><summary>python_image_upload.py 寫法</summary>
</details>
|-image_filter.py
<details><summary>image_filter.py 寫法</summary>
'''
## 使用
- 需安裝套件 : conda install -c conda-forge opencv
python3 -m pip install opencv-python
(ref: https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwi_t9_Rwov5AhVMqVYBHdLODrQQFnoECCcQAQ&url=https%3A%2F%2Fresearchdatapod.com%2Fpython-modulenotfounderror-no-module-named-cv2%2F&usg=AOvVaw2_s76JWRae1yekPVnlgZhZ)
- 將這個 .py 檔放到想篩選圖片的資料夾內
- 執行 python檔: python3 image_filter.py
- 若有不符合之色碼會新建資料夾,複製.png圖片檔進資料夾,並建立 .csv檔,顯示不符合色碼之 [X座標, y座標, 色碼],可用 Excel 匯入 .csv檔查看
## 需求
- 請使用者輸入符合色碼組(零到多組不等)
- 選擇想篩選的資料夾(內含 .jpg .png .xcf)
- 讀取圖片,只讀取 png 檔
- 遍歷圖片所有 pixel
- 取得每一 pixel 的 hex 色碼
- 判斷是否符合輸入篩選的色碼組
- 若不符合,
- 檢查資料夾是否存在,若不存在就新增資料夾
- 檢查圖片是否存在,若不存在就複製圖片檔到新資料夾內
- 新增csv檔
- 紀錄xy位置和色碼
- [excel] 在 excel 整理出不符合單一色碼(e.g. 若有 3 個不符合的 #ffffff 色碼,只記錄一個 #ffffff)
- 模組化
'''
"""
- 請使用者輸入符合色碼組(零到多組不等)
- 選擇想篩選的資料夾(內含 .jpg .png .xcf)
- 讀取圖片,只讀取 png 檔
- 遍歷圖片所有 pixel
- 取得每一 pixel 的 hex 色碼
- 判斷是否符合輸入篩選的色碼組
- 若不符合,新增資料夾,複製圖片檔到新資料夾內,新增csv檔,紀錄xy位置和色碼,在 excel 整理出不符合單一色碼(e.g. 若有 3 個不符合的 #ffffff 色碼,只記錄一個 #ffffff)
"""
</details>
---
## 打包作業:
.py打包成.pyd 動態連接檔和.exe 執行檔交給客戶
[回頁首](#頁首)
檔案準備:
303,104 data_analysis.cp39-win_amd64.pyd
3,524,096 auto_predictor.cp39-win_amd64.pyd (會 import data_analysis)
main.py (會 import auto_predictor)
注意事項:
打包環境需要有要 import 的模組,requests、tqdm、lxml
### 整理
```
auto_predictor.py (匯入import data_analysis)
data_analysis.py
main.py (匯入import auto_predictor)
```
打包環境中必須有所需的第三方模組,以這邊為例是需要 requests, tqdm, lxml
推薦使用方法1. ,不用一個一個--follow-import-to=xxx 導入第三方模組
1. 生成 .pyd 時不匯入第三方模組((python IDLE內可匯入 .pyd 使用), 所有import加入到 main.py 再生成 .exe
```
nuitka --module data_analysis.py
=> 產生 data_analysis.pyd
nuitka --module auto_predictor.py
=> 產生 auto_predictor.pyd
在 main.py 加入 import requests,tqdm,lxml (auto_predictor.py 和 data_analysis.py所需的第三方模組)
nuitka --standalone --onefile main.py
=> 產生 main.exe (不依賴於python3x.dll)
```
2. 生成 .pyd 時匯入必要第三方模組(python IDLE內匯入 .pyd 會出現錯誤但打包 .exe 後可正常運作), 生成 .exe
```
用 --follow-import-to=xxx 加入第三方模組
nuitka --module data_analysis.py
=> 產生 data_analysis.pyd
nuitka --module --follow-import-to=requests --folow-import-to=tqdm --follow-import-to=lxml auto_predictor.py
=> 產生 auto_predictor.pyd
nuitka --stanalond --onefile main.py
=> 產生 main.exe
** 使用--windows-disable-console 產生執行 main.exe 時,不跳出 cmd 視窗**
nuitka --standalone --onefile --windows-disable-console main.py
```
---
## 資料夾比對
[回頁首](#頁首)
files_dispatch.py
需求:
1. 指定 現在資料夾路徑 和 對照用的資料夾路徑 進行比對 .xml .jpg 檔案
2. 把比對符合 對照用資料夾 內的檔案存放到 matched 資料夾,不符合的放到 unmatched 資料夾,把剩下的 .xml .jpg 檔案存放到 other 資料夾
3. 產生 紀錄有比對符合 matched 和比對不存在的(對照資料夾有但現有資料夾沒有) unmatched 列表的 .csv 檔案(方便用 excel 匯入查看確認)
@ 紀錄有比對符合 matched 和比對不存在的(對照資料夾有但現有資料夾沒有) unmatched 列表的 .csv 檔案

@ csv檔的內文如下:

@excel匯入.csv檔時,使用 UTF-8 編碼 (這邊用LibreOffice excel 畫面示意,沒有Microsoft excel)

@ 匯入excel 後方便確認比對符合和比對不符合的(對照資料夾有但現有資料夾沒有)檔案

程式:
- 選取新、舊資料夾路徑(GUI或手動填)-手動填
- 比對 對照資料夾 和 原資料夾是否有相符的檔案,並移動 .jpg .xml 檔案到 matched 資料夾和 unmatched 資料夾
- 寫入比對符合和比對不存在的(對照資料夾有但現有資料夾沒有)檔案名稱到 .csv檔方便確認
- 將比對完移動後,剩下來的 .jpg .xml 檔案移動到 other 資料夾
使用:
- 安裝套件 : 不需安裝,使用內建lib
- 執行 python:
```
下面指令會把 --path 資料夾內.jpg .xml 檔, 比對 --cpath 內的檔案,符合的放到 matched 資料夾,
不符合的放到 unmatched 資料夾,剩下的放到 other 資料夾
> python3 files_dispatch.py --path "現在資料夾路徑" --cpath "對照資料夾路徑"
例如.
> python3 files_dispatch.py --path D:\labelImg提交檔案 --cpath D:\labelImg提交檔案\對照資料夾
可以把上面的 --path --cpath 換成簡寫的 -p -c ,如下所示(空格是為了和上面清楚對照可以不需要這麼多空格)
> python3 files_dispatch.py -p "現在資料夾路徑" -c "對照資料夾路徑"
例如.
> python3 files_dispatch.py -p D:\labelImg提交檔案 -c D:\labelImg提交檔案\對照資料夾
```
指令參數說明:
```
-p, --path
現在資料夾 路徑,例如. `D:\labelImg提交檔案`
-c, --cpath
用來比對用的 .xml 檔所在的 對照資料夾 路徑,例如. `D:\labelImg提交檔案\對照資料夾`
```
---
## 更改標註名稱
[回頁首](#頁首)
xml_node_rename.py
需求:
1. 指定資料夾路徑,舊劣化名稱、新劣化名稱
2. 把資料夾內的 .xml 檔內的舊劣化名稱置換成新劣化名稱
3. 防呆:
```
若原本的劣化有 crack_01 efflorescence,更名時誤下指令 把 crack_01 更名成 efflorescence 而不是原本要換的 crack_fissures,
會造成更名後的 efflorescence(實際上是裂縫龜裂) 和原本已經有的 efflorescence(白華) 混在一起,變成全部都必須重新人工標註修正,
因此需要在更名時,若更改名稱和已有的劣化名稱重疊,需提示
```
4. 注意事項!!: (!!注意!! 程式無法判斷,所以須正確下指令或是一次執行指處理一個劣化名稱比較保險)
```
下指令時 --old_tag 和 --new_tag 項目需前後對照順序一致
例如.
(O)正確的例子
` --old_tag crack_01 water_gain --new_tag crack_fissures infiltration_crack`
crack_01 對到 crack_fissures, water_gain 對到 infiltration_crack
(X) 錯誤的例子
--old_tag crack01 water_gain --new_tag infiltration_crack crack_fissures
crack_01 對到 infiltration_crack, water_gain 對到 crack_fissures
```
程式:
- 選取資料夾路徑(GUI或手動填)-手動填 , 指定舊劣化名稱、新劣化名稱
- 遍歷選取資料夾讀取 .xml 檔,取得劣化資訊
- 防呆: 比對劣化資訊,若更改名稱是已存在劣化標註,就詢問確認
- 更換指定的舊的劣化類別名稱,並寫入到 .xml 檔
使用:
- 安裝套件 : 不需安裝,使用內建lib
- 執行 python:
```
下面指令會把 --path 資料夾內的 --old_tag 舊劣化名稱 置換成 --new_tag 新劣化名稱
> python3 xml_node_rename.py --path "資料夾路徑" --old_tag "舊劣化名稱" --new_tag "新名稱"
> python3 xml_node_rename.py --path D:\labelImg提交檔案 --old_tag crack_01 water_gain --new_tag crack_fissures infiltration_crack
可以把上面的 --path --old_tag --new_tag 換成簡寫的 -p -o -n ,如下所示
> python3 xml_node_rename.py -p D:\labelImg提交檔案 -o crack_01 water_gain -n crack_fissures infiltration_crack
```
指令參數說明:
```
-p, --path
指定被置換掉的 .xml 檔案所在的資料夾路徑,例如. `D:\labelImg提交檔案`
-o, --old_tag
要被置換掉的劣化類別名稱,例如. crack_01
-n, --new_tag
用來置換的調劣化類別名稱,例如. crack_fissures
```
- 將 old 資料夾的 .xml檔內的特定劣化節點名稱(e.g. <crack_01> ) 換成新名稱(e.g. <crack_fissures>)
---
## 置換劣化節點
[回頁首](#頁首)
xml_node_move.py
需求:
1. 指定 old xml 和 new xml 路徑 (檔名相同) 及更動的劣化類別
2. 新建 xml,裏面包含 old xml 移除特定劣化類別節點 (ex. <crack>)後,把 new xml 特定劣化類別節點 append 到 old xml ,放到 replaced 資料夾
程式:
- 選取新、舊資料夾路徑(GUI或手動填)-手動填 , 指定劣化類別
- 遍歷選取資料夾讀取 .xml 檔
- 新建空xml,裡面包含移除舊的劣化類別節點,將更動的劣化類別節點複製,並寫入到舊的 .xml 放到 replaced 資料夾(沒有更動 old xml 和 new xml)
使用:
- 安裝套件 : 不需安裝,使用內建lib
- 執行 python:
```
@ 置換劣化類別:
下面指令會使用 --new_folder 資料夾內的指定劣化類別節點 --deteriorate , 替代掉 --old_folder 內的指定劣化類別節點
> python3 xml_node_move.py --deteriorate crack efflorescence --old_folder "要被置換的舊節點資料夾路徑" --new_folder "新節點資料夾路徑"
可以把上面的 --deteriorate --old_folder --newfolder 換成簡寫的 -d -o -n ,如下所示(空格是為了和上面清楚對照可以不需要這麼多空格)
> python3 xml_node_move.py -d crack efflorescence -o "要被置換的舊節點資料夾路徑" -n "新節點資料夾路徑"
@ 保留劣化類別:
下面指令會使用 --new_folder 資料夾內的指定保留劣化類別以外的所有節點 --keep_deteriorate , 替代掉 --old_folder 內的指定劣化類別節點
> python3 xml_node_move.py --keep_deteriorate crack efflorescence --old_folder "要被置換的舊節點資料夾路徑" --new_folder "新節點資料夾路徑"
可以把上面的 --keep_deteriorate --old_folder --newfolder 換成簡寫的 -k -o -n ,如下所示(空格是為了和上面清楚對照可以不需要這麼多空格)
> python3 xml_node_move.py -k crack efflorescence -o "要被置換的舊節點資料夾路徑" -n "新節點資料夾路徑"
```
指令參數說明:
```
-d 置換劣化節點 和 -k 保留劣化節點 是互斥選項,無法同時執行
-d, --deteriorate
指定要置換的劣化類別,可指定一個到多個,例如. `-d crack` 或 `-d crack efflorescence`,這些劣化類別的節點會被置換掉
-k, --keep_deteriorate
指定保留的劣化類別,可指定一個到多個, 例如. `-k crack` 或 `-k crack efflorescence`,除了指定的劣化類別外都會置換成新的版本
-o, --old_folder
要被置換掉的 .xml 檔案所在的資料夾路徑,例如. `D:\labelImg提交檔案`
-n, --new_folder
用來置換的調整過後的新劣化節點的 .xml 檔所在的資料夾路徑,例如. `D:\labelImg提交檔案\白華_efflorescence`
```
- 將 old 資料夾的 .xml檔內的特定劣化節點資訊(e.g. <crack>附帶的框選位置尺寸資訊) 換成 new 資料夾的 .xml檔的劣化節點資訊
---
## 計算劣化數量
[回頁首](#頁首)
```
xml_parse_count.py # 只計算數量不輸出 .csv 檔
xml_parse_count_csv.py # 計算數量並輸出 .csv檔
```
### 需求
"執行的資料夾名稱_csvfile.csv" 存放處理一個資料夾的結果,計算的是以一個框選為單位,只要一個框選標註數量就加 1
"_csvtotal.csv" 存放處理多個資料夾的結果,用excel 匯入來加總所有處理資料夾的結果,計算的是以一張圖出現該種劣化為單位,一張圖有出現劣化計數就加 1,不管多少框選都只算 1 個,下圖說明 對不同資料夾執行多次產生的 "_csvtotal.csv" :

1. 計算劣化數量
- 選取資料夾路徑(GUI或手動填)-手動填
- 遍歷選取資料夾讀取 .xml 檔
- 列出該張圖片的所有劣化分類
- 計算各項劣化圖片總數量
## 使用
- 安裝套件 : 不需安裝,使用內建lib
- 執行 python檔:
```
> python3 xml_parse_count_csv.py -p "要處理的資料夾路徑"
> python3 xml_parse_count_csv.py -p D:\labelImg提交檔案\測試
> python3 xml_parse_count_csv.py -r "要處理的遞迴資料夾路徑"
> python3 xml_parse_count_csv.py -r D:\labelImg提交檔案\
```
- 印出總數及各劣化數量如下範例:
`Total xml : 6, defaultdict(<class 'int'>, {'crack_00': 3, 'rusty_water': 1, 'spalling': 4, 'crack_AC': 1, 'crack': 1, 'corrosion': 1})`
- 輸出 .csv 檔包含劣化數量資訊方便匯入到 excel 處理
(_csvfile.csv 存放處理一個資料夾的結果)
(_csvtotal.csv 存放處理多個資料夾的結果,用excel 匯入來加總所有處理資料夾的結果)
---
## 分離劣化資料
[回頁首](#頁首)
`xml_parse_split_deteriorate.py`
### 需求

複製 .jpg圖片 和輸出 單一劣化 .xml檔 到新建的單一劣化資料夾
前置作業:
- 比對同一張圖片的多重劣化和個單一劣化的 xml 內容結構差異,確認需更改的地方
程式:
- 選取資料夾路徑(GUI或手動填)-手動填
- 遍歷選取資料夾讀取 .xml 檔
- 將劣化類別複製,並寫入到分別的劣化類別 .xml 檔
- 複製.jpg圖片到劣化類別資料夾
- 模組化
使用
安裝套件 : 不需安裝,使用內建lib
將這個 .py 檔放到想篩選圖片的資料夾內
執行 python檔:
```
> python3 xml_parse_split_deteriorate.py -p "要處理的資料夾路徑"
e.g. python3 xml_parse_split_deteriorate.py -p D:\labelImg提交檔案\測試xml_parse_split_deteriorate\檔案重複bug測試
> python3 xml_parse_split_deteriorate.py -r "要遞迴處理的資料夾路徑"
e.g. python3 xml_parse_split_deteriorate.py -r D:\labelImg提交檔案\測試xml_parse_split_deteriorate\檔案重複bug測試
```
輸出單一劣化資料到對應的資料夾,複製.jpg 圖片檔並抽取單一劣化 .xml 檔進資料夾
注意:
若是windows下,指令使用
```
python xml_parse_split_deteriorate.py -p "D:\labelImg提交檔案\測試\"
```
最後的雙引號會被跳脫路徑名會變成多了雙引號==>
```
D:\labelImg提交檔案\測試"
```
建議後面不加"\":
```
python xml_parse_split_deteriorate.py -p D:\labelImg提交檔案\測試
```
---