マイブログ リスト

医療言語処理講座

2020年11月20日金曜日

JSRT vol76No11 「AI による放射線技術の発展」特集号誌上講座

 日本放射線技術学会雑誌 Vol 76 No11 Nov 2020 「AI による放射線技術の発展」特集号誌上講座が発刊されました.

この特集号に「Pydicomを使ってDICOM画像を操る」と題してPydicomの解説とサンプルプログラムを投稿しました.

サンプルプログや補足などを以下に記述します.

1.Pydicomとは

   Pydicomを簡単に紹介しました.


2.Pydicomプログラミングの準備

2.1.前提条件

  • 筆者はAnacondaでPython環境をVersion3.7の環境を構築しました.
  • Anacondaにはnumpy, matplotlib, pyQt5は含まれているので改めてインストールの必要はありません.
もしインストールされていないライブラリがあれば以下からインストールを行ってください.


2.2. DICOM画像データセット

JSRTの標準デジタル画像データベース(DICOM版)の胸部CR画像をダウンロードして解凍します.

2.3.Pydicomのインストール

Pydicomのドキュメント(pydicom documentation,https://pydicom.github.io/pydicom/stable/)も是非参照してください.有用な情報がたくさん得られます.


3.Pydicomを使ってDICOM画像を操る

記事内で紹介したサンプルプログラムをダウンロードして解凍してください.

内容は以下の通りです.

3.1.DICOM画像を表示する

3.2.DICOM画像をPNGに変換する

3.3.DICOM画像の匿名化

3.4.DICOMタグ情報取得の関数化

3.5.セグメンテーションツールを作成する


AI研究のために自施設のDICOM画像を有効に利用できることを願っています.


質問や要望などありましたら uesugi@do-johodai.ac.jp までメールをください.






2020年3月23日月曜日

Pyゼミ0.05 備忘録 Ubuntu18.04にTensorFlowとChainerをインストールする

昨年2019年12月に突然PFN社がChainerの開発の中止を発表.
日本発のAIフレームワークと整然としたコードが好きだったので,長く使おうと思っていたのに開発中止のニュース.
残念です.

世の中のメジャーはGoogleのTensorFlowということで,研究室のUbuntu16.04を18.04にアップグレードと合わせてTensorFlowをインストールしました.
まだ,Chainerの資産があるのでChainerもインストールしておきます.
その他,画像関連のAI開発に必要なライブラリもインストール.
これらの作業の備忘録ですので,見た目は良くないので,勘弁.

Key word:Ubuntu 18.04,TensorFlow,Chainer,GPU


インストールPCの仕様

インストールを行ったPCの仕様は以下の通りです.

  • CPU     Core i7 or i5
  • メモリ  16GB or 8GB
  • GPU       GeForce 1080 or 1060
  • Storage  240GB SSD ~ 1Tb HDD 


行った作業項目

  1. Ubuntu 18.04のインストール(詳細割愛)
  2. NVIDIAドライバーとCUDAのインストール
  3. CUDAのパスを.bashrcに設定する
  4. cuDNNのインストール
  5. Anacondaのインストール
  6. TensorFlowとKerasのインストール
  7. cupyのインストール
  8. Chainerのインストール
  9. OpenCVのインストール(画像処理関連ライブラリ)
  10. DCMTKのインストール(画像圧縮,解凍のツールキット)
  11. ImageJのインストール(DICOM画像のフリービューワ)
  12. Dropboxのインストール(おまけ)


具体的作業手順

1)Ubuntu 18.04 インストール

  • インストールはSecure BootをDisableにしていること.
  • インストール後,アップデートを実行・完了すること.

2)NVIDIA DriverとCUDAのインストール

参考URL

 CUDA Toolkit 10.2 Download
 https://developer.nvidia.com/cuda-downloads

ダウンロード条件

 Linux
 x86_64
 Ubuntu
 18.04
 dev[network]

以下の作業をターミナルから入力し実行する.

$ wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
$ sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
$ sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
$ sudo add-apt-repository "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/ /"
$ sudo apt-get update
$ sudo apt-get -y install cuda

再起動する

$ sudo reboot

確認

