fc2ブログ

Python版OpenCV用GUIを作る

 Ubuntu18.04にOpenCVの実行環境を作成し、以前のブログで2回に分けてお話しました(1回目の話はこちらで2回目はこちら)。今回はカラー画像を読み込んで、グレー化、二値化の一連の流れを、Ubuntu環境下でPythonを用いてtkinterでGUI実装し、実行してみました。動作確認だけで、厳密なエラー処理等は行っていませんのでご参考まで。

 プログラムはGUI部分とOpenCV処理部分を分けて作成しました。GUI部分のコードは以下の通りです。
import tkinter
import tkinter.filedialog as tkdialog
from tkinter import font
from PIL import Image, ImageTk
import os
import image_proc

class AppForm(tkinter.Frame):

def __init__(self, master=None):
super().__init__(master, height=500, width=660)
self.pack()
self.create_widgets()
self.menubar_create()

def create_widgets(self):
self.canvas = tkinter.Canvas(
root,
width = 640,
height = 480,
relief= tkinter.RIDGE,
bd=0
)
self.canvas.place(x=10, y=10)

def menubar_create(self):

self.menubar = tkinter.Menu(root)

filemenu = tkinter.Menu(self.menubar, tearoff=0)
filemenu.add_command(label="Open", command=self.File_open)
filemenu.add_separator()
filemenu.add_command(label="Exit", command=root.quit)
self.menubar.add_cascade(label="File", menu=filemenu)

editmenu = tkinter.Menu(self.menubar, tearoff=0)
editmenu.add_command(label="Grayscale", command=self.Proc_grayscale)
editmenu.add_command(label="Binarize", command=self.Proc_binarize)
self.menubar.add_cascade(label="Processing", menu=editmenu)

root.config(menu=self.menubar)
root.config()

def Disp_image(self, im_temp):
self.img_temp = ImageTk.PhotoImage(Image.fromarray(im_temp))
self.canvas.create_image(
0,
0,
image = self.img_temp,
anchor = tkinter.NW
)

def File_open(self):
fname = tkdialog.askopenfilename(filetypes=[("bmp files","*.bmp"),("png files","*.png")],initialdir=os.getcwd())
self.im = image_proc.Image_read(fname)
self.Disp_image(self.im)

def Proc_grayscale(self):
self.im_gray = image_proc.Image_grayscale(self.im)
self.Disp_image(self.im_gray)

def Proc_binarize(self):
self.ret, self.im_bin = image_proc.Image_binarize(self.im_gray)
self.Disp_image(self.im_bin)

root = tkinter.Tk()
root.title("OpenCV Developer")
root.option_add('*font', ('MS Sans Serif', 16))
app = AppForm(master=root)
app.mainloop()
 6行目で以下のOpenCVのコードをインポートしています。
import cv2

def Image_read(img_name):
im = cv2.imread(img_name)
im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
return im

def Image_save(img_name, img_temp):
if img_temp.ndim == '3': # color image (gray image : 2)
img_temp = cv2.cvtColor(img_temp, cv2.COLOR_RGB2BGR)
cv2.imwrite(img_name, img_temp)

def Image_grayscale(img_temp):
im_gray = cv2.cvtColor(img_temp, cv2.COLOR_BGR2GRAY)
return im_gray

def Image_binarize(img_temp):
ret, im_bin = cv2.threshold(img_temp, 60, 255, cv2.THRESH_BINARY)
return ret, im_bin
 こちらは基本的にOpenCVに特化した単純なコードです。画像処理を手直しする際にはこちらのプログラムだけで済みます。

 以下、実行結果。起動画面はこんな感じです。OpenCV_GUI_1_180818.pngメニューバーの「File-Open」を選択するとOpenCV_GUI_2_180818.pngファイル選択ダイアログが出ますので、目的の画像ファイルを選択します。OpenCV_GUI_3_180818.pngとりあえず、ベタな画像ですが、GUI上に表示されました。そのまま進みましょう・・。OpenCV_GUI_4_180818.png「Processing-Grayscale」を選択すると、OpenCV_GUI_5_180818.pngグレー化され、表示されました。OpenCV_GUI_6_180818.png次に、「Processing-Binarize」を実行すると、指定したしきい値範囲のオブジェクトが抽出されました。問題なく動作しました。OpenCV_GUI_7_180818.png 今回は単純な画像処理のコードでしたが、PythonでGUIを作成して、それなりのことができそうなことはよく分かりました。C++で面倒なビルドしながら画像処理を確認・構築して行くよりも手軽にできそうですね。最近、画像処理を触る機会がめっきり減りましたが、機会があれば使ってみようと思います。
