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

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

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

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

1875閲覧

画像ファイルの読み込みエラー

machaco

総合スコア13

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2019/02/08 07:56

編集2019/02/08 12:42

前提・実現したいこと

Python初心者です。
画像の間違い認識(2つの画像を重ね合わせて判別するもの)をしようとしています。

具体的な内容は

1.ファイル選択ダイアログを表示
2.1つ目の画像をファイル選択
3.ファイル選択ダイアログを表示
4.2つ目の画像をファイル選択
5.1つ目の画像と2つ目の画像を比較して差異を赤色で表示

といった流れになります。

Python初心者でわからないことだらけですが、ご協力頂けたらと思います。

ここに質問の内容を詳しく書いてください。
●ファイル選択ダイアログであるjpgファイルを選択するとNone Typeとなり読み込めません。
すべてがエラーになるのではなくなるものと、ならないものがあります。
原因はわかりませんが読み込みができたものは、サイズが332x254です。(サンプルで適当に作ったもの)
読み込みができなかったものはサイズが13248x9376です。

大変申し訳ありませんが、読み込みできなかったファイルは都合上お見せできません。

またjpgファイル以外(tiff、bmpは試しました)でも同様のエラーとなります。
temp_img = cv2.imread(temp_fle, 1)  でエラーとなります。

発生している問題・エラーメッセージ

'NoneType' object has no attribute 'shape'

該当のソースコード

Python

# -*- coding: utf-8 -*- """ import cv2 import numpy import tkinter, tkinter.filedialog, tkinter.messagebox, os from tkinter import messagebox #------------------------------------------------------------------------- #ファイル選択ダイアログ表示 root = tkinter.Tk() root.withdraw() fTyp = [("","*")] iDir = os.path.abspath(os.path.dirname(__file__)) temp_fle = tkinter.filedialog.askopenfilename(filetypes = fTyp,initialdir = iDir) filename = os.path.basename(temp_fle) name, ext = os.path.splitext(filename) #画像ファイル読込み temp_img = cv2.imread(temp_fle, 1) t_height = temp_img.shape[0] t_width = temp_img.shape[1]

試したこと

いろいろ試してみたのですがうまくいきませんでした。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

can110

2019/02/08 08:39

インデントがなくなっていますのでソースコードはコードブロックで囲んでください。 また、読み込みができなかった画像も差支えなければアップロードください。
machaco

2019/02/08 09:40

初歩的なご指摘、ご指導ありがとうございます。 読み込みができなかった画像は、申し訳ありませんが都合上お見せすることができません。
Q71

2019/02/09 04:37

では、ほかの見せられる画像を読ませてみてください。それでも同じエラーでしょうか。 エラー内容としては、OpenCVが理解できない画像のようですが…
machaco

2019/02/11 13:25

同じエラーになります。 他の画像はペイントで適当に作成したjpgとパワーポイントで図形を適当に貼り、jpg保存したものです。
guest

回答2

0

自分自身余り詳しい方ではないですし、別枠で質問されたほうが良い案件ではあります…が、とりあえずの回答を記載しておきます。

画面上にすべてを表示させたいのでしたら、以下のコードにて実現できます。

#ウインドウサイズに合うような拡大率(scale)を設定 scale=min(640/t_width,480/t_height) #リサイズ resized_img = cv2.resize(temp_img,None,fx=scale,fy=scale) cv2.imshow('image',resized_img)

また、自分の能力不足からクリックによる画像の拡大・縮小ができなかったので、
代わりにスクロールバーによる画面表示を実装しました。

###画像の表示 from PIL import Image, ImageTk #表示画面の作成 root2 = tkinter.Tk() frame = Frame(root2) canvas = Canvas(frame, width=400, height=400, scrollregion=(0, 0, t_height*2,t_width*2)) #スクロールバーの設定 xscroll = Scrollbar(frame, orient=HORIZONTAL, command=canvas.xview) xscroll.grid(row=1, column=0, sticky=E+W) yscroll = Scrollbar(frame, orient=VERTICAL, command=canvas.yview) yscroll.grid(row=0, column=1, sticky=N+S) canvas.config(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set) canvas.grid(row=0, column=0, sticky=N+E+W+S) canvas.bind("<ButtonPress-1>", lambda e: canvas.scan_mark(e.x, e.y)) canvas.bind("<B1-Motion>", lambda e: canvas.scan_dragto(e.x, e.y, gain=1)) #画面に画像を生成 tkimg = ImageTk.PhotoImage(file=temp_fle,master=canvas) canvas.create_image(t_height, t_width, image=tkimg) frame.grid_rowconfigure(0, weight=1) frame.grid_columnconfigure(0, weight=1) frame.grid(sticky=N+E+W+S) root2.mainloop()

スクロールバーを動かす(または画面をドラッグする)ことで、画像の比率をそのままにした状態で色んな部分を見られるかと思います。

以下、最終的なコード内容になります。