次のコマンドを入力してドライバーがインストールされたことを確認する
$ nvidia-smi
(以下の情報が表示されればOK,DriverとCUDAのバージョンが表示されている)
Fri Mar  6 18:15:09 2020       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.33.01    Driver Version: 440.33.01    CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 106...  On   | 00000000:01:00.0  On |                  N/A |
| 41%   39C    P2    23W / 120W |    233MiB /  6075MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0       984      G   /usr/lib/xorg/Xorg                            18MiB |
|    0      1014      G   /usr/bin/gnome-shell                          48MiB |
|    0      1312      G   /usr/lib/xorg/Xorg                            95MiB |
|    0      1445      G   /usr/bin/gnome-shell                          66MiB |
+-----------------------------------------------------------------------------+

3)CUDAのパスを.bashrcに設定

エディタgeditを使って.bashrcファイルを編集する. 
$ gedit .bashrc

以下の3行を.basrcファイルの最後に追加し,保存する.
これでCUDAのパスが通るようになる.
#CUDA
export PATH="/usr/local/cuda/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"

確認

$ source .bashrc
$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2019 NVIDIA Corporation
Built on Wed_Oct_23_19:24:38_PDT_2019
Cuda compilation tools, release 10.2, V10.2.89

4)cuDNNのインストール

https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/
からダウンロード:libcudnn7_7.6.5.32-1+cuda10.2_amd64.deb
$ sudo dpkg -i libcudnn7_7.6.5.32-1+cuda10.2_amd64.deb

参考URL

【Ubuntu18.04】NVIDIAドライバ・CUDA・cuDNNのインストール方法
https://atsuyakoike.hatenablog.com/entry/2019/08/08/214530


5)Anacondaのインストール

https://www.anaconda.com/distribution/
ダウンロード:Anaconda3-2019.10-Linux-x86_64.sh
$ bash Anaconda3-2019.10-Linux-x86_64.sh

・・・・・
installation finished.
Do you wish the installer to initialize Anaconda3
by running conda init? [yes|no]
[no] >>>yes

確認

$ source .bashrc
$ conda -V
conda 4.7.12


6)TnesorFlow と Kerasのインストール

TensorFlowのインストール

GPU対応のTensorFlowをインストールする

$ conda install tensorflow-gpu

確認

(TensorFlowをimportして,デバイスにGPUの形式が表示されていることを確認する)
$ python
Python 3.7.4 (default, Aug 13 2019, 20:35:49) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow    
>>> from tensorflow.python.client import device_lib
>>> device_lib.list_local_devices()
2020-03-06 16:09:01.783756: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AVX AVX2 FMA
(省略)
2020-03-06 16:09:01.870307: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1618] Found device 0 with properties: 
name: GeForce GTX 1060 6GB major: 6 minor: 1 memoryClockRate(GHz): 1.759
pciBusID: 0000:01:00.0
(省略)
2020-03-06 16:09:01.936563: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1304] Created TensorFlow device (/device:GPU:0 with 5412 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1060 6GB, pci bus id: 0000:01:00.0, compute capability: 6.1)
2020-03-06 16:09:01.937931: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x55efb35f1a50 executing computations on platform CUDA. Devices:
2020-03-06 16:09:01.937946: I tensorflow/compiler/xla/service/service.cc:175]   StreamExecutor device (0): GeForce GTX 1060 6GB, Compute Capability 6.1
[name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
(省略)
incarnation: 12303617427411943325
physical_device_desc: "device: 0, name: GeForce GTX 1060 6GB, pci bus id: 0000:01:00.0, compute capability: 6.1"
, name: "/device:XLA_GPU:0"
device_type: "XLA_GPU"
memory_limit: 17179869184
locality {
}
incarnation: 2429606674858306080
physical_device_desc: "device: XLA_GPU device"
]

Kerasのインストール

$ conda install keras

参考URL

GPU付きのTensorflowをUbuntu18.04に入れる
https://qiita.com/python_walker/items/d599aeeea673bf89b7cb


7)cupyのインストール

$ pip search cupy
・・・
cupy-cuda102 (7.2.0)      - CuPy: NumPy-like API accelerated with CUDA
・・・

$ pip install cupy-cuda102

確認 

pythonを起動して
>>> import cupy as cp
>>> cp.__version__
'7.2.0'

参考URL