スポンサーサイト



久留米を歩く

 前回に引き続いて、昨日(8/13)は久留米を放浪しました。よりによって、昨日の久留米市は、全国で二番目の暑さでした。Kurume_temperature_180813.png 西鉄電車で実家の最寄りの駅から久留米駅まで行き、まず昼食で「久留米 大砲ラーメン」へ。西鉄久留米駅から歩いて10分ほどでお店に着きました。風向きのせいでしょうか、お店が見えなくても、近付くにつれて、ほのかに豚骨の美味しそうな匂いが漂ってきました(お店のご近所さんは毎日豚骨の匂いを嗅いでいることになりますね・・・)。

 久留米 大砲ラーメンですが、以前、九州出身の職場の同僚が非常に美味しいと言っていたのを思い出し、8/10にKITTE博多店(駅前の博多マルイの9F)で「昔ラーメン」を食べました。お味は「う〜ん・・」。濃厚豚骨スープ、伝統の「呼び戻しスープ」を期待していたのですが、薄〜く、水っぽく、まったく濃厚でない?かなり残念なお味でした。その後、ネットでいろいろな記事を確認していると、博多店の味に私と同じ意見の方がおられました。店舗数を増やして行くと当然のことながら味も落ちるのでしょうね。一蘭ラーメンも同じですね(最近は体が受け付けなくなってしまいましたが・・)。リベンジも兼ねて、大砲ラーメン本店で再トライです。Taihou_ramen_180813.png博多店とはまったく濃厚さが違い、大変美味しくいただけました。博多店の味は何だったんだろうと残念な気持ちになりました。

 食事後は、石橋文化センター内にある久留米市美術館に行きました。石橋文化センターの名前は以前から聞いたことがありましたが、行ったのは今回が初めてです。kurume_art_museum_180813.pngブリヂストン創業者の石橋正二郎氏(政治家の鳩山由紀夫氏、邦夫氏の祖父ですね)が久留米市に寄贈されたものとのこと。ちなみに久留米は「ゴムの街」でも有名で、ブリヂストンやムーンスター(旧月星化成)の工場が立ち並びます。
 話は戻って、美術館で公開されていた「名画が奏でる8つのフーガ」を鑑賞しました。Exhibition_180813.png幸いなことに昨日はお盆特別開館日で入館無料でした。ブリヂストン美術館所蔵のセザンヌ、ルノアールの絵画や久留米にゆかりのある青木繁の作品を満喫でき、大変素晴らしかったです。
 豚骨のように密度の濃い2時間半の滞在で猛暑の久留米を後にしました。

