質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1778閲覧

pythonにおけるGLOBAL変数について

kokawa2003

総合スコア217

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/08/03 05:37

編集2019/08/03 06:26

PythonでプログラムしていますがGLOBALなオブジェクトの扱いがよくわかりません。
以下のソースを見てください。

python

1import cv2 2import transformer 3import torch 4import utils 5from imutils import paths 6import argparse 7import itertools 8 9PRESERVE_COLOR = False 10 11 12 13net=None 14device=None 15 16def myinit(): 17 net=None 18 device=None 19 """ 20 Captures and saves an image, perform style transfer, and again saves the styled image. 21 Reads the styled image and show in window. 22 23 Saving and loading SHOULD BE eliminated, however this produces too much whitening in 24 the "generated styled image". This may be caused by the async nature of VideoCapture, 25 and I don't know how to fix it. 26 """ 27 mypath="C:\Users\oakoa\work\fast_neural_style_transfer\model_path" 28 29 modelPaths = paths.list_files(mypath, validExts=('.pth',)) 30 modelPaths = sorted(list(modelPaths)) 31 32 modelIter = itertools.cycle(modelPaths) 33 # Device 34 device = ("cuda" if torch.cuda.is_available() else "cpu") 35 36 # Load Transformer Network 37 print("Loading Transformer Network") 38 net = transformer.TransformerNetwork() 39 modelPath = next(modelIter) 40 net.load_state_dict(torch.load(modelPath)) 41 net = net.to(device) 42 print("Done Loading Transformer Network") 43 44 45 46 47def mainfunc(): 48 myinit() 49 50 # Set webcam settings 51 mycam = cv2.VideoCapture("rtsp://192.168.100.142:8554/in.mp4") 52 53 # Main loop 54 with torch.no_grad(): 55 count = 1 56 while True: 57 # Get webcam input 58 ret_val, img = mycam.read() 59 60 # Mirror 61 #img = cv2.flip(img, 1) 62 key=0 63 try: 64 height = img.shape[0] 65 width = img.shape[1] 66 d=1 67 img = cv2.resize(img , (int(width*d), int(height*d))) 68 69 print("P1") 70 # Free-up unneeded cuda memory 71 torch.cuda.empty_cache() 72 73 print("P2") 74 # Generate image 75 content_tensor = utils.itot(img).to(device) 76 print("P3") 77 generated_tensor = net(content_tensor) 78 print("P4") 79 generated_image = utils.ttoi(generated_tensor.detach()) 80 if (PRESERVE_COLOR): 81 generated_image = utils.transfer_color(content_image, generated_image) 82 img2 = cv2.imdecode(cv2.imencode(".png", generated_image)[1], cv2.IMREAD_UNCHANGED) 83 84 count += 2 85 # Show webcam 86 #img3 = cv2.flip(img2, 1) 87 d=1 88 img = cv2.resize(img , (int(width*d), int(height*d))) 89 cv2.imshow('real', img) 90 img2 = cv2.resize(img2 , (int(width*d), int(height*d))) 91 cv2.imshow('Demo webcam', img2) 92 key = cv2.waitKey(1) & 0xFF 93 except: 94 print('error occured') 95 96 if key == ord('n'): 97 modelPath = next(modelIter) 98 net.load_state_dict(torch.load(modelPath)) 99 net = net.to(device) 100 101 if key == ord('y'): #save on pressing 'y' 102 cv2.imwrite(f'images/capture/c{count}.png',img2) 103 104 105 elif key == ord('q'): 106 break # q to quit 107 108 # Free-up memories 109 mycam.release() 110 cv2.destroyAllWindows() 111 112# print(next(modelPaths)) 113mainfunc()

これなのですが実行すると
generated_tensor = net(content_tensor)
のところで落ちてしまいます。
しかし初期化のコードを関数でするのをやめて直接書くとうまく動きます。

python