最新の cuda + cudnn + cupy を Ubuntu 18.04 へインストールする@2019年春版
https://qiita.com/aizakku_nidaa/items/3c97dbcc30e1995488a5

8)chainerのインストール

$ pip install chainer

確認 

pythonを起動して
>>> import chainer
>>> chainer.__version__
'7.2.0'


9)OpenCVのインストール

$ pip install opencv-python

確認 

pythonを起動して
>>> import cv2
>>> cv2.__version__
'4.2.0'

10)Pydicomインストール

$ pip install  pydicom

確認 

pythonを起動して
>>> import pydicom
>>> pydicom.__version__
'1.4.2'

11)DCMTKのインストール

$ sudo apt install dcmtk

確認

$ dcmdjpeg --version
(以下の内容が表示されればOK)
$dcmtk: dcmdjpeg v3.6.2 2017-07-14 $

dcmdjpeg: Decode JPEG-compressed DICOM file

Host type: Debian
Character encoding: UTF-8

External libraries used:
- ZLIB, Version 1.2.11
- IJG, Version 6b  27-Mar-1998 (modified)


12)ImageJのインストール

参考URL

https://imagej.nih.gov/ij/
ダウンロード:ij152-linux64-java8.zip
Homeで展開、起動してアイコンをお気に入りに登録する

おまけ)Dropboxのインストール

$ cd ~ && wget -O - "https://www.dropbox.com/download?plat=lnx.x86_64" | tar xzf -

起動

$ ~/.dropbox-dist/dropboxd


以上です.

2020年2月16日日曜日

Pyゼミ2.05 PyQt5によるラジオボタンとチェックボックス

ラジオボタンとチェックボックスの使い方を学ぼう.


Keyword:PyQt5,ラジオボタン,チェックボックス


画像のセグメンテーションにラベルを付けるようなとき,ラジオボタン(どれか一つ選択)やチェックボックス(複数選択)を使いたいときがあります.

インターネットを調べるとラジオボタンやチェックボックスについての記事がいろいろあるけど,実際使ってみようとするといろいろと問題が発生します.
  • チェック付けた情報をどうやって得るの?
  • チェックボックスを増やしたり減らしたり簡単にしたいよ.

これらを短いプログラムで解決していこうと思います.
具体的には次のような仕様になります.
  • 3つの部位をラジオボタンで選択する.
  • 5つの状態をチェックボックスで選択する.
  • OKボタンをクリックすると,チェックのついた情報がコンソールに表示する.
  • ラジオボタンやチェックボックスの項目はリストで持ち,増やしたり減らしたりできる.

GUIのイメージは次のようになります.




プログラム概要


はじめに'__main__'を見てみる

リストpartsに3つの部位が格納され,stateにはLevel1からLevel5までの5つの状態が格納されています.

    parts = [ 'Brain' , 'Lung' , 'Abdomen' ]
    state = [ 'Level1' , 'Level2' , 'Level3' , 'Level4' , 'Level5']

リスト内の値を自由に追加や編集することでいろいろ応用可能です.

この2つのリストを引数にCheckBox_RadioButtonクラスを呼びだします.


次に,イニシャライザ__init__を見てみる

partsとstateの要素数をそれぞれself.nPtとself.nStに代入しています.
そして,ラジオボタンを生成するself.radbtnをボタンの個数分のリストを作成しています(とりあえず空白" "を値としてリストを作成).
このリストにあとでラジオボタンを作成します.

    self.radbtn = list(" " * self.nPt)

同様にチェックボックスのボタンを生成するリストself.chkboxも作成しています.

部位と状態のリストをクラス内で使用するためself.partsとself.stateに代入しています.


initUIを見てみよう


最初に部位を選択するラジオボタンを作る.

”部位”を表示するラベルlblPrtを作成しします.
ラジオボタンは複数のラジオボタンから一つ選択しますが,複数ラジオボタンをグループにまとめるためradbtngrpを作成します.

    self.radbtngrp = QButtonGroup()

ラジオボタンや”部位”ラベルを配置するBoxLayoutを作成します.
縦に並べるので,QVBoxLayoutを使い,それにラベルlblPrtを配置します.

        vboxPrt = QVBoxLayout()
        vboxPrt.addWidget(lblPrt, alignment=Qt.AlignTop | Qt.AlignHCenter)