世界遺産 宗像大社 中津宮に行く

 今年も夏期休暇を取って8/9(木)の夜、実家の博多に帰省しました。今回は土日を含め、5泊6日の予定で、明日(8/14)現実?に戻ります・・。今年も私一人だけの気楽な帰省で家族は留守番です。子供の部活等で、家族全員のスケジュールが合いませんからね・・。
 ご先祖様に手を合わせると共に、年寄りの毎度同じ話や愚痴を聞きつつ、日頃の疲れを取るために、いつもの「現実逃避の放浪の旅」に出ました。

 去年は、熊本城と北九州の世界遺産「官営八幡製鐵所 旧本事務所」に行きましたが、今年は2017年7月に世界遺産に登録された「宗像大社 中津宮(むなかたたいしゃ なかつぐう)」に行きました。「神宿る島」宗像・沖ノ島と関連遺産群の一つです。沖ノ島は一般観光客は入ることができませんので、沖ノ島が臨める大島へ向かいました。Map_oshima_180812.png ちなみに、「宗像大社」はホームページによると以下の三宮を総称したもので、三女神がそれぞれ祀られているとのこと。
 田心姫神(たごりひめのかみ)・・沖津宮(おきつぐう) → 沖ノ島
 湍津姫神(たぎつひめのかみ)・・中津宮(なかつぐう) → 大島
 市杵島姫神(いちきしまひめのかみ)・・辺津宮(へつぐう) → 九州本土(総社・宗像大社)


 博多駅からJRの快速に乗って東郷駅で下車。その後、西鉄バスで神湊(こうのみなと)フェリーターミナルに向かいました。大島行のフェリー「おおしま」に乗り込み、いざ出発!Ferry_oshiima_180812.pngフェリー4Fフロアの屋外デッキで潮の匂いと潮風を浴びながら、心地良い約30分ほどの船旅でした。現実逃避には船旅が一番ですね。日々の疲れや悩みもその時は些細なものに思えました・・。

 大島に上陸後、フェリーターミナル近くの物産直売所「さよしま」で「魚ロッケ」を購入。大変美味しかったです。gyoroke_180812.png中津宮にお参り後、大島交流館まで海岸線を歩きましした。天気も良く熱中症になりそうな暑さでした。nakatsugu_180812.png
 その後、バスで「砲台跡」へ。大島にはレンタサイクルもあるのですが、かなりの山道で、バスを選択したのは正解でした。山道を抜けると、視界が急に広がり眼の前に海が一面に。大変素晴らしいパノラマビューです。赤い風車が青い海と緑の草原とマッチしていました。Fuusya_180812.png運が良ければ、この場所から沖ノ島が見えるのですが、残念なことに靄がかっていて確認できませんでした。砲弾は太平洋戦争時代の昭和11年に完成したとのことで、現在はコンクリートの基礎を残すのみです。Houdan_180812.png
 大島を経つ前に、自分へのお土産として「塩サイダー」を購入。salt_cider_180812.png普通のサイダーと違って後味が優しい感じです。かなり汗をかいたので、「塩分補給ヨシ!」です。

 九州本土の神湊にフェリーで戻ってきた後は、総社・宗像大社をお参りしました。神宝館で「沖ノ島国宝」と「沖ノ島」の写真集で知られる藤原新也氏のコラボ展示会を観覧。exhibition_180812.png国宝ばかりで久々に大変見応えのある展示でした。
 今回も大変良い息抜きができました。

池井戸潤著『下町ロケット ゴースト』

『下町ロケット』は第一弾から読んでいるので、今回の第三弾の『下町ロケット ゴースト』も早速読んでみました。

 読んだ感想ですが、う〜ん・・・です。満たされない気持ちというか、完結しないモヤモヤなのか、分かりませんが、第一弾、第二弾に比べ、後味が中途半端です。すでに続編の第四弾が準備されているようで、『下町ロケット ヤタガラス』2018年秋発売予定とのこと。そのための「つなぎ」だったのでしょうか?うまい商売ですね・・・。
 期待しているストーリー展開も私にとっては物足りないもので、予測可能な展開でした。あまり喋るとネタバレしてしまうので、これ以上言いませんが、残念感が拭えません。第四弾に続くとのことなので、そちらに「かなり」期待したいと思います。第三弾の物足りなさが、第四弾の伏線ならば納得もしますが・・。(ご注意:本内容は、あくまでも個人の意見で、著者や作品を批難するものではありません・・)

Ubuntu18.04にOpenCV実行環境を作る(2)

 前回はmatplotlibを使って画像を表示させましたが、今回はTkinterを使って、GUIにボタンや画像表示部を実装して表示させました。

 まずは、PIL(Python Imaging Library)を用いて、GUI上の「Load Image」ボタンを押すと、「PILのOpen関数」で指定している画像ファイルを読み込み、キャンバス上に画像を表示させるコードを実行させました。OpenCVを使わずに画像を読み込み、表示させるパターンです。
