PythonでImageJを使うときに保存する際のpathのあれこれ

線虫の二値化を行ってROIを取得し、そのROIで蛍光測定するプログラムを作りました。
(このプログラムについては公開するのかどうか、していいのかどうかよくわからないので興味ある方はお声がけ頂ければ個別に対応します。）

そのプログラムの過程で、ROI、測定結果(形態、蛍光値)等々のデータoutputにおいて、pathの処理や保存行程で少々手間取ったので備忘録的に書き残しておきます。

まずベースに参考にしたサイト様達

https://satoshithermophilus.hatenablog.com/entry/2017/06/12/195827

http://wiki.cmci.info/documents/130800snb


画像解析にPythonを導入した経緯として、七面倒くさい諸々の処理を何回もやるのが鬱陶しいのでバッチ処理を施して楽にしようという魂胆がありました。そのため、複数の画像に処理を欠けられるシステムが先決。

そこで、Fijiでバッチ処理を行うファイルを選択するために、フォルダを選ぶ行程があるのですが、それは上記の2サイトどちらでもjavaのシステムであるDirectoryChooserを使用しているんですよね。僕はjavaについて何も知らないので、pythonのシステムからこれを実現しようかと試みて、tkinterというGUIからフォルダ選択の出来るシステムは見つけました。

ただこれが、Cpythonの機能で、javaを動かすFijiのJythonでは使えなさそう、というところにたどり着いたので、結局DirectoryChooserを使用することになりました。

```Python
# Open dialog to choose folder
srcDir = DirectoryChooser("Choose directory").getDirectory()
IJ.log("directory: " + srcDir)
```

これで、srcDirに格納されるのは何か。
解答としては選んだpathになります。それは下のlogのところで確認できるんですけどね。

```python
# search tif file in srcDir and analyze tif file by worm_binary()
for root, directories, filenames in os.walk(srcDir):
    for filename in filenames:
        if filename.endswith(".tif"):
            filepath = os.path.join(root, filename)
            IJ.log("Image file path: " + filepath)
            worm_binary(filepath)
```
それで、上で選んだファイルの中からtiffファイル(拡張子.tif)のファイルをos.walkで探して、そのファイルに関数の処理をかける、っていう形。あまりここの内容について理解していない。

```python
    #Save
    savefilepath = os.path.splitext(os.path.basename(imagepath))[0]
    IJ.log("savefilepath:"+savefilepath)

    #make "Result" directory (only first time)
    result_directory = os.path.join(srcDir,"result")
    if not os.path.exists(result_directory):
        os.makedirs(result_directory)
        IJ.log("result_Directory:" + os.path.abspath(result_directory))

    #make Result directory of every images 
    savedirpath = os.path.join(result_directory,str(savefilepath))
    IJ.log("savedirpath:"+os.path.abspath(savedirpath))
    os.makedirs(savedirpath)
    savepath = os.path.join(savedirpath,str(savefilepath))

```
本題。関数中の保存処理について。
一段落目。
savefilepathは画像の絶対path(filepath→Imagepath）だったものから、basenameとsplittextを使って、拡張子なしのファイル名として取り出す。

```
filepath:C\User\gazou\analytics\hoge1.tiff
savefilepath:hoge1
```
となる。

二段落目。
Resultのフォルダを作成する。そしてその中に画像毎の解析結果をそれぞれ保存するためのフォルダを作ることを目的にする。
result_directoryはsrcDirで取得したフォルダの絶対パスにresultをくっつけた物にする。つまり、このpathもフォルダを差す。このフォルダが存在しなければmakedirsで作ってね、と操作する。

```
srcDir:C\User\gazou\analytics
result_directory:C\User\gazou\analytics\result
```
となる。

三段落目。

```python
#make Result directory of every images 
savedirpath = os.path.join(result_directory,str(savefilepath))  
IJ.log("savedirpath:"+os.path.abspath(savedirpath))
os.makedirs(savedirpath)
savepath = os.path.join(savedirpath,str(savefilepath))
```

二段落目で作ったresultフォルダに、一段落目で取った画像のpathの名前でフォルダを作り、それをsavedirpathとする。
それでsavepathをさらにつくり、savedirpathにsavefilepathをさらにくっつける。これについて何で？っていう疑問は次に解決されるので。

```
savedirpath:C\User\gazou\analytics\result\hoge1
savepath:C\User\gazou\analytics\result\hoge1\hoge1
```

次にImageJのIJモジュールに含まれるsaveAsの機能を利用して保存する。

```python    
IJ.saveAs("Results", savepath + "_figure" + ".csv") #Save ROI parameta  
IJ.saveAs(binimp,"bmp", savepath + "_ROI.bmp") #Save ROI Image
IJ.saveAs("Drawing of DUP_C1-" + imagepath, savepath + "ROI.bmp")
rm.runCommand("Save", savepath + "_ROI.roi") #Save ROI Data
```

ここで、IJ.saveAsの機能の話になるが
IJ.saveAs(A,B)と書かれていると、Aの内容をBという「名前」で保存する、というシステムになっている。
一番上の物で行くと、Resultsをsavepathにfigure.csvという名前をくっつけて保存することになる。
つまり

```
savepath:C\User\gazou\analytics\result\hoge1\hoge1
result:savepath:C\User\gazou\analytics\result\hoge1\hoge1_figure.csv
```

つまり、最後のhoge1はファイル名に含まれてしまう。そのため、savedirpathのままだとresultフォルダ内のhoge1フォルダにファイルが作られず、resultフォルダにファイルが作られることになる。

path名でこんがらがるが、logの機能を上手く使っていくと、何がおかしいのかは理解しやすくなるので、デバッグの際はこの記事を参考にしつつ、上手くlogに出力してやってみてほしい。



p.s.
こんな感じのpythonの画像解析をやっている修士2年です。似たような開発をしている研究室の方がもしもお読みになりましたら連絡して頂けると喜びます。