次に部位の数分(self.nPt)繰り返してi番目のラジオボタンをリストself.radbtn[i]に作成します.

    self.radbtn[i] = QRadioButton( self.parts[i])

このラジオボタンに対して,チェック可能かどうかsetCheckableをTrueに,フォーカスするかどうかsetFocusPolicyについてフォーカスしないに,そして,ラジオボタンをチェックしたときの動作をclicked.connectを使ってself.clickedRadbtn関数を呼ぶようにします.
ラジオボタンのグループradbtngrpにaddButtonを使って,i番目のラジオボタンself.radbtn[i]とIDのiの値を追加します.
このIDはどのボタンがチェックされているか調べるのに使われます.
そして最後にvboxPrtレイアウトにaddWidgetを使って配置している.

            self.radbtn[i] = QRadioButton( self.parts[i])
            self.radbtn[i].setCheckable(True)
            self.radbtn[i].setFocusPolicy(Qt.NoFocus)
            self.radbtn[i].clicked.connect(self.clickedRadbtn)                           
            self.radbtngrp.addButton(self.radbtn[i], i)
            vboxPrt.addWidget(self.radbtn[i], alignment=Qt.AlignTop)  


次に,状態を選択するチェックボックスを作る

最初に”状態”のラベルlblSttを作成し,チェックボックスを配置するレイアウトvboxSttに配置する.

状態の数分(self.nSt)繰り返して,i番目のチェックボックスをリストself.chkbox[i]に作成し,このチェックボックスがチェックされたときの動作をclicked.connectを使ってself.clickedCbxbtn関数を呼ぶようにし,最後にvboxSttレイアウトにaddWidgetを使って配置します.

            self.chkbox[i] = QCheckBox(self.state[i],self)
            self.chkbox[i].stateChanged.connect(self.clickedCbxbtn)
            vboxStt.addWidget(self.chkbox[i], alignment=Qt.AlignTop)

このようにfor文を使うことで簡単にボタンを追加することができます.


OKボタンを作る.

ボタンをチェックした後,情報を取得するアクションとしてOKボタンokbtnをQPushButtonを使って作ります.
このokbtnをクリックしたときの動作をclicked.connectを使って,self.clickedOkbtn関数を呼び出すようにします.
OKボタンokbtnを配置するだけですが,レイアウトokboxを作成して.これにOKボタンを配置します.


レイアウトを作成する.

最後にラジオボタンのレイアウトvboxPart,チェックボックスのレイアウトvboxSttを水平にレイアウトするためhboxをQHBoLayoutで作成しこれに2つのレイアウトを配置ます.

        hbox = QHBoxLayout()
        hbox.addLayout(vboxPrt)
        hbox.addLayout(vboxStt) 

最後に,上のhboxとokboxを縦に配置するためにQVBoxLayoutを使ってvboxを作成し,これにhboxとokboxをレイアウトします.

        vbox = QVBoxLayout()
        vbox.addLayout(hbox)
        vbox.addLayout(okbox)


ボタンをクリックしたときの動作する関数を作る


クリックしたチェックボックスを調べる関数clickedCbxbtn

この関数では,どのチェックボックスがチェックされたのかコンソールに表示します.
チェックボックスself.chkbox[i]にチェックあるかどうかcheckState()を使って調べて表示します.

        for i in range(self.nSt):
            print(self.state[i], self.chkbox[i].checkState())


クリックしたラジオボタンを調べる関数clickedRadbtn

この関数はチェックされたラジオボタンをコンソールに表示します.
ラジオボタンのグループradbtngrpのどれがクリックされたのか,checkedId()を使ってIDを取得します.
このIDを用いてリストpartsのどれがチェックされているか知ることができます.

        checkid = self.radbtngrp.checkedId()         
        print( "PART:", self.parts[checkid] )


OKボタンがクリックされたらボタンの情報を表示するclickedOkbtn関数

ボタンのクリックされた情報を集約し,変数rsltStrにまとめます.
はじめにラジオボタンのIDを取得し,部位名称をrsltStrに代入します.

        checkid = self.radbtngrp.checkedId()   
        rsltStr = self.parts[checkid]

