Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the all-in-one-seo-pack domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /virtual/mcu03iphuk/public_html/radiology-technologist.info/wp-includes/functions.php on line 6114

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the easy-fancybox domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /virtual/mcu03iphuk/public_html/radiology-technologist.info/wp-includes/functions.php on line 6114

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the urvanov-syntax-highlighter domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /virtual/mcu03iphuk/public_html/radiology-technologist.info/wp-includes/functions.php on line 6114

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the breadcrumb-navxt domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /virtual/mcu03iphuk/public_html/radiology-technologist.info/wp-includes/functions.php on line 6114

Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the advanced-ads domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Translations should be loaded at the init action or later. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /virtual/mcu03iphuk/public_html/radiology-technologist.info/wp-includes/functions.php on line 6114

Notice: 関数 _load_textdomain_just_in_time が誤って呼び出されました。lancr ドメインの翻訳の読み込みが早すぎました。これは通常、プラグインまたはテーマの一部のコードが早すぎるタイミングで実行されていることを示しています。翻訳は init アクション以降で読み込む必要があります。 詳しくは WordPress のデバッグをご覧ください。 (このメッセージはバージョン 6.7.0 で追加されました) in /virtual/mcu03iphuk/public_html/radiology-technologist.info/wp-includes/functions.php on line 6114

Warning: Cannot modify header information - headers already sent by (output started at /virtual/mcu03iphuk/public_html/radiology-technologist.info/wp-includes/functions.php:6114) in /virtual/mcu03iphuk/public_html/radiology-technologist.info/wp-content/plugins/all-in-one-seo-pack/app/Common/Meta/Robots.php on line 87

Warning: Cannot modify header information - headers already sent by (output started at /virtual/mcu03iphuk/public_html/radiology-technologist.info/wp-includes/functions.php:6114) in /virtual/mcu03iphuk/public_html/radiology-technologist.info/wp-includes/feed-rss2.php on line 8
便利技 | 診療放射線技師がPythonをはじめました。 http://radiology-technologist.info 診療放射線技師のPython日記。解析等で使えるコードを作成、アップしていきたいと思っています。その他いろいろ Fri, 21 May 2021 06:21:24 +0000 ja hourly 1 https://wordpress.org/?v=6.7 https://i0.wp.com/radiology-technologist.info/wp-content/uploads/2018/09/cropped-logo5.png?fit=32%2C32 便利技 | 診療放射線技師がPythonをはじめました。 http://radiology-technologist.info 32 32 164362728 画像選択のプログラムを使いやすく!! http://radiology-technologist.info/post-371 Fri, 20 Dec 2019 21:59:57 +0000 http://radiology-technologist.info/?p=371 DICOMタグを取得するのも、画像処理をするのもま […]

The post 画像選択のプログラムを使いやすく!! first appeared on 診療放射線技師がPythonをはじめました。.]]>
DICOMタグを取得するのも、画像処理をするのもまずはファイル選択することから始まります。


一番簡単な方法は、プログラムの中でファイルを指定することなのですが、それでは他のファイルを処理したいときにいちいちコードのファイル名を書き換えなければならないし、保存しているフォルダが違うと余計に面倒ですよね。


それを解決するために以前の記事で「ファイルを一つ選択する方法」「ファイルを複数選択する方法」「フォルダ内のファイルを一括選択する方法」と3回にわたって記事にしてきました。


いずれも、一つのファイル内にコードを記述していたわけですが、コードが長くなってくると目的のコードを探すのが大変になってしまいます。

そこで、今回はファイル選択の部分だけを一つのプログラム(モジュール)として作成し、他のプログラムから呼び出す方法を記載していきたいと思います。



ファイル名を「fileselect.py」として作成します。

ひとまず前3回分のコードを一つにコピペしてみました。

#ファイルを一つ選択::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
import tkinter
from tkinter import filedialog as tkFileDialog

def fileselect():
    root = tkinter.Tk()
    root.withdraw()

    fTyp = [('', '*')]

    iDir = 'C:/Desktop'

    filename = tkFileDialog.askopenfilename(filetypes=fTyp, initialdir=iDir)
    return filename


#ファイルを複数選択:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

