PlantCVで植物の分析作業をやってみる

10月も終わりに近付いているというのに、最高気温はまだ25度を越える日があります。秋をとばして冬になるのでしょうか。植物も大変ですね。

# 植物を画像で解析する
植物の品種改良(育種)において、外観から葉の長さや形などを測定する機会がありました。画像であれば、Python で OpenCV でゴニョゴニョすればいろいろできるだろうなと思っていたところ、その名もずばり PlantCV を見つけたので、どのようなものか確認しました。

https://plantcv.org/

PlantCV はオープンソースで植物向けに特化して開発されているようです。リポジトリを見ると開発は続いているようです。チュートリアルを見ると、なんとなく便利そうな機能が紹介されています。
基本的に jupyter notebook で作業しますが、もうひとつ大きなポイントは jupyter notebookでまとめた作業手順を plantcv-run-workflow のしくみでバッチのように多くの画像に当てることができることでしょうか。
品種改良となると、何千何万という苗を選抜するようなので便利な機能だろうと思われます。しかし、日本語の情報がほぼゼロなのが気になります。

# 動かしてみる
チュートリアルのひとつをやってみることにします。骨みたいにして、その形を分析するのが面白そうだったので、Morphology tutorial をやってみました。

https://plantcv.readthedocs.io/en/stable/tutorials/morphology_tutorial/

こんなのが
<img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132817/8049dde3-7bf5-3526-b71f-c484a4448b33.png" />
こんなになります
<img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132817/3257ae0c-e861-f6ff-e780-d151584cc649.png" />
おもしろいですね。
脱線しますが、中をチラっと見たところ、OpenCVと scikit-image を駆使しているようでした。

# workflow を実行してみる
うまく使えば、複数のPCに分散させて処理させることもできるようです。中身は、dask-jobqueue というものを使っているようです。
こまかいところは、ドキュメントにまかせるとして、windows で実行するにあたってポイントだけ。

### 変換した python ファイルを書き変える
まず、ipynb ファイルを通常の python ファイルに変換するのですが、変換したファイルについても、変更場所がいくつかあります。

matplotlibの設定
```python
# matplotlib を notebook 向けに
# get_ipython().run_line_magic('matplotlib', 'widget')
```

workflowのインポート
```python
# from plantcv.parallel import WorkflowInputs
from plantcv.parallel import workflow_inputs
```

引数の受け取り
```python
# args = WorkflowInputs(
#     images=["img/side_view_sorghum.png"],
#     names="image1",
#     result="side_view_morphology_analysis.json",
#     outdir=".",
#     writeimg=True,
#     debug="plot"
# )
args = workflow_inputs()
```

読み込む画像の指定
```python
# img, path, filename = pcv.readimage(filename=args.image1)
img, path, filename = pcv.readimage(filename=args.none)
```
これは、ドキュメントには無かったのですが、args の中身を表示させると名前が付けられず、"none"になっているので、そのように指定しています。

### 実行してみる
workflow の処理手順をjsonファイルに記述して実行します。テンプレートを作ってからこれを修正するのがいいようです。書き変えたjsonファイルを指定しつつ、以下のように実行します。
```
C:\path\to\plantcv>plantcv-run-workflow --config myconfig.json
```
さて実行と思ったのですが、自宅PCで dask がうまく動かず。どうやら windows Home エディションがジャマしているようです。なんか設定を書き変えればいいのかも、とも思ったのですが、続きは別のPC (Pro or Enterprise)でやります。

さて、Home エディションでなくても落とし穴はあって Windows 上では動きません。実は PlantCV用の仮想環境を venv で作っているので、おそらくそのためだろうと思っているのですがこんなエラーが出ます。
```
(.plantcv) C:\path\to\plantcv>plantcv-run-workflow --config myconfig.json
Starting run 2024-xx-xx_xx-xx-xx

Reading image metadata...
Reading image metadata took 0.017763376235961914 seconds.
Building job list...
Task list includes 1 workflows
Building job list took 0.0051288604736328125 seconds.
Processing images...
[                                        ] | 0% Completed |  2.3sBinder detected.
Traceback (most recent call last):
  File "C:\path\to\plantcv\Morphology.py", line 37, in <module>
    from plantcv import plantcv as pcv
ModuleNotFoundError: No module named 'plantcv'
Processing images took 4.16569972038269 seconds.
Processing results...
Processing results took 0.07796859741210938 seconds.
```
plantcv を読み込むことができないらしいです。dask-jobqueueの設定とかでなんとかなるのかと考えていたのですが、回避方法を見つけることができませんでした。

