0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

pythonでサブルーチンはどう書くの?

Posted at

はじめに

pythonでプログラムを作りはじめたとき、サブルーチンは、どう書くのだろうという疑問を持ちました。
過去の話になりますが、BASIC言語ではプログラムを作るとき、何度も使う部分は一つにまとめて、gosub文で呼び出していたので、pythonにもあるだろうと思っていましたが、そのような文はありませんでした。
pythonのプログラムを学んでいくと、def文で関数をつくって、それを呼び出せば、サブルーチンの代わりになることが分かってきました。さらに、別ファイルに関数をまとめて作っておくと、他のプログラムで利用できるようになり、便利に使えるということもわかってきました。
プログラマーには当たり前の話かと思いますが、これからpythonを始める人に少しでも役立てていただけるように、例を挙げて書いておこうと思います。

def文の例

(例) 画像読み込み関数の作成

例えば、openCVを使って画像の編集をしたいが、画像ファイルのパスに日本語が入っていてエラーが出るため、つぎのようなプログラムを作ったとします。

import cv2
from PIL import Image
import numpy as np

file=r'C:\Users\heroshi\OneDrive\画像\abc.jpg'
pil_img=Image.open(file)
np_img=np.array(pil_img)
cv_img=cv2.cvtColor(np_img, cv2.COLOR_RGB2BGR)

PIL(pillow)でファイルを読み込み、numpyアレイに変換し、さらにカラー順を変換して、ようやくopenCVで画像を編集できるようになるのですが、画像を読み込むたびに、この3行を書くのは面倒ですし、分かりにくくなります。そこで、def文で関数を1つ用意し、その中に3行を入れておきます。

import cv2
from PIL import Image
import numpy as np

def load_img(file):
    pil_img=Image.open(file)
    np_img=np.array(pil_img)
    cv_img=cv2.cvtColor(np_img, cv2.COLOR_RGB2BGR)
    return cv_img

file=r'C:\Users\heroshi\OneDrive\画像\abc.jpg'
cv_img=load_img(file) #関数の呼び出し gosub文のようなもの

上のプログラムはdef文で「load_img」という名前をつけた関数を定義しています。プログラムは長くなっていますが、BASIC言語のサブルーチンのように「load_img」を何度も使うときに便利になります。
例えば、画像を2つ読み込んで、画像を足しあわせる場合は次のように書けます。

import cv2
from PIL import Image
import numpy as np

def load_img(file):
    pil_img=Image.open(file)
    np_img=np.array(pil_img)
    cv_img=cv2.cvtColor(np_img, cv2.COLOR_RGB2BGR)
    return cv_img

file_1=r'C:\Users\heroshi\OneDrive\画像\abc.jpg'
file_2=r'C:\Users\heroshi\OneDrive\画像\def.jpg'
cv_img_1=load_img(file_1) #関数の呼び出し gosub文のようなもの
cv_img_2=load_img(file_2)
mix_img= cv2.addWeighted(src1=cv_img_1,alpha=0.5,src2=cv_img_2,beta=0.5,gamma=0)

(例) 画像の表示関数の作成

画像を表示する際、openCVのcv2.imshowを使って描くよりも、matplotlibのplt.showを使ったほうが拡大縮小も簡単に操作できるので、次のようなプログラムを作って描画しています。

import matplotlib.pyplot as plt
plt_mix_img=cv2.cvtColor(mix_img, cv2.COLOR_BGR2RGB) # BGRからRGBへ変換して表示
plt.imshow(plt_mix_img)  
plt.axis('off')  # 軸を非表示にする
plt.show()

こちらも表示させるのに何度も同じ文(4行)を書くのが面倒なので、次のようにdef文で関数を定義します。

import matplotlib.pyplot as plt
def draw_img(image):
    plt_mix_img=cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # BGRからRGBへ変換して表示
    plt.imshow(plt_mix_img)  
    plt.axis('off')  # 軸を非表示にする
    plt.show()

draw_img(mix_img) #関数の呼び出し gosub文のようなもの

関数だけを別ファイルへ

上の例では、ファイルの読み込みと画像の描画の関数を作りました。その関数だけを別のファイルに入れて、ファイル名は、dif_list.pyとします。

import cv2
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

def load_img(file):
    pil_img=Image.open(file)
    np_img=np.array(pil_img)
    cv_img=cv2.cvtColor(np_img, cv2.COLOR_RGB2BGR)
    return cv_img

def draw_img(image):
    plt_mix_img=cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # BGRからRGBへ変換して表示
    plt.imshow(plt_mix_img)  
    plt.axis('off')  # 軸を非表示にする
    plt.show()

次に実行するファイルを作ります。def_listから関数をインポートすることで、実行ファイルの中身は非常にすっきりします。※実行ファイルと関数のファイルは同じフォルダに入れています。

import cv2
from def_list import * #ここでdef_listのファイルから関数をインポートします。*は、すべてという意味です。

file_1=r'C:\Users\heroshi\OneDrive\画像\abc.jpg'
file_2=r'C:\Users\heroshi\OneDrive\画像\def.jpg'
cv_img_1=load_img(file_1)
cv_img_2=load_img(file_2)
mix_img= cv2.addWeighted(src1=cv_img_1,alpha=0.5,src2=cv_img_2,beta=0.5,gamma=0)

draw_img(mix_img)

関数にわかりやすい名前をつけることで、使いやすいものになり、別の実行プログラムでも、関数をインポートすることで同様に使えるようになります。

関数の修正や追加時の確認

関数の修正や追加した際に、きちんと動くかを確認したい場合があると思います。こんなとき、関数のファイルの最後に、if _ _ name _ _ =="_ _ main _ _" 文を入れておけば、関数ファイルのみで実行して確認できるようになるので、こちらもお勧めです。

import cv2
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

def load_img(file):
    pil_img=Image.open(file)
    np_img=np.array(pil_img)
    cv_img=cv2.cvtColor(np_img, cv2.COLOR_RGB2BGR)
    return cv_img

def draw_img(image):
    plt_mix_img=cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # BGRからRGBへ変換して表示
    plt.imshow(plt_mix_img)  
    plt.axis('off')  # 軸を非表示にする
    plt.show()

if __name__=="__main__":
    file=r'C:\Users\heroshi\OneDrive\画像\abc.jpg'
    cv_img=load_img(file)
    deaw_img(cv_img)

さいごに

最初はBASIC言語のサブルーチンってpythonでどう書くんだろうと思っていましたが、pythonを学んでいくうちに、def文でできることを知り、関数を別ファイルとして用意しておけば、インポートするだけで、他のプログラムでも使えるようになるということを知りました。プログラミングの進化を感じた次第です。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?