1import cv2 2import transformer 3import torch 4import utils 5from imutils import paths 6import argparse 7import itertools 8 9PRESERVE_COLOR = False 10 11 12 13net=None 14device=None 15 16def mainfunc(): 17 net=None 18 device=None 19 """ 20 Captures and saves an image, perform style transfer, and again saves the styled image. 21 Reads the styled image and show in window. 22 23 Saving and loading SHOULD BE eliminated, however this produces too much whitening in 24 the "generated styled image". This may be caused by the async nature of VideoCapture, 25 and I don't know how to fix it. 26 """ 27 mypath="C:\Users\oakoa\work\fast_neural_style_transfer\model_path" 28 29 modelPaths = paths.list_files(mypath, validExts=('.pth',)) 30 modelPaths = sorted(list(modelPaths)) 31 32 modelIter = itertools.cycle(modelPaths) 33 # Device 34 device = ("cuda" if torch.cuda.is_available() else "cpu") 35 36 # Load Transformer Network 37 print("Loading Transformer Network") 38 net = transformer.TransformerNetwork() 39 modelPath = next(modelIter) 40 net.load_state_dict(torch.load(modelPath)) 41 net = net.to(device) 42 print("Done Loading Transformer Network") 43 # Set webcam settings 44 mycam = cv2.VideoCapture("rtsp://192.168.100.142:8554/in.mp4") 45 46 # Main loop 47 with torch.no_grad(): 48 count = 1 49 while True: 50 # Get webcam input 51 ret_val, img = mycam.read() 52 53 # Mirror 54 #img = cv2.flip(img, 1) 55 key=0 56 try: 57 height = img.shape[0] 58 width = img.shape[1] 59 d=1 60 img = cv2.resize(img , (int(width*d), int(height*d))) 61 62 print("P1") 63 # Free-up unneeded cuda memory 64 torch.cuda.empty_cache() 65 66 print("P2") 67 # Generate image 68 content_tensor = utils.itot(img).to(device) 69 print("P3") 70 generated_tensor = net(content_tensor) 71 print("P4") 72 generated_image = utils.ttoi(generated_tensor.detach()) 73 if (PRESERVE_COLOR): 74 generated_image = utils.transfer_color(content_image, generated_image) 75 img2 = cv2.imdecode(cv2.imencode(".png", generated_image)[1], cv2.IMREAD_UNCHANGED) 76 77 count += 2 78 # Show webcam 79 #img3 = cv2.flip(img2, 1) 80 d=1 81 img = cv2.resize(img , (int(width*d), int(height*d))) 82 cv2.imshow('real', img) 83 img2 = cv2.resize(img2 , (int(width*d), int(height*d))) 84 cv2.imshow('Demo webcam', img2) 85 key = cv2.waitKey(1) & 0xFF 86 except: 87 print('error occured') 88 89 if key == ord('n'): 90 modelPath = next(modelIter) 91 net.load_state_dict(torch.load(modelPath)) 92 net = net.to(device) 93 94 if key == ord('y'): #save on pressing 'y' 95 cv2.imwrite(f'images/capture/c{count}.png',img2) 96 97 98 elif key == ord('q'): 99 break # q to quit 100 101 # Free-up memories 102 mycam.release() 103 cv2.destroyAllWindows() 104 105# print(next(modelPaths)) 106mainfunc()

これから見るとpythonでGLOBALなオブジェクトを宣言するときはどうも=Noneではまずいらしいですが
どうすべきか知っている人はいませんか?

追記
GLOBALな変数についてしったのでこう直しても同じでした

python

1 2def myinit(): 3 global modelIter 4 global device 5 global mynet 6 7 mypath="C:\Users\oakoa\work\fast_neural_style_transfer\model_path" 8 9 modelPaths = paths.list_files(mypath, validExts=('.pth',)) 10 modelPaths = sorted(list(modelPaths)) 11 12 modelIter= itertools.cycle(modelPaths) 13 print(modelIter) 14 # Device 15 device = ("cuda" if torch.cuda.is_available() else "cpu") 16 # Load Transformer Network 17 print("Loading Transformer Network") 18 mynet = transformer.TransformerNetwork() 19 print(mynet) 20 modelPath = next(modelIter) 21 mynet.load_state_dict(torch.load(modelPath)) 22 mynet = mynet.to(device) 23 print("Done Loading Transformer Network") 24 25 26

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

グローバル変数とローカル変数について誤解がありそうです。

関数の中で行われた代入は原則すべてローカル変数に対して実行されます。たとえ同名のグローバル変数が存在していても、そちらには何ら影響はなく、同名のローカル変数が新たに作られます。

だから、そのmyinitはほとんど何もしていないのと同じです。

global宣言を使うか、結果を返り値で返すようにするのがいいかと。

投稿2019/08/03 06:16

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kokawa2003

2019/08/03 06:21 編集

それを今知ったので変更しましたが結果は変わりませんでした。 ```python import cv2 import transformer import torch import utils from imutils import paths import argparse import itertools PRESERVE_COLOR = False modelIter=None device=None; mynet=None; def myinit(): global modelIter global device global mynet mypath="C:\Users\oakoa\work\fast_neural_style_transfer\model_path" modelPaths = paths.list_files(mypath, validExts=('.pth',)) modelPaths = sorted(list(modelPaths)) modelIter= itertools.cycle(modelPaths) print(modelIter) # Device device = ("cuda" if torch.cuda.is_available() else "cpu") # Load Transformer Network print("Loading Transformer Network") mynet = transformer.TransformerNetwork() print(mynet) modelPath = next(modelIter) mynet.load_state_dict(torch.load(modelPath)) mynet = mynet.to(device) print("Done Loading Transformer Network") def mainfunc(): myinit() print("myinitend") # Set webcam settings mycam = cv2.VideoCapture("rtsp://192.168.100.142:8554/in.mp4") # Main loop with torch.no_grad(): count = 1 while True: # Get webcam input ret_val, img = mycam.read() # Mirror #img = cv2.flip(img, 1) key=0 try: height = img.shape[0] width = img.shape[1] d=1 img = cv2.resize(img , (int(width*d), int(height*d))) print("P1") # Free-up unneeded cuda memory torch.cuda.empty_cache() print("P2") # Generate image content_tensor = utils.itot(img).to(device) print("P3") generated_tensor = mynet(content_tensor) print("P4") generated_image = utils.ttoi(generated_tensor.detach()) if (PRESERVE_COLOR): generated_image = utils.transfer_color(content_image, generated_image) img2 = cv2.imdecode(cv2.imencode(".png", generated_image)[1], cv2.IMREAD_UNCHANGED) count += 2 # Show webcam #img3 = cv2.flip(img2, 1) d=1 img = cv2.resize(img , (int(width*d), int(height*d))) cv2.imshow('real', img) img2 = cv2.resize(img2 , (int(width*d), int(height*d))) cv2.imshow('Demo webcam', img2) key = cv2.waitKey(1) & 0xFF except: print('error occured') if key == ord('n'): modelPath = next(modelIter) mynet.load_state_dict(torch.load(modelPath)) mynet = mynet.to(device) if key == ord('y'): #save on pressing 'y' cv2.imwrite(f'images/capture/c{count}.png',img2) elif key == ord('q'): break # q to quit # Free-up memories mycam.release() cv2.destroyAllWindows() # print(next(modelPaths)) mainfunc() ```
hayataka2049

2019/08/03 06:25

コメントでコードだけ見てもなんともいえません。
kokawa2003

2019/08/03 06:30

ちょっとかんがえてもう一度別スレ立てます
hayataka2049

2019/08/03 06:35

こういうケースの場合、とりあえず回答する上で必要そうな情報は、落ちてしまうときのエラーメッセージ全文(それぞれのコードに対して)ですかね。結果が変わらない、というのが完全に同じエラーメッセージが出る、という意味であれば一つだけ貼ればいいのですが。
kokawa2003

2019/08/03 06:47

今回関数の頭で global modelIter global device global mynet を追記しました。 それで結果をみるため initを抜けたところで print( modelIter) print (device) print( mynet) でそれぞれ見てみると <itertools.cycle object at 0x000001EEC0EC0D80> cuda Traceback (most recent call last): File "webcam.py", line 106, in <module> mainfunc() File "webcam.py", line 35, in mainfunc print(mynet) UnboundLocalError: local variable 'mynet' referenced before assignment という感じで最初の2個はGLOBALになっているが最後のmynetはそうでないらしい その理由がわかりません
kokawa2003

2019/08/03 06:49

initが最後まで走っているのは確認しています
hayataka2049

2019/08/03 06:59

mainfuncの中でnet(mynetに変えてるのかな)に対して代入する行があるので、ローカル変数扱いになるのです。ここのサンプル2とかがわかりやすいでしょうか。 https://snowtree-injune.com/2018/07/29/post-734/ mainfuncの側にnet(mynet)のglobal宣言を入れれば動くかと。
kokawa2003

2019/08/03 07:00

mainにも global modelIter global device global mynet でうまく動作しました。ありがとう。
kokawa2003

2019/08/03 07:01

ほぼ同時でした。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問