そこで、WSLならどうか、と思って試したところ、すんなり動きました。なんとなく処理も早いような気がしたので、もうこれでいいのかとも思ったのですが、すっきりしません。
もしかしたら、よく勉強されている方は気がついたかもしれませんが、モジュールの import 先についてよく知らなくて、いろいろ調べているうちに、sys.path を発見しました。こいつをWSLで動く python ファイルに仕掛けて動かしてみると、(見やすいように改行を加えています)
```
['/path/to/plantcv',
'/usr/lib/python312.zip',
'/usr/lib/python3.12',
'/usr/lib/python3.12/lib-dynload',
'/path/to/.plantcv/lib/python3.12/site-packages']
```
どうやら、カレントとvenvで構築した仮想環境へのパスを利用しているようです。windowsに戻って同じことをすると、(見やすいように改行を加えています)
```
['C:\\path\\to\\plantcv',
'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312\\python312.zip',
'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312\\DLLs',
'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312\\Lib',
'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312',
'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages']
```
なるほど。そういうことでしたか。なぜか、venvの環境がパスに含まれていません。venvで普通に起動するとどうなっているか確認すると、(見やすいように改行を加えています)
```
['C:\\path\\to\\plantcv',
'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312\\python312.zip',
'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312\\DLLs',
'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312\\Lib',
'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312',
'C:\\path\\to\\.plantcv',
'C:\\path\\to\\.plantcv\\Lib\\site-packages',
'C:\\path\\to\\.plantcv\\Lib\\site-packages\\win32',
'C:\\path\\to\\.plantcv\\Lib\\site-packages\\win32\\lib',
'C:\\path\\to\\.plantcv\\Lib\\site-packages\\Pythonwin']
```
venvの環境がすっぽり抜けていますね。このうち site-packages に plantcv があることは確認できているので、こいつをパスに加えてやればいいかと思われました。なぜ落ちてしまったか不明ですが、環境変数で追加できるようです。PYTHONPATHですね。ドキュメントには追加するとあるので大丈夫でしょう。
```
(.plantcv) C:\path\to\plantcv>echo %PYTHONPATH%
%PYTHONPATH%

(.plantcv) C:\path\to\plantcv>set PYTHONPATH=%VIRTUAL_ENV%\Lib\site-packages

(.plantcv) C:\path\to\plantcv>echo %PYTHONPATH%
C:\path\to\.plantcv\Lib\site-packages
```
ということで、動かしてみると、
```

(.plantcv) C:\path\to\plantcv>plantcv-run-workflow --config myconfig.json
Starting run 2024-xx-xx_xx-xx-xx

Reading image metadata...
Reading image metadata took 0.007285594940185547 seconds.
Building job list...
Task list includes 1 workflows
Building job list took 0.003053903579711914 seconds.
Processing images...
[                                        ] | 0% Completed |  2.3sBinder detected.
['C:\\path\\to\\plantcv', 'C:\\path\\to\\.plantcv\\Lib\\site-packages', 'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312\\python312.zip', 'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312\\DLLs', 'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312\\Lib', 'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312', 'C:\\path\\to\\AppData\\Local\\Programs\\Python\\Python312\\Lib\\site-packages']
Processing images took 8.300228595733643 seconds.
Processing results...
Processing results took 0.09302330017089844 seconds.
```
ちゃんと動きました。よかったです。sys.path にも追加されていますね。

# おわりに
この植物の分析、残念ながら話が立ち消えになってしまったので、PlantCVを駆使するところまではできないようです。日本語の情報が無いのでなにかの参考にと思ったのですが、まぁ、またいつか機会が得られれば。