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

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

ただいまの
回答率

90.32%

  • Python

    9230questions

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

PythonのTkinterで違うファイルから関数をインポートしたら、エラーが出て実行できなくなる

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 365

gymgym

score 69

import cv2
import random
import pyautogui
import pandas as pd
import os
from tkinter import ttk
from tkinter import *
from datetime import datetime
#from classfy02 import input_data

pyautogui.doubleClick(86,94)

zyan_slide = ['paa.png', 'guu.png', 'tyoki.png']
q_slide = ['kati.png', 'make.png', 'hikiwake.png']

data_time = []
zyan, q = [],[]

random.shuffle(zyan_slide)
random.shuffle(q_slide)

que_list, task_list = [], []

# 注視画像
img = cv2.imread('cross.png')
cv2.namedWindow('screen', cv2.WINDOW_NORMAL)
cv2.setWindowProperty('screen', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
cv2.imshow('screen', img)
cv2.waitKey(1000)

time = datetime.now()
data_time.append(time)

# 問題提示

img = cv2.imread(q_slide[0])
cv2.namedWindow('screen', cv2.WINDOW_NORMAL)
cv2.setWindowProperty('screen', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
cv2.imshow('screen', img)
cv2.waitKey(2000)
img = cv2.imread(zyan_slide[0])
cv2.namedWindow('screen', cv2.WINDOW_NORMAL)
cv2.setWindowProperty('screen', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
cv2.imshow('screen', img)
cv2.waitKey(2000)

# グー:0、チョキ:1、パー:2
if(zyan_slide[0]=='guu.png' and q_slide[0] == 'hikiwake.png' or zyan_slide[0]=='tyoki.png' and q_slide[0] == 'kati.png' or zyan_slide[0]=='paa.png' and q_slide[0] == 'make.png'):
    zyan.append(0)
elif(zyan_slide[0]=='tyoki.png' and q_slide[0] == 'hikiwake.png' or zyan_slide[0]=='paa.png' and q_slide[0] == 'kati.png' or zyan_slide[0]=='guu.png' and q_slide[0] == 'make.png'):
    zyan.append(1)
elif(zyan_slide[0]=='paa.png' and q_slide[0] == 'hikiwake.png' or zyan_slide[0]=='guu.png' and q_slide[0] == 'kati.png' or zyan_slide[0]=='tyoki.png' and q_slide[0] == 'make.png'):
    zyan.append(2)


以上のコードは、うまく実行できるのですが、
以下の関数を他ファイルから呼び出してくると、

from classfy02 import input_data
OpenCV Error: Assertion failed (size.width>0 && size.height>0) in imshow, file /Users/travis/build/skvark/opencv-python/opencv/modules/highgui/src/window.cpp, line 325
Traceback (most recent call last):
  File "test.py", line 28, in <module>
    cv2.imshow('screen', img)
cv2.error: /Users/travis/build/skvark/opencv-python/opencv/modules/highgui/src/window.cpp:325: error: (-215) size.width>0 && size.height>0 in function imshow

以上のエラーが出てしまいます。
原因はどこにあるのでしょうか。

よろしくお願い致します。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

カレントディレクトリが異なるためでしょう。
ご提示のエラーは、画像のオープンに失敗したときによく見るエラーです。

絶対パスで書けば解決するはずですが、移植性がなくなりますので...
サンプルとして、こんなコードを紹介してみます。

from pathlib import Path

parent_path = Path(__file__).parent
path = str(
    (parent_path / 'myimg.jpg').resolve()
)

print(type(path), path)

どう適用すればいいかは、ちょっと考えてみてください。

ついでに

test.pyという名前は標準ライブラリのtestと被るので、避けてください。
Pythonでtest.pyを作るな!

あと、モジュールレベルにコードをべた書きするのはやめた方がいいです。
pythonで小さなツールを作る時のtips

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/19 11:25

    回答ありがとうございます。
    お手数ですが質問させていただきます。
    カレントディレクトリが異なるという指摘を頂いきましたが、画像とコードはすべて同じディレクトリに入っています。それでは、まだ不十分であるということでしょうか。
    よろしくお願い致します。

    キャンセル

  • 2018/01/19 11:54

    LouiS0616 さんのアドバイスを参考に簡単なコードで実行してみました。

    from pathlib import Path
    import cv2
    from classfy02 import input_data

    def main():
    parent_path = Path(__file__).parent
    path = str(
    (parent_path / 'cross.png').resolve()
    )


    img = cv2.imread(path)
    cv2.namedWindow('screen', cv2.WINDOW_NORMAL)
    cv2.setWindowProperty('screen', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
    cv2.imshow('screen', img)
    cv2.waitKey(1000)

    if __name__ == '__main__':
    main()

    やはり、これでもfrom classfy02 import input_dataがあることで以下のエラーが出ています。

    OpenCV Error: Assertion failed (size.width>0 && size.height>0) in imshow, file /Users/travis/build/skvark/opencv-python/opencv/modules/highgui/src/window.cpp, line 325
    Traceback (most recent call last):
    File "path.py", line 19, in <module>
    main()
    File "path.py", line 15, in main
    cv2.imshow('screen', img)
    cv2.error: /Users/travis/build/skvark/opencv-python/opencv/modules/highgui/src/window.cpp:325: error: (-215) size.width>0 && size.height>0 in function imshow

    from classfy02 import input_dataがなければうまく実行できます。
    何度も申し訳ないのですがよろしくお願い致します。

    キャンセル

  • 2018/01/19 15:46

    > 画像とコードはすべて同じディレクトリに入っています。それでは、まだ不十分であるということでしょうか。

    Pythonインタプリタを起動した際のカレントディレクトリに依ります。

    キャンセル

  • 2018/01/19 15:48

    pathをprintして、利用通りになっているか確認した方がいいですよ。
    あと、エラーが発生しているのはもともとinput_data.py内じゃなかったんですか?

    キャンセル

  • 2018/01/19 15:56

    回答ありがとうございます。
    >Pythonインタプリタを起動した際のカレントディレクトリに依ります
    了解です!もう一度確認してみます。

    キャンセル

  • 2018/01/19 15:57

    > あと、エラーが発生しているのはもともとinput_data.py内じゃなかったんですか?
    input_data単体ではエラーは出ていません。
    呼び出しを行うと画像が表示できないというエラーが出てしまいます。

    キャンセル

  • 2018/01/19 16:13

    『呼び出した際のカレントディレクトリによって、input_data内でエラーが発生している』のかと。
    そういう意味で、『カレントディレクトリに依存しない』ようにする工夫はinput_data側に必要です。

    キャンセル

+2

classfy02.pyの内容が質問文に記載されていないため、憶測での回答になっていますが、
他のpyファイルで定義した関数や変数を呼び出したいと仮定して回答します。

前回も指摘しましたが、あまり上手く伝わっていないのですこし他のアプローチで回答します。
■前提知識
pythonはモジュールをimportした時にモジュール内のトップレベルソースを全部実行します。

aaa.py

# -*- coding: UTF-8 -*
print(__name__)
print('aaa.py caller')


def calculation(n):
    print('calculation')
    return 2**n


bbb.py

# -*- coding: UTF-8 -*
import aaa
print(__name__)
print('bbb.py caller')

print(aaa.calculation(2))

python bbb.py

#出力結果
aaa
aaa.py caller
__main__
bbb.py caller
calculation
4

importで呼び出されたかのかそうでないかはnameで判断できます。
よって、どちらで呼び出されたのかを意識してソースコードを記述する必要があります。

■モジュール分割するときのポイント
1,まず各ファイル(モジュール)で行う事を決めてください。
できるだけ単一の処理内容になっていることがふさわしいです。

2,画面の入力/表示(View)とデータ(Model)を分ける。
画面からの入力された内容に対して、if文で判断していますが
a,画面から入力した内容をデータをlistまたはdictに格納する。
b,引数で渡されたlist/dictに対して処理を行う。
この2つの関数に分けると処理の結合度が低くなります。

3,循環するimportは避ける。下記のようなimportです。
aaa.py

import bbb

bbb.py

import aaa

循環importを行いたい時はimportで行いたい処理を切り出し、新規にccc.pyを作成してimportしてくださいな。
aaa.py

import ccc


bbb.py

import ccc

5,ソースの構成は以下のような形にする。
質問文のコードだとこうなります。

# 1,組み込みライブラリのimport文
import os
import random
from datetime import datetime
from tkinter import ttk
from tkinter import *
# 2,pipでインストールした import文
import cv2
import pandas as pd
import pyautogui
#自作したライブラリのimport文
#from classfy02 import input_data

#1,2,3のこの順番でimportすることにより間違ったimportによる名前空間の汚染が防げる事が多いです。

# 他のモジュールからimport時に公開したい処理
# import時はmainメソッドは呼び出されないことに注意すること。
# よってmainメソッドの内容に依存する処理は記述してはダメです。
# 例)calculationを公開
def calculation(n):
    return 2**n
# Python ファイル名.pyを実行時に行いたい処理
def main():
    #以下に処理を記述
    pyautogui.doubleClick(86, 94)

    zyan_slide = ['paa.png', 'guu.png', 'tyoki.png']
    q_slide = ['kati.png', 'make.png', 'hikiwake.png']

    data_time = []
    zyan, q = [], []

    random.shuffle(zyan_slide)
    random.shuffle(q_slide)

    que_list, task_list = [], []

    # 注視画像
    img = cv2.imread('cross.png')
    cv2.namedWindow('screen', cv2.WINDOW_NORMAL)
    cv2.setWindowProperty('screen', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
    cv2.imshow('screen', img)
    cv2.waitKey(1000)

    time = datetime.now()
    data_time.append(time)

    # 問題提示
    img = cv2.imread(q_slide[0])
    cv2.namedWindow('screen', cv2.WINDOW_NORMAL)
    cv2.setWindowProperty('screen', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
    cv2.imshow('screen', img)
    cv2.waitKey(2000)
    img = cv2.imread(zyan_slide[0])
    cv2.namedWindow('screen', cv2.WINDOW_NORMAL)
    cv2.setWindowProperty('screen', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
    cv2.imshow('screen', img)
    cv2.waitKey(2000)

    # グー:0、チョキ:1、パー:2
    if (zyan_slide[0] == 'guu.png' and q_slide[0] == 'hikiwake.png' or zyan_slide[0] == 'tyoki.png' and q_slide[
        0] == 'kati.png' or zyan_slide[0] == 'paa.png' and q_slide[0] == 'make.png'):
        zyan.append(0)
    elif (zyan_slide[0] == 'tyoki.png' and q_slide[0] == 'hikiwake.png' or zyan_slide[0] == 'paa.png' and q_slide[
        0] == 'kati.png' or zyan_slide[0] == 'guu.png' and q_slide[0] == 'make.png'):
        zyan.append(1)
    elif (zyan_slide[0] == 'paa.png' and q_slide[0] == 'hikiwake.png' or zyan_slide[0] == 'guu.png' and q_slide[
        0] == 'kati.png' or zyan_slide[0] == 'tyoki.png' and q_slide[0] == 'make.png'):
        zyan.append(2)

if __name__ == '__main__':
    main()

■余談
同じ処理を2回書いたらこれは関数化できるのか?どうかを一考してみてくださいな。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/19 11:26

    丁寧にアドバイスいただきありがとうござます。
    参考にコードを組んでいきたいと思います!

    キャンセル

同じタグがついた質問を見る

  • Python

    9230questions

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