# -*- coding: utf-8 -*-

import tkinter  # tkinterをインポート
from tkinter import filedialog as tkFileDialog


def fileselect():
    root = tkinter.Tk()
    root.withdraw()

    fTyp = [('', '*')]
    iDir = 'C:/Desktop'

    filenames = tkFileDialog.askopenfilenames(filetypes=fTyp, initialdir=iDir)

    return filenames


#ファイルをフォルダで一括選択:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
# -*- coding: utf-8 -*-

import tkinter  
from tkinter import filedialog as tkFileDialog
import glob

def fileselect():
    root = tkinter.Tk()  
    root.withdraw()  

    iDir = 'C:/Desktop'  

    dirname = tkFileDialog.askdirectory(initialdir=iDir)

    filenames = glob.glob(dirname +"/*")
    return filenames

ここで目に着くところが、import~というところが複数出てきていますのでこれを一番先頭に持ってきて、重複している部分を削除してしまいましょう。


そうすると、以下のようになります。

# -*- coding: utf-8 -*-

import tkinter  
from tkinter import filedialog as tkFileDialog
import glob

#ファイルを一つ選択::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
def fileselect():
    root = tkinter.Tk()
    root.withdraw()

    fTyp = [('', '*')]

    iDir = 'C:/Desktop'

    filename = tkFileDialog.askopenfilename(filetypes=fTyp, initialdir=iDir)
    return filename

#ファイルを複数選択:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
def fileselect():
    root = tkinter.Tk()
    root.withdraw()

    fTyp = [('', '*')]
    iDir = 'C:/Desktop'

    filenames = tkFileDialog.askopenfilenames(filetypes=fTyp, initialdir=iDir)

    return filenames

#ファイルをフォルダで一括選択:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
def fileselect():
    root = tkinter.Tk()  
    root.withdraw()  

    iDir = 'C:/Desktop'  

    dirname = tkFileDialog.askdirectory(initialdir=iDir)

    filenames = glob.glob(dirname +"/*")
    return filenames

だいぶスッキリとしました。しかし、

def 〇 〇 〇 〇 ():

で始まる関数名がすべて同じになってしまっていますので、これを変更しましょう。

ファイルを一つ選択する場合は、single_fileselect、複数選択するときはmulti_fileselect、フォルダで選択する場合はfolder_fileselectと変更しましょう。


# -*- coding: utf-8 -*-

import tkinter  
from tkinter import filedialog as tkFileDialog
import glob

#ファイルを一つ選択::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
def single_fileselect():
    root = tkinter.Tk()
    root.withdraw()

    fTyp = [('', '*')]

    iDir = 'C:/Desktop'

    filename = tkFileDialog.askopenfilename(filetypes=fTyp, initialdir=iDir)
    return filename

#ファイルを複数選択:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
def multi_fileselect():
    root = tkinter.Tk()
    root.withdraw()

    fTyp = [('', '*')]
    iDir = 'C:/Desktop'

    filenames = tkFileDialog.askopenfilenames(filetypes=fTyp, initialdir=iDir)

    return filenames

#ファイルをフォルダで一括選択:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
def folder_fileselect():
    root = tkinter.Tk()  
    root.withdraw()  

    iDir = 'C:/Desktop'  

    dirname = tkFileDialog.askdirectory(initialdir=iDir)

    filenames = glob.glob(dirname +"/*")
    return filenames

これで完成です。

それでは、実際に使用してみたいと思います。

前回の「マウスを使って画像を切り替える」のコードを使って説明します。

前回のコードは以下になります。

# coding: UTF-8
import cv2
import tkinter
from tkinter import filedialog as tkFileDialog
 
def onMouse(event, x, y, flag, params):
    i, filenames= params
 
    if event == cv2.EVENT_MOUSEWHEEL:  # ホイールを回したときの動作
 
        if flag > 0:       #もしflagが正の数だったら画像番号iを1引く
            i -= 1         # -= とはiの数から1を引いた数をiに代入すること
        elif flag < 0:     #もしflagが負の数だったら画像番号iを1足す
            i += 1         # += とはiの数から1を引いた数をiに代入すること
 
        if i <= 0:         #もし、iが0より小さかったら
            i = 0         #iは0
        elif i >= len(filenames)-1:  #もし、iが要素数以上だったら
            i = len(filenames)-1    #要素数より1少ない数に
 
        imageshow(filenames, i)
 
def fileselect():
    root = tkinter.Tk()
    root.withdraw()
    fTyp = [('', '*')]
    iDir = 'C:/Desktop'
    filenames = tkFileDialog.askopenfilenames(filetypes=fTyp, initialdir=iDir)
    return filenames  # 選択ファイルの絶対パスを返します。
 
def imageshow(filenames,i):
    img = cv2.imread(filenames[i])
    wname = "img"
 
    cv2.imshow(wname, img)
    print(str(i) + "   image  " + filenames[i])
 
    cv2.setMouseCallback(wname, onMouse, [i, filenames])
    cv2.waitKey()
    cv2.destroyAllWindows()
 
filenames = fileselect()
i=0
imageshow(filenames,i)

まず、23行目から、29行目のコードは新しく作成したfileselect.pyに記載してありますので削除します。

あと、3行目と4行目のimport文はファイルを選択するダイアログを開く際に必要なライブラリでした。このライブラリはfileselect.pyの中で呼び出しをしますので必要なくなりましたので削除します。

その代わり、fileselect.pyを使用しますので

import fileselect

の一文を追加します。これで、 fileselect.py を使用することができます。

最後に、42行目

filenames = fileselect()

の文をfileselect.pyの中の使用したい関数名を指定すればいいので例えば一つのファイルを選択したいのであれば

filenames = fileselect.single_fileselect()

複数のファイルであれば

filenames = fileselect.multi_fileselect()

フォルダごと選択であれば

filenames = fileselect.folder_fileselect()

とすることで使用することができます。

例えば、複数ファイルでやってみるとコードは以下となります。

# coding: UTF-8
import cv2
import fileselect

def onMouse(event, x, y, flag, params):
    i, filenames = params

    if event == cv2.EVENT_MOUSEWHEEL:  # ホイールを回したときの動作

        if flag > 0:  # もしflagが正の数だったら画像番号iを1引く
            i -= 1  # -= とはiの数から1を引いた数をiに代入すること
        elif flag < 0:  # もしflagが負の数だったら画像番号iを1足す
            i += 1  # += とはiの数から1を引いた数をiに代入すること

        if i <= 0:  # もし、iが0より小さかったら
            i = 0  # iは0
        elif i >= len(filenames) - 1:  # もし、iが要素数以上だったら
            i = len(filenames) - 1  # 要素数より1少ない数に

        imageshow(filenames, i)

def imageshow(filenames, i):
    img = cv2.imread(filenames[i])
    wname = "img"

    cv2.imshow(wname, img)
    print(str(i) + "   image  " + filenames[i])

    cv2.setMouseCallback(wname, onMouse, [i, filenames])
    cv2.waitKey()
    cv2.destroyAllWindows()

filenames = fileselect.multi_fileselect()
i = 0
imageshow(filenames, i)

少し、コードがすっきりとしましたね。

マウスイベントも同様に別ファイルとして作ってしまえば、かなりすっきりとしますので試してみてください。

それでは。お疲れ様でした。


環境

  • windows10
  • python3.6.1
  • Anaconda custom(64-bit)
  • PyCharm2020.2(Communication Edition)

広告
上新電機 パソコン買取サービス
The post 画像選択のプログラムを使いやすく!! first appeared on 診療放射線技師がPythonをはじめました。.]]>
371
ダイアログを使って、フォルダでファイルを一括選択する。 http://radiology-technologist.info/post-279 Sun, 27 Oct 2019 04:22:27 +0000 http://mcu03iphuk.m5.valueserver.jp/wordpress/?p=279 ダイアログを使って、フォルダでファイルを一括選択す […]

The post ダイアログを使って、フォルダでファイルを一括選択する。 first appeared on 診療放射線技師がPythonをはじめました。.]]>
ダイアログを使って、フォルダでファイルを一括選択する。

私たち放射線技師がDICOM画像を使って何か解析をしようとした際、CDやDVDといったメディアに画像を出力して自分のパソコンに取り込み、処理していることと思います。

そして、出力した画像はシリーズごとにフォルダに入っていますよね。


前回、前々会ではファイルを一つ、もしくは複数ファイルをそれぞれ選択して処理に回していきました。

今回は、フォルダを選択することで複数画像を一括で選択してしまおうという会です。


前回の「ダイアログを使って、ファイルを複数選択する。」

前々回の「ダイアログを使って、ファイルを選択する。」


処理の流れ

まずは、

①ファイル名の一覧を取得したいディレクトリの指定

②ファイル名の一覧を取得する

といった流れとなります。


一覧取得するフォルダの指定

まずは、前回のファイルを複数選択するコードです。

# -*- coding: utf-8 -*-

import tkinter  # tkinterをインポート
from tkinter import filedialog as tkFileDialog

# tkinterのfiledialogをインポート

def fileselect():
    root = tkinter.Tk()  # tkinterのインスタンスを生成
    root.withdraw()      # この一文が無いと謎の黒いウインドウが出てくるらしい

    fTyp = [('', '*')]   # ダイアログに表示するファイル種類を指定。
                         # 今回は指定なし
                         # fTyp=[('テキストファイル','*.txt')]
                         # 上記の様にすればテキストファイルのみに絞れる。
                         # ()を足していくことで複数指定することも可能。

    iDir = 'C:/Desktop'  # ダイアログが開くディレクトリを指定
                         # 今回はデスクトップ

    filenames = tkFileDialog.askopenfilenames(filetypes=fTyp, initialdir=iDir)

    return filenames     # 選択ファイルの絶対パスを返します。


fname = fileselect()     # fileselectの最後returnで返されたものをfnameに格納

print(fname)             #選択したファイルのパスが表示される。

上記コードで今回修正するところは23行目

filenames = tkFileDialog.askopenfilenames(filetypes=fTyp, initialdir=iDir)

の行を以下のように変更します。

dirname = tkFileDialog.askdirectory(initialdir=iDir)

まず、ディレクトリを指定するので

dirnameという名前に変更します。

その後、

.askopenfilenames

の部分を

.askdirectory

と、filenamesからdirectoryに変更にします。

そして、引数の中のファイルタイプの指定 (filetypes=fTyp) は、ディレクトリの指定となるので必要なくなります。

これにより、一覧取得するフォルダの指定が完了です。


ファイル名取得

その後に、ファイル名の一覧取得になりますが、使用するモジュールはglobを使用しますのでまずはインポートしていきたいと思います。

7行目に以下のコードを追加します。

import glob

その後、26行目の return filenames の前に

filenames = glob.glob(dirname +”/*”)

の一文を追加します。

引数には、先ほど取得したディレクトリのパスを入れた変数名dirnameを入れます。

しかし、このままだとディレクトリを指定しているのでディレクトリの中を指定してあげるためにディレクトリのパスの後に / を追加する必要があるので

変数名dirname の後に  +”/*”  を追加してあげます。

なお、”*”はファイルの種類全てを指しています。もし、テキストファイルのみでしたら  +”/*.txt”とすることで絞り込むことができます。

以上で完了です。

以下が本日のコードとなります。

# -*- coding: utf-8 -*-

import tkinter  
from tkinter import filedialog as tkFileDialog
import glob   # globをインポート

def fileselect():
    root = tkinter.Tk()  
    root.withdraw()  

    iDir = 'C:/Desktop'  

    dirname = tkFileDialog.askdirectory(initialdir=iDir)

    filenames = glob.glob(dirname +"/*")
    return filenames

fname = fileselect()  # fileselectの最後returnで返されたものをfnameに格納

print(fname)

いかがでしたか?結果下の図のように表示されていませんか?

次回は、リストで取得したパスをひとつづつ取り出して画像表示していく方法をやってみたいと思います。


広告
デル株式会社

環境

  • windows10
  • python3.6.1
  • Anaconda custom(64-bit)
  • PyCharm2020.2(Communication Edition)


広告
上新電機 パソコン買取サービス
The post ダイアログを使って、フォルダでファイルを一括選択する。 first appeared on 診療放射線技師がPythonをはじめました。.]]>
279