###前提・実現したいこと
Pythonを使って、動画や画像を表示するGUIを作っています。その中で、みなさまのご支援を頂ながらカメラの画像を取り込んで再生できるところまで来ました。
###発生している問題・エラーメッセージ
GUIのウインドウを閉じると、GUIを閉じることはできるのですが、threadがまだ残っているのかコマンドプロンプトのコントロールが帰ってきません。
###該当のソースコード
Python
1import wx 2import os 3import cv2 4import numpy as np 5import threading 6import sys 7 8GUI_IMAGE_X = 240 9 10GUI_IMAGE_Y = 180 11CAMMODE = False 12 13######################################################################## 14class DnDPanel(wx.Panel): 15 16 #---------------------------------------------------------------------- 17 def __init__(self, parent): 18 wx.Panel.__init__(self, parent=parent) 19 20 # Image box 21 img = wx.Image(GUI_IMAGE_X,GUI_IMAGE_Y) 22 23 # Statc bitmap 24 self.imageCtrl = wx.StaticBitmap(self, wx.ID_ANY,wx.Bitmap(img)) 25 26 # Text box 27 self.fileTextCtrl = wx.TextCtrl(self,style=wx.TE_MULTILINE|wx.HSCROLL|wx.TE_READONLY) 28 29 sizer = wx.BoxSizer(wx.HORIZONTAL) 30 sizer.Add(self.imageCtrl, 1, wx.ALL, 5) 31 sizer.Add(self.fileTextCtrl, 1, wx.EXPAND|wx.ALL, 5) 32 self.SetSizer(sizer) 33 self.Fit() 34 35 #---------------------------------------------------------------------- 36 def updateText(self, text): 37 #Overwtite a text 38 self.fileTextCtrl.SetValue(text) 39 40 #Add a text 41 #self.fileTextCtrl.WriteText(text) 42 43 #---------------------------------------------------------------------- 44 def updateImage_Entity(self, cv2image): 45 46 # Calculate aspect rat 47 mag_X = GUI_IMAGE_X / cv2image.shape[1] 48 mag_Y = GUI_IMAGE_Y / cv2image.shape[0] 49 50 if mag_X < mag_Y: 51 img = cv2.resize(cv2image, None, fx = mag_X, fy = mag_X) 52 else: 53 img = cv2.resize(cv2image, None, fx = mag_Y, fy = mag_Y) 54 55 # Calculate aspect ratio diff 56 # X-axis 57 diff_X = GUI_IMAGE_X - img.shape[1] 58 diff_X_start = round(diff_X/2) 59 diff_X_end = diff_X_start + img.shape[1] 60 61 # Y-axis 62 diff_Y = GUI_IMAGE_Y - img.shape[0] 63 diff_Y_start = round(diff_Y/2) 64 diff_Y_end = diff_Y_start + img.shape[0] 65 #print("[(%s,%s) : (%s,%s)]"%(diff_X_start,diff_Y_start,diff_X_end,diff_Y_end)) 66 67 # Create modified picture 68 bg_image = np.zeros((GUI_IMAGE_Y, GUI_IMAGE_X, 3), np.uint8) 69 70 bg_image[diff_Y_start:diff_Y_end,diff_X_start:diff_X_end] = img 71 # BGR --> RGB 72 img = cv2.cvtColor(bg_image, cv2.COLOR_BGR2RGB) 73 74 # Convert color array to bitmap image 75 img = wx.Bitmap.FromBuffer(img.shape[1], img.shape[0], img) 76 77 #Static bitmap 78 self.imageCtrl.SetBitmap(img) 79 80 81######################################################################## 82class CameraControl(threading.Thread): 83 84 def __init__(self,parent): 85 threading.Thread.__init__(self) 86 87 # Prepare camera mode 88 self.panelText = DnDPanel(parent).updateText 89 self.panelImage = DnDPanel(parent).updateImage_Entity 90 91 #---------------------------------------------------------------------- 92 def run(self): 93 94 global CAMMODE 95 if CAMMODE == False: 96 return False 97 98 # End other daemon thread at first 99 while threading.activeCount() > 2: 100 CAMMODE = False 101 102 # Start only one daemon thread 103 CAMMODE = True 104 105 while CAMMODE == True : 106 # Get camera information : "0" is device numer 107 cap = cv2.VideoCapture(0) 108 ret, frame = cap.read() 109 while ret == False: 110 # Get camera information : "0" is device numer 111 cap = cv2.VideoCapture(0) 112 ret, frame = cap.read() 113 self.panelText("ERROR: Camera is not working.") 114 return False 115 116 while ret == True: 117 cv2.waitKey(1) 118 ret, frame = cap.read() 119 self.panelText("Camera mode") 120 # Load an image to entity from file 121 self.panelImage(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) 122 123 if CAMMODE == False: 124 ret = False 125 126######################################################################## 127class DnDFrame(wx.Frame): 128 #---------------------------------------------------------------------- 129 def __init__(self): 130 self.window = wx.Frame.__init__(self, parent=None, title="GUI test", style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER) 131 132 self.InitMenu() 133 self.panel = DnDPanel(self) 134 self.Fit() 135 136 self.cc = CameraControl(self) 137 self.cc.setDaemon(True) 138 self.cc.start() 139 140 self.Show() 141 142 #---------------------------------------------------------------------- 143 # Initialize 144 def InitMenu(self): 145 # Menubar 146 menubar = wx.MenuBar() 147 fileMenu = wx.Menu() 148 f_item2 = fileMenu.Append(wx.ID_ANY, '&Camera(C)', 'Load image from USB camera') 149 fileMenu.AppendSeparator() 150 f_item3 = fileMenu.Append(wx.ID_ANY, '&Quit(Q)', 'Quit application') 151 menubar.Append(fileMenu, '&File(F)') 152 153 self.SetMenuBar(menubar) 154 155 # Event call definition 156 self.Bind(wx.EVT_MENU, self.OnCamera, f_item2) 157 self.Bind(wx.EVT_MENU, self.OnQuit, f_item3) 158 159 # Frame definition 160 self.Centre() 161 162 # Status bar 163 self.CreateStatusBar() 164 self.setstatusbarTXT("") 165 166 self.Show(True) 167 168 #---------------------------------------------------------------------- 169 # Event hander: set status text 170 def setstatusbarTXT(self, msg): 171 self.SetStatusText(msg) 172 173 #---------------------------------------------------------------------- 174 # Event: Quit 175 def OnQuit(self,event): 176 global CAMMODE 177 CAMMODE = False 178 179 sys.exit() 180 181 #---------------------------------------------------------------------- 182 # Event: Camera 183 def OnCamera(self, event): 184 global CAMMODE 185 CAMMODE = True 186 self.panel.updateText("Camera mode") 187 self.setstatusbarTXT("Camera mode") 188 189 self.cc = CameraControl(self) 190 self.cc.setDaemon(True) 191 self.cc.start() 192 193#---------------------------------------------------------------------- 194if __name__ == "__main__": 195 app = wx.App(False) 196 frame = DnDFrame() 197 app.MainLoop() 198
###試したこと
class CameraControlのrunにあるwhileloopの中にprint("foobar")のようなでバグ文字列を吐かせましたが、GUI終了時にはデバグ文字列は出てきませんでしたので、whileloopで躓いているわけではなさそうです。
###補足情報
Win10(64bit)
Python 3.5.3(64bit)
wxPython 4.0.0a1 (Phoenix)
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/05/20 03:47 編集
2017/05/20 04:16
退会済みユーザー
2017/05/20 07:51