pythonのglobで末端のファイル名だけ取得したい
pythonのglob.globによるファイル名の一括取得。便利ですよね。
glob君に任せ切りにしていたら一瞬迷ったのでメモとして残します。
全然大した話ではないのですし、もっと良いやり方があるかもしれません。
2020/05/17 15:20 追記
os.path.basename()
これで行けるらしい。俺がアホだった。
cv2.imwrite(new_dir + os.path.basename(file1), merge_img)
問題
こんな処理をしたい時がありました。
- 二つのファイルに同じ名前だが異なる処理をした画像がある。
- これらのファイルから同じ名前の画像を読み込み横につなげる。
- 別のファイルに元と同じ名前で書き出す。
ファイル構造はこんな感じ。名前は連番ではない場合もあります。
current_dir/ ┠ gattai.py ┠ images_A/ ┃ ┠ abcdefg.png ┃ ┠ hijk.png ┃ ┠ lmnopq.png ┃ ┠ 以下略 ┠ images_B/ ┃ ┠ abcdefg.png ┃ ┠ hijk.png ┃ ┠ lmnopq.png ┃ ┠ 以下略
↑を↓にしたい。
current_dir/ ┠ gattai.py ┠ images_A/ #略 ┠ images_B/ #略 ┠ images_C/ #自分で名前をつけて作成 ┃ ┠ abcdefg.png #処理されて合体した画像 ┃ ┠ hijk.png ┃ ┠ lmnopq.png ┃ ┠ 以下略
最初は何も考えずこんなコードを書きました。
import numpy as np import cv2 import os import glob import sys import re args = sys.argv filename1 = args[1] #images_A filename2 = args[2] #images_B outname = args[3] #images_C if __name__ == "__main__": new_dir = outname + "/" os.makedirs(new_dir, exist_ok=True) #出力用のファイルを生成 files1 = glob.glob(filename1 + "/*.png") #ファイル内の画像のパスを取得 files1.sort() files2 = glob.glob(filename2 + "/*.png") files2.sort() for file1, file2 in zip(files1, files2): #読み込む画像パスを名前をループで取得 img1 = cv2.imread(file1) img2 = cv2.imread(file2) images = [img1, img2] merge_img = np.concatenate(images, axis=1) cv2.imwrite(new_dir + file1, merge_img)
実行してみると…
python3 gattai.py images_A images_B images_C
実はこの部分がまずい。
new_dir + file1 ## => images_C/images_A/hogehoge.png
globで取得したfile1には
images_A/hogehoge.png
というように相対パスが全て書き込まれます。
os.makedirs(new_dir, exist_ok=True)
で作成したのはimages_Cまでなのでその中のimages_Aは作成されておらず画像は保存できません。
解決
pythonの文字列分割機能を使って解決しました。
qiita.com
phrase = "If you can dream it you can do it" # 「split」使用 .split(区切り文字, 分割数) print(phrase.split()) ## => ["If","you","can","dream","it","you","can","do","it"] word = "HelloWorld" # 「rsplit」使用 .rsplit(区切り文字, 分割数) print(word.rsplit("l",1)) ## => ['HelloWor', 'd']
今回globで取得したパスは
/images_A/hogehoge.png
取得したいのはhogehoge.pngの部分なので、"/"で区切った末端の部分を取れば良いですね。
phrase.split("/") ## => ["", "images", "hogehoge.png"] phrase.split("/")[-1] ## => ["hogehoge.png"]
ということで最後のcv2.imwriteをこのように書き換えました。
cv2.imwrite(new_dir + file1.split("/")[-1], merge_img)
これで当初の狙い通りの出力になりました。めでたし。