次に,チェックボックスchkbox[i]をひとつずつcheckState()を使って調べ,もしチェックされていれば値2が返るので,そのインデックス+1を変数rsltStrに追加します.

        for i in range(self.nSt):
            if self.chkbox[i].checkState() > 0:
                rsltStr += ":" + str(i+1)   

この変数rsltStrを表示すると,ラジオボタンとチェックボックスの状態を知ることができます.

        print("RESULT:", rsltStr)

例えば図のようにチェックしたとすると,結果は次のようになります.

コンソールに表示される結果は次のようになります.

---------- Clicked RadioButton
PART: Lung
---------- Clicked Changebox
Level1 0
Level2 0
Level3 2
Level4 0
Level5 0
========== Clicked OK ==========
RESULT: Lung:3

プログラムを入力して実行してみよう


# -*- coding: utf-8 -*-
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.Qt import *
from PyQt5 import QtCore, QtWidgets

class CheckBox_RadioButton(QWidget):
    def __init__(self, Parts, State):
        super().__init__()

        self.nPt    = len(Parts)
        self.nSt    = len(State)       
        self.radbtn = list(" " * self.nPt)
        self.chkbox = list(" " * self.nSt)
        self.parts  = Parts  
        self.state  = State
        self.initUI()

    def initUI(self):
        """ Radio Button """
        lblPrt         = QLabel("部位")
        self.radbtngrp = QButtonGroup()
        vboxPrt        = QVBoxLayout()
        vboxPrt.addWidget(lblPrt, alignment=Qt.AlignTop | Qt.AlignHCenter)
        for i in range(self.nPt):
            self.radbtn[i] = QRadioButton( self.parts[i])
            self.radbtn[i].setCheckable(True)
            self.radbtn[i].setFocusPolicy(Qt.NoFocus)
            self.radbtn[i].clicked.connect(self.clickedRadbtn)                          
            self.radbtngrp.addButton(self.radbtn[i], i)
            vboxPrt.addWidget(self.radbtn[i], alignment=Qt.AlignTop)   
       
        """ CheckBox """
        lblStt  = QLabel("状態")
        vboxStt = QVBoxLayout()
        vboxStt.addWidget(lblStt, alignment=Qt.AlignTop | Qt.AlignHCenter)
        for i in range(self.nSt):
            self.chkbox[i] = QCheckBox(self.state[i],self)
            self.chkbox[i].stateChanged.connect(self.clickedCbxbtn)
            vboxStt.addWidget(self.chkbox[i], alignment=Qt.AlignTop)

        """ OK Button """
        okbtn = QPushButton("OK")
        okbtn.clicked.connect(self.clickedOkbtn)
        okbox = QHBoxLayout()
        okbox.addWidget(okbtn)
       
        """ Layout """
        hbox = QHBoxLayout()
        hbox.addLayout(vboxPrt)
        hbox.addLayout(vboxStt)       
        vbox = QVBoxLayout()
        vbox.addLayout(hbox)
        vbox.addLayout(okbox)
       
        self.setLayout(vbox)   

        self.setGeometry(100, 75, 250, 250)
        self.setWindowTitle("RadioButton&CheckBox")   
        self.show()
       
    def clickedCbxbtn(self):
        print("-"*10, "Clicked Changebox")
        for i in range(self.nSt):
            print(self.state[i], self.chkbox[i].checkState())
           
    def clickedRadbtn(self):
        print("-"*10, "Clicked RadioButton")
        checkid = self.radbtngrp.checkedId()        
        print( "PART:", self.parts[checkid] )
           
    def clickedOkbtn(self):
        print("="*10,"Clicked OK", "="*10)
        checkid = self.radbtngrp.checkedId()  
        rsltStr = self.parts[checkid]
        for i in range(self.nSt):
            if self.chkbox[i].checkState() > 0:
                rsltStr += ":" + str(i+1)     
        print("RESULT:", rsltStr)
       
if __name__ == '__main__':
    parts = ['Brain','Lung','Abdomen']
    state = ['Level1','Level2','Level3','Level4','Level5']
   
    app = 0     #For Spyder
    app = QApplication(sys.argv)

    ex = CheckBox_RadioButton(parts, state)
    sys.exit(app.exec_())