import tkinter
from tkinter import font
from PIL import Image, ImageTk

class Application(tkinter.Frame):

def __init__(self, master=None):
super().__init__(master, height=300, width=400)
self.pack()
self.create_widgets()

def create_widgets(self):
self.canvas = tkinter.Canvas(
root, # 親要素をメインウィンドウに設定
width = 320, # 幅を設定
height = 240, # 高さを設定
relief= tkinter.RIDGE, # 枠線を表示
bd=0 # 枠線の幅を設定
)
self.canvas.place(x=10, y=10) # メインウィンドウ上に配置

self.LoadImage_btn = tkinter.Button(self)
self.LoadImage_btn["text"] = "Load Image"
self.LoadImage_btn["command"] = self.Image_get
my_font = font.Font(root,family="Helvetica",size=16,weight="bold")
self.LoadImage_btn["font"] = my_font
self.LoadImage_btn.place(x=50, y=255)

def Image_get(self):
im = Image.open('flower.png')
self.img = ImageTk.PhotoImage(im) # 表示するイメージを用意

self.canvas.create_image( # キャンバス上にイメージを配置
0, # x座標
0, # y座標
image = self.img, # 配置するイメージオブジェクトを指定
anchor = tkinter.NW # 配置の起点となる位置を左上隅に指定
)

root = tkinter.Tk()
app = Application(master=root)
app.mainloop()
起動画面はこんな感じです。run1_1800804.png「Load Image」ボタンを押すとrun2_1800804.png画像が読み込まれ、キャンバスに表示されました。

 PILは簡単な画像処理もできるようですが、本命のOpenCVに話を戻します。次に「OpenCVのimread関数」で画像を読み込むパターンです(31行目)。GUI上のキャンバスに画像を表示させる部分はPILを用いています。PILは表示だけに使います。
import tkinter
from tkinter import font
from PIL import Image, ImageTk
import cv2

class Application(tkinter.Frame):

def __init__(self, master=None):
super().__init__(master, height=300, width=400)
self.pack()
self.create_widgets()

def create_widgets(self):
self.canvas = tkinter.Canvas(
root, # 親要素をメインウィンドウに設定
width = 320, # 幅を設定
height = 240, # 高さを設定
relief= tkinter.RIDGE, # 枠線を表示
bd=0 # 枠線の幅を設定
)
self.canvas.place(x=10, y=10) # メインウィンドウ上に配置

self.LoadImage_btn = tkinter.Button(self)
self.LoadImage_btn["text"] = "Load Image"
self.LoadImage_btn["command"] = self.Image_get
my_font = font.Font(root,family="Helvetica",size=16,weight="bold")
self.LoadImage_btn["font"] = my_font
self.LoadImage_btn.place(x=50, y=255)

def Image_get(self):
im = cv2.imread("flower.png")
im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
self.img = ImageTk.PhotoImage(Image.fromarray(im)) # 表示するイメージを用意

self.canvas.create_image( # キャンバス上にイメージを配置
0, # x座標
0, # y座標
image = self.img, # 配置するイメージオブジェクトを指定
anchor = tkinter.NW # 配置の起点となる位置を左上隅に指定
)

root = tkinter.Tk()
app = Application(master=root)
app.mainloop()
これも、当然ながら同じ結果が得られます。

 Python環境でも簡単にOpenCVを実行できるGUIが構築できることが分かりました。C#(OpenCvSharp)やC++/CLIでプログラムを作成する場合、ビルドして画像処理を確認する必要があり、手間がかかりますが、GUIを実装したPythonなら手軽に実行でき、デバッグ等も便利かもしれません。今後、利用していこうと思います。

ご訪問者数

(Since 24 July, 2016)

タグクラウド


プロフィール

Dr.BobT

Author: Dr.BobT
興味のおもむくままに生涯考え続けるエンジニアでありたい。

月別アーカイブ

メールフォーム

名前:
メール:
件名:
本文: