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

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

ただいまの
回答率

89.07%

Python: opencvで取得してimageをtkのcanvasに表示させたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 794

IroIroShiritai

score 19

opnecvで取得したimageをtkのcanvasに表示させたいと考えております。googleで色々検索しましたが、tkに貼るには変換が必要であることまでは分かり、変換して貼ってみましたが何も表示されていないです。色々間違えているとは思いますが、ご確認頂ければと思います。
動作は、1.File->Openを押す。2.filedialogで画像ファイルを選ぶ。3.選んだ画像がcanvas上に表示される。と言う流れを期待しております。

import numpy as np
import tkinter as tk
import tkinter.filedialog as fd
from PIL import Image,ImageTk
import cv2

class mainApp(tk.Frame):
    def __init__(self,master):
        super().__init__(master,height=500,width=800)
        self.pack()
        self.create_widgets()

    def create_widgets(self):
        #メニュー
        menubar = tk.Menu(self)
        menu1 = tk.Menu(menubar,tearoff=False)
        menu1.add_command(label="open", command=self.file_open)
        menubar.add_cascade(label='File',menu=menu1)
        self.master["menu"] = menubar 

        # 画像表示エリア
        image_frame = tk.Frame(self,width=400,height=400)
        image_frame.propagate(False)
        image_frame.place(x=300,y=50)
        image_yscrollbar = tk.Scrollbar(image_frame)
        image_yscrollbar.pack(side=tk.RIGHT,fill=tk.Y)
        image_xscrollbar = tk.Scrollbar(image_frame,orient=tk.HORIZONTAL)
        image_xscrollbar.pack(side=tk.BOTTOM,fill=tk.X)
        self.image_canvas = tk.Canvas(image_frame,\
          xscrollcommand=image_xscrollbar.set,yscrollcommand=image_yscrollbar.set)
        self.image_canvas.pack(side=tk.TOP, fill=tk.BOTH)
        image_xscrollbar["command"] =self.image_canvas.xview
        image_yscrollbar["command"] =self.image_canvas.yview

    def file_open(self):
      #fileを選択
      image_file_path = str(get_file_path("画像ファイルを選択してください"))
      #imageを読み込む
      img_cv = imread(image_file_path)
      img_tk = img_fromCv_toTk(img_cv)
      self.image_canvas.create_image(0,0,image=img_tk,anchor='nw')

# Fileのdialogを呼び出し、Pathを返す関数
def get_file_path(stitle):
    in_path = fd.askopenfilename(
        title = stitle
    )
    return in_path
# filePathで指定されたイメージをよみこみimgを返す関数
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
# OpenCVで読み込まれたイメージをtkフォーマットに変換する関数
def img_fromCv_toTk(image_cv):
  image_rgb = cv2.cvtColor(image_cv, cv2.COLOR_BGR2RGB)
  image_pil = Image.fromarray(image_rgb)
  image_tk = ImageTk.PhotoImage(image_pil)
  return image_tk

root = tk.Tk()
app = mainApp(root)
app.mainloop()
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

以下を修正ください。

  • 読み込んだ画像をメンバ変数として保持
  • キャンバスサイズとスクロール領域を設定
    def __init__(self,master):
        # 略。以下を追加
        self.img_tk = None

    def file_open(self):
      # 略。以下を追加
      w,h = img_tk.width(), img_tk.height()
      self.image_canvas.config(width=w, height=h,scrollregion=(0,0,w,h))
      self.img_tk = img_tk

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/05/01 13:26

    早速ご回答いただきありがとうございます。ご指摘のように変更すると思い通りの動きとなりました。また、スクロールの領域を画像の大きさから決める方法も勉強になりました。

    キャンセル

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

  • ただいまの回答率 89.07%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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