import sys import cv2 import numpy as np import tkinter, tkinter.filedialog, tkinter.messagebox, os from tkinter import messagebox def imread(filename, flags=cv2.IMREAD_COLOR, dtype=np.uint8): try: n = np.fromfile(filename, dtype) img = cv2.imdecode(n, flags) return img except Exception as e: print(e) return None #------------------------------------------------------------------------- #ファイル選択ダイアログ表示 root = tkinter.Tk() root.withdraw() fTyp = [("","*")] iDir = os.path.abspath(os.path.dirname(sys.argv[0])) temp_fle = tkinter.filedialog.askopenfilename(filetypes = fTyp) filename = os.path.basename(temp_fle) name, ext = os.path.splitext(filename) #画像ファイル読込み temp_img=imread(temp_fle, 1) t_height = temp_img.shape[0] t_width = temp_img.shape[1] ###画像のリサイズ(画面上にすべてを表示させる) #scale=min(640/t_width,480/t_height) #resized_img = cv2.resize(temp_img,None,fx=scale,fy=scale) #cv2.imshow('image',resized_img) #※cv2.imshow('image',resized_img[100:400,70:900])で部分表示も可能 #cv2.waitKey(0) #cv2.destroyAllWindows() ###画像の表示 from PIL import Image, ImageTk #表示画面の作成 root2 = tkinter.Tk() frame = Frame(root2) canvas = Canvas(frame, width=400, height=400, scrollregion=(0, 0, t_height*2,t_width*2)) #スクロールバーの設定 xscroll = Scrollbar(frame, orient=HORIZONTAL, command=canvas.xview) xscroll.grid(row=1, column=0, sticky=E+W) yscroll = Scrollbar(frame, orient=VERTICAL, command=canvas.yview) yscroll.grid(row=0, column=1, sticky=N+S) canvas.config(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set) canvas.grid(row=0, column=0, sticky=N+E+W+S) canvas.bind("<ButtonPress-1>", lambda e: canvas.scan_mark(e.x, e.y)) canvas.bind("<B1-Motion>", lambda e: canvas.scan_dragto(e.x, e.y, gain=1)) tkimg = ImageTk.PhotoImage(file=temp_fle,master=canvas) canvas.create_image(t_height, t_width, image=tkimg) frame.grid_rowconfigure(0, weight=1) frame.grid_columnconfigure(0, weight=1) frame.grid(sticky=N+E+W+S) root2.mainloop()

ウインドウを消してもプログラムが実行し続けるバグがあります(手動でinteruptする必要がある)。ご了承ください。

とりあえずの回答となります。これ以上の追求がありましたら、別件としてまた質問してください。

ご参考になれば幸いです。

投稿2019/04/19 10:24

amahara_waya

総合スコア1029

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

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

machaco

2019/04/19 16:52

御回答ありがとうございます。 会社のパソコンでの作業案件なので来週に確認したいと思います。 以前頂いた回答で実現したいことが出来たのでベストアンサーにさせていただきます。本当にありがとうございます。
guest

0

ベストアンサー

読み込む画像ファイルの名前に日本語が含まれていると、imreadが失敗し画像を読み込めません(Noneを返す)。

そのため、以下のようなコードを使うとうまくいきます。

import numpy as np import cv2 def imread(filename, flags=cv2.IMREAD_COLOR, dtype=np.uint8): try: n = np.fromfile(filename, dtype) img = cv2.imdecode(n, flags) return img except Exception as e: print(e) return None

結論、以下のように書き換えればうまくいくのではないかと思います。

import sys import os import cv2 import numpy as np import tkinter, tkinter.filedialog, tkinter.messagebox, os from tkinter import messagebox def imread(filename, flags=cv2.IMREAD_COLOR, dtype=np.uint8): try: n = np.fromfile(filename, dtype) img = cv2.imdecode(n, flags) return img except Exception as e: print(e) return None #------------------------------------------------------------------------- #ファイル選択ダイアログ表示 root = tkinter.Tk() root.withdraw() fTyp = [("","*")] iDir = os.path.abspath(os.path.dirname(sys.argv[0])) #sys.argv[0]は__file__でも可、自分の環境では通じなかったのでsys.argv[0]を使ってます temp_fle = tkinter.filedialog.askopenfilename(filetypes = fTyp) print(temp_fle) filename = os.path.basename(temp_fle) name, ext = os.path.splitext(filename) #画像ファイル読込み temp_img=imread(temp_fle, 1) t_height = temp_img.shape[0] t_width = temp_img.shape[1] print('ok')

参考記事:Python OpenCV の cv2.imread 及び cv2.imwrite で日本語を含むファイルパスを取り扱う際の問題への対処について

ご参考になれば幸いです。

投稿2019/04/17 15:45

amahara_waya

総合スコア1029

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

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

machaco

2019/04/19 04:47

amahara_wayaさん ご回答ありがとうございます。 無事解決できました。 しかし新たな問題が。。。 ご指導いただいた内容を参考に画像表示をさせましたが、サイズが大きいからか一部しか表示されません。 画像サイズは t_height:9376、t_width:13248です。 理想は通常のjpgを開くような形で画面上にすべてを表示し、拡大・縮小ができるようなイメージです。 当初の質問内容からそれてしまっていますが、お分かりになるようでしたら御教授頂けたらと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問