# 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檔](https://i.imgur.com/bP9tBW2.png) @ csv檔的內文如下: ![csv檔內容](https://i.imgur.com/H8rsRYt.png) @excel匯入.csv檔時,使用 UTF-8 編碼 (這邊用LibreOffice excel 畫面示意,沒有Microsoft excel) ![](https://i.imgur.com/3cpKyGu.png) @ 匯入excel 後方便確認比對符合和比對不符合的(對照資料夾有但現有資料夾沒有)檔案 ![](https://i.imgur.com/kCAN11w.png) 程式: - 選取新、舊資料夾路徑(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" : ![](https://i.imgur.com/OPr0ymS.png) 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` ### 需求 ![](https://i.imgur.com/nFt8lB1.png) 複製 .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提交檔案\測試 ``` ---