-
-
Save nomissbowling/6dbb6772e0e6f23ef1f159fcbda4c284 to your computer and use it in GitHub Desktop.
カメラ画像加工器その6 完成コード
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf-8 | |
import os, sys | |
import wx | |
import cv2 | |
import cvframe | |
import datetime | |
import configparser | |
import numpy as np | |
from threading import Event, Thread | |
import winsound | |
import re | |
"""---------------------------------------------- | |
カメラ | |
グローバル定数 | |
path : 実行ファイルのディレクトリ | |
today : 今日の日付 | |
now : 今の時間 | |
INI : 設定ファイルの場所 | |
capture : カメラのマウント | |
camera : 起動したときはカメラモードにする | |
設定ファイルに最後に保存したディレクトリの情報を記載する | |
----------------------------------------------""" | |
path = os.path.dirname( sys.argv[0] ) | |
now = datetime.datetime.now() | |
INI = path + "/INI.conf" | |
conf = configparser.SafeConfigParser() | |
capture = cv2.VideoCapture(0) | |
capture.grab() | |
cascade_path = "C:/Users/" + os.getlogin() + "/AppData/Local/Programs/Python/Python35-32/Lib/site-packages/cv2/data/" | |
cascade_list = os.listdir(cascade_path) | |
cascade_files = [f for f in cascade_list if os.path.splitext(f)[1] == ".xml"] | |
class Mainframe( cvframe.MyFrame1 ): | |
def __init__( self, parent ): | |
cvframe.MyFrame1.__init__( self, parent ) | |
self.nowtime = now.strftime( "%H:%M:%S" ) | |
self.today = now.strftime( "%Y/%m/%d" ) | |
self.camera = True | |
self.m_listBox1.SetItems(cascade_files) | |
self.m_listBox1.SetSelection(0) | |
def camera_button( self, event ): | |
self.camera = True | |
def Fileopen( self, event ): | |
"""FileDialog(parent, message=FileSelectorPromptStr, | |
defaultDir="", defaultFile="", | |
wildcard=FileSelectorDefaultWildcardStr, style=FD_DEFAULT_STYLE, | |
pos=DefaultPosition, size=DefaultSize, name=FileDialogNameStr)""" | |
filter = "JPG file(*.jpg)|*.jpg|PNG file(*.png)|*.png|All file(*.*)|*.*" | |
file = wx.FileDialog( None, "ファイルの選択", ".", wildcard = filter, | |
name="画像の選択") | |
result = file.ShowModal() | |
if result == 5101: | |
return | |
self.filename = file.GetPath() | |
print(self.filename) | |
# バイナリから読み込み | |
with open(self.filename, 'rb') as f: | |
binary = f.read() | |
# 一度ndarrayに変換してからdecodeする。日本語ファイルに対応 | |
self.arr = np.asarray(bytearray(binary), dtype=np.uint8) | |
self.camera = False | |
def Grafbutton( self, event ): | |
print("画像を見る") | |
thread = Thread(target = self.Viewloop, name = "loop", args=()) | |
thread.start() | |
def Viewloop(self): | |
negative = False | |
WINDOW_NAME = "frame" | |
self.firstcap = False | |
cv2.namedWindow(WINDOW_NAME, cv2.WINDOW_NORMAL) | |
while not threadevent.wait(0.1): | |
# カメラモードと画像モードはソースを変えるだけ | |
if self.camera: | |
ret, image = capture.read() | |
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) | |
else: | |
image = cv2.imdecode(self.arr, cv2.IMREAD_UNCHANGED) | |
gray = cv2.imdecode(self.arr, cv2.IMREAD_GRAYSCALE) | |
p1, p2 = self.p1_Val.GetValue(), self.p2_Val.GetValue() | |
effect = self.m_radioBox1.GetSelection() | |
# 効果の選択 | |
if effect == 0: | |
im = image | |
elif effect == 1: | |
im = gray | |
elif effect == 2: | |
im = cv2.Canny(gray, p1, p2) | |
elif effect == 3: | |
ret, im = cv2.threshold(gray, p1, 255, cv2.THRESH_BINARY) | |
else: | |
break | |
# waitKeyの戻り値に0xffをつけることでASCIIコードにする | |
k = cv2.waitKey(10)&0xff | |
# ord(文字)でASCIIコードにする | |
live = cv2.getWindowProperty(WINDOW_NAME, 0) == 0 | |
if k == ord("1"): | |
print("オリジナル") | |
effect = 0 | |
elif k == ord("2"): | |
print("グレー") | |
effect = 1 | |
elif k == ord("3"): | |
print("エッジ") | |
effect = 2 | |
elif k == ord("4"): | |
print("2値化") | |
effect = 3 | |
elif k == ord("n"): | |
if negative: | |
negative = False | |
else: | |
negative =True | |
# elif k == ord("s"): | |
# self.imagesave(im) | |
elif not live and self.firstcap: | |
print("終わり") | |
threadevent.set() | |
break | |
self.m_radioBox1.SetSelection(effect) | |
if negative: | |
im = cv2.bitwise_not(im) | |
# 画像認識する場合 | |
if self.m_checkBox1.GetValue(): | |
cascade = cv2.CascadeClassifier(os.path.join(cascade_path, self.m_listBox1.GetStringSelection())) | |
detect = cascade.detectMultiScale(gray) | |
for rect in detect: | |
cv2.rectangle(im, tuple(rect[0:2]), tuple(rect[0:2] + rect[2:4]), (0,255,255), thickness=2) | |
if k == ord("s"): | |
self.imagesave(im) | |
cv2.imshow(WINDOW_NAME, im) | |
self.firstcap = True | |
threadevent.clear() | |
cv2.destroyAllWindows() | |
def imagesave( self, im ): | |
savepath = self.m_dirPicker1.GetPath() # 手動保存のディレクトリ | |
file_name = "pic_" | |
if os.path.exists( savepath ) or savepath == "": | |
savepath = path | |
else: | |
os.mkdir(savepath) | |
save_file = self.New_file(savepath, file_name)[0] | |
cv2.imwrite(save_file, im) | |
winsound.PlaySound('SystemAsterisk', winsound.SND_ASYNC) | |
print(save_file) # パスを表示 | |
return | |
def New_file( self, dir, file_name ): | |
# ディレクトリのパスを受け取って最高値+1のファイル名を返す | |
# 同名ファイルのナンバリング最高値を求める | |
dir_list = os.listdir(dir) # フォルダの中身をリスト化 | |
if len(dir_list) == 0: # ディレクトリ内にファイルがない場合は00000 | |
return dir + "/" + file_name + "00000" + ".jpg", "00000" | |
if [s for s in dir_list if s.startswith(file_name)]: | |
max_num = max([s for s in dir_list if s.startswith(file_name)]).split(".")[0] | |
max_num = re.sub(file_name, r"", max_num) # ファイル名を削除 | |
new_file = "{0:05d}".format(int(max_num)+1) # ファイル名に+1して5ケタでゼロサプレスする | |
else: | |
new_file = "00000" | |
return dir + "/" + file_name + new_file + ".jpg", new_file | |
def ExitHandler( self, event ): | |
dlg = wx.MessageDialog( None, 'カメラで遊ぶ奴を終了します。\nよろしいですか?', | |
"カメラで遊ぶ奴", style = wx.YES_NO ) | |
result = dlg.ShowModal() #ダイアログの表示 | |
if result == wx.ID_YES: #はいを押した時終了 | |
threadevent.set() | |
sys.exit() #プログラム終了 | |
else: #いいえの時は何もしない | |
return | |
thread = Thread(target=Mainframe) | |
threadevent = Event() | |
app = wx.App( False ) | |
frame = Mainframe( None ) | |
frame.Show( True ) | |
app.MainLoop() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
########################################################################### | |
## Python code generated with wxFormBuilder (version Nov 6 2017) | |
## http://www.wxformbuilder.org/ | |
## | |
## PLEASE DO *NOT* EDIT THIS FILE! | |
########################################################################### | |
import wx | |
import wx.xrc | |
########################################################################### | |
## Class MyFrame1 | |
########################################################################### | |
class MyFrame1 ( wx.Frame ): | |
def __init__( self, parent ): | |
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"カメラで遊ぶ奴", pos = wx.DefaultPosition, size = wx.Size( 684,380 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL ) | |
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize ) | |
bSizer1 = wx.BoxSizer( wx.VERTICAL ) | |
self.m_panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL ) | |
self.m_panel1.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_INFOTEXT ) ) | |
self.m_panel1.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_INFOBK ) ) | |
bSizer2 = wx.BoxSizer( wx.VERTICAL ) | |
bSizer6 = wx.BoxSizer( wx.HORIZONTAL ) | |
bSizer4 = wx.BoxSizer( wx.VERTICAL ) | |
sbSizer1 = wx.StaticBoxSizer( wx.StaticBox( self.m_panel1, wx.ID_ANY, u"画像認識処理" ), wx.VERTICAL ) | |
self.m_checkBox1 = wx.CheckBox( sbSizer1.GetStaticBox(), wx.ID_ANY, u"画像認識(重い)", wx.DefaultPosition, wx.DefaultSize, 0 ) | |
sbSizer1.Add( self.m_checkBox1, 0, wx.ALL, 5 ) | |
m_listBox1Choices = [] | |
self.m_listBox1 = wx.ListBox( sbSizer1.GetStaticBox(), wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, m_listBox1Choices, wx.LB_HSCROLL|wx.LB_NEEDED_SB ) | |
sbSizer1.Add( self.m_listBox1, 1, wx.ALL|wx.EXPAND, 5 ) | |
bSizer4.Add( sbSizer1, 1, wx.EXPAND, 5 ) | |
bSizer6.Add( bSizer4, 1, wx.EXPAND, 5 ) | |
bSizer3 = wx.BoxSizer( wx.VERTICAL ) | |
m_radioBox1Choices = [ u"元画像", u"グレースケール", u"エッジ検出", u"2値化" ] | |
self.m_radioBox1 = wx.RadioBox( self.m_panel1, wx.ID_ANY, u"処理", wx.DefaultPosition, wx.DefaultSize, m_radioBox1Choices, 2, wx.RA_SPECIFY_COLS ) | |
self.m_radioBox1.SetSelection( 0 ) | |
bSizer3.Add( self.m_radioBox1, 0, wx.ALL|wx.EXPAND, 5 ) | |
self.m_button1 = wx.Button( self.m_panel1, wx.ID_ANY, u"表示", wx.DefaultPosition, wx.DefaultSize, 0 ) | |
bSizer3.Add( self.m_button1, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, 5 ) | |
bSizer5 = wx.BoxSizer( wx.HORIZONTAL ) | |
self.m_staticText1 = wx.StaticText( self.m_panel1, wx.ID_ANY, u"p1", wx.DefaultPosition, wx.DefaultSize, 0 ) | |
self.m_staticText1.Wrap( -1 ) | |
bSizer5.Add( self.m_staticText1, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) | |
self.p1_Val = wx.Slider( self.m_panel1, wx.ID_ANY, 50, 0, 500, wx.DefaultPosition, wx.DefaultSize, wx.SL_LABELS ) | |
bSizer5.Add( self.p1_Val, 0, wx.ALL, 5 ) | |
self.m_staticText2 = wx.StaticText( self.m_panel1, wx.ID_ANY, u"p2", wx.DefaultPosition, wx.DefaultSize, 0 ) | |
self.m_staticText2.Wrap( -1 ) | |
bSizer5.Add( self.m_staticText2, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 ) | |
self.p2_Val = wx.Slider( self.m_panel1, wx.ID_ANY, 100, 0, 500, wx.DefaultPosition, wx.DefaultSize, wx.SL_LABELS ) | |
bSizer5.Add( self.p2_Val, 0, wx.ALL, 5 ) | |
bSizer3.Add( bSizer5, 0, wx.EXPAND, 5 ) | |
bSizer6.Add( bSizer3, 1, wx.EXPAND, 5 ) | |
bSizer2.Add( bSizer6, 1, wx.EXPAND, 5 ) | |
self.m_dirPicker1 = wx.DirPickerCtrl( self.m_panel1, wx.ID_ANY, wx.EmptyString, u"Select a folder", wx.DefaultPosition, wx.DefaultSize, wx.DIRP_DEFAULT_STYLE ) | |
bSizer2.Add( self.m_dirPicker1, 0, wx.ALL|wx.EXPAND, 5 ) | |
self.m_panel1.SetSizer( bSizer2 ) | |
self.m_panel1.Layout() | |
bSizer2.Fit( self.m_panel1 ) | |
bSizer1.Add( self.m_panel1, 1, wx.EXPAND, 5 ) | |
self.SetSizer( bSizer1 ) | |
self.Layout() | |
self.m_menubar1 = wx.MenuBar( 0 ) | |
self.m_menubar1.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, wx.EmptyString ) ) | |
self.m_File0 = wx.Menu() | |
self.m_menuItemF0 = wx.MenuItem( self.m_File0, wx.ID_ANY, u"画像を開く", wx.EmptyString, wx.ITEM_NORMAL ) | |
self.m_File0.Append( self.m_menuItemF0 ) | |
self.m_menuItemF1 = wx.MenuItem( self.m_File0, wx.ID_ANY, u"カメラ", wx.EmptyString, wx.ITEM_NORMAL ) | |
self.m_File0.Append( self.m_menuItemF1 ) | |
self.m_menuItemFE = wx.MenuItem( self.m_File0, wx.ID_ANY, u"終了", wx.EmptyString, wx.ITEM_NORMAL ) | |
self.m_File0.Append( self.m_menuItemFE ) | |
self.m_menubar1.Append( self.m_File0, u"ファイル" ) | |
self.m_menu6 = wx.Menu() | |
self.m_menubar1.Append( self.m_menu6, u"設定" ) | |
self.SetMenuBar( self.m_menubar1 ) | |
self.m_statusBar1 = self.CreateStatusBar( 1, wx.STB_SIZEGRIP, wx.ID_ANY ) | |
self.Centre( wx.BOTH ) | |
# Connect Events | |
self.Bind( wx.EVT_CLOSE, self.ExitHandler ) | |
self.m_button1.Bind( wx.EVT_BUTTON, self.Grafbutton ) | |
self.p1_Val.Bind( wx.EVT_SCROLL, self.change_val ) | |
self.p2_Val.Bind( wx.EVT_SCROLL, self.change_val ) | |
self.Bind( wx.EVT_MENU, self.Fileopen, id = self.m_menuItemF0.GetId() ) | |
self.Bind( wx.EVT_MENU, self.camera_button, id = self.m_menuItemF1.GetId() ) | |
self.Bind( wx.EVT_MENU, self.ExitHandler, id = self.m_menuItemFE.GetId() ) | |
def __del__( self ): | |
pass | |
# Virtual event handlers, overide them in your derived class | |
def ExitHandler( self, event ): | |
event.Skip() | |
def Grafbutton( self, event ): | |
event.Skip() | |
def change_val( self, event ): | |
event.Skip() | |
def Fileopen( self, event ): | |
event.Skip() | |
def camera_button( self, event ): | |
event.Skip() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment