Python-OpenCV-在tkinter的canvas控件中显示OpenCV图像

20 篇文章 4 订阅
tkinter是python中界面设计常用的库,但是对图片显示的仅支持GIF 和 PGM/PPM 文件格式。和OpenCV没有直接的转换函数,这里另外引进了python常用的图像库PIL来间接的进行转换。
实现了在在tkinter的canvas上显示OpenCV图像。效果如图:

在这里插入图片描述
实现代码如下:

# -*- coding: utf-8 -*-
"""
Created on Fri Mar 13 14:37:33 2020

@author: xin
"""
from tkinter import *
import cv2 as cv
from a import Image,ImageTk

def Showimage(imgCV_in,canva,layout="null"):
    """
    Showimage()是一个用于在tkinter的canvas控件中显示OpenCV图像的函数。
    使用前需要先导入库
    import cv2 as cv
    from PIL import Image,ImageTktkinter
    并注意由于响应函数的需要,本函数定义了一个全局变量 imgTK,请不要在其他地方使用这个变量名!
    参数:
    imgCV_in:待显示的OpenCV图像变量
    canva:用于显示的tkinter canvas画布变量
    layout:显示的格式。可选项为:
        "fill":图像自动适应画布大小,并完全填充,可能会造成画面拉伸
        "fit":根据画布大小,在不拉伸图像的情况下最大程度显示图像,可能会造成边缘空白
        给定其他参数或者不给参数将按原图像大小显示,可能会显示不全或者留空
    """
    global imgTK
    canvawidth = int(canva.winfo_reqwidth())
    canvaheight = int(canva.winfo_reqheight())
    sp = imgCV_in.shape
    cvheight = sp[0]#height(rows) of image
    cvwidth = sp[1]#width(colums) of image
    if (layout == "fill"):
        imgCV = cv.resize(imgCV_in,(canvawidth,canvaheight), interpolation=cv.INTER_AREA)
    elif(layout == "fit"):
        if (float(cvwidth/cvheight) > float(canvawidth/canvaheight)):
            imgCV = cv.resize(imgCV_in,(canvawidth,int(canvawidth*cvheight/cvwidth)), interpolation=cv.INTER_AREA)
        else:
            imgCV = cv.resize(imgCV_in,(int(canvaheight*cvwidth/cvheight),canvaheight), interpolation=cv.INTER_AREA)
    else:
        imgCV = imgCV_in
    imgCV2 = cv.cvtColor(imgCV, cv.COLOR_BGR2RGBA)#转换颜色从BGR到RGBA
    current_image = Image.fromarray(imgCV2)#将图像转换成Image对象
    imgTK = ImageTk.PhotoImage(image=current_image)#将image对象转换为imageTK对象
    canva.create_image(0,0,anchor = NW, image = imgTK)

root = Tk()
root.title("OpenCV Win")
canva = Canvas(root, width=800, height=600,bg="gray")
canva.pack()
img = cv.imread("test.jpg")
Showimage(img,canva,"fill")
root.mainloop()

版权声明:本文为CSDN博主「※陈默※」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_38179212/article/details/104968754

由于需求不同,进行自我改进:

@staticmethod
def showimage(imgCV_in, canva, layout="null"):
    """
    from PIL import Image,ImageTktkinter
    并注意由于响应函数的需要,本函数定义了一个全局变量 imgTK,请不要在其他地方使用这个变量名!
    参数:
    imgCV_in:待显示的OpenCV图像变量
    canva:用于显示的tkinter canvas画布变量
    layout:显示的格式。可选项为:
        "fill":图像自动适应画布大小,并完全填充,可能会造成画面拉伸
        "fit":根据画布大小,在不拉伸图像的情况下最大程度显示图像,可能会造成边缘空白
        给定其他参数或者不给参数将按原图像大小显示,可能会显示不全或者留空
    """
    global imgTK
    try:
        canvawidth = int(canva.winfo_reqwidth())
        canvaheight = int(canva.winfo_reqheight())
        sp = imgCV_in.shape
        cvheight = sp[0]  # height(rows) of image
        cvwidth = sp[1]  # width(colums) of image
        if layout == "fill":
            imgCV = cv2.resize(imgCV_in, (canvawidth, canvaheight), interpolation=cv2.INTER_AREA)
        elif layout == "fit":
            if (float(cvwidth / cvheight) > float(canvawidth / canvaheight)):
                imgCV = cv2.resize(imgCV_in, (canvawidth, int(canvawidth * cvheight / cvwidth)),
                                   interpolation=cv2.INTER_AREA)

            else:
                imgCV = cv2.resize(imgCV_in, (int(canvaheight * cvwidth / cvheight), canvaheight),
                                   interpolation=cv2.INTER_AREA)
        else:
            if cvwidth>800 or cvheight>480:
                imgCV = cv2.resize(imgCV_in, (canvawidth, canvaheight), interpolation=cv2.INTER_AREA)
            else:
                imgCV = imgCV_in
        imgCV2 = cv2.cvtColor(imgCV, cv2.COLOR_BGR2RGBA)  # 转换颜色从BGR到RGBA
        current_image = Image.fromarray(np.uint8(imgCV2))  # 将图像转换成Image对象
        imgTK = ImageTk.PhotoImage(image=current_image)  # 将image对象转换为imageTK对象
        canva.create_image(0, 0, anchor=NW, image=imgTK)
    except:
        showwarning("警告","未导入图片!!!")
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用TkinterOpenCV结合可以实现一个简单的图像处理系统,在界面上实现对图像的预览和一些基本的处理功能。下面是一个使用TkinterOpenCV实现图像处理系统的示例代码: ```python import tkinter as tk from PIL import Image, ImageTk import cv2 class App: def __init__(self, root): self.root = root self.root.title("图像处理系统") # 创建图像显示区域 self.canvas = tk.Canvas(root, width=640, height=480) self.canvas.pack() # 创建按钮 self.btn_open = tk.Button(root, text="打开图像", command=self.open_image) self.btn_open.pack(side=tk.LEFT, padx=10, pady=10) self.btn_gray = tk.Button(root, text="灰度化", command=self.gray_image) self.btn_gray.pack(side=tk.LEFT, padx=10, pady=10) self.btn_edge = tk.Button(root, text="边缘检测", command=self.edge_image) self.btn_edge.pack(side=tk.LEFT, padx=10, pady=10) self.btn_reset = tk.Button(root, text="重置", command=self.reset_image) self.btn_reset.pack(side=tk.LEFT, padx=10, pady=10) # 初始化变量 self.img = None self.tk_img = None def open_image(self): # 选择图像文件并读取 filename = tk.filedialog.askopenfilename() if filename: self.img = cv2.imread(filename) self.show_image() def gray_image(self): # 灰度化处理 if self.img is not None: gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY) self.img = gray self.show_image() def edge_image(self): # 边缘检测处理 if self.img is not None: gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (5, 5), 0) edges = cv2.Canny(blur, 50, 150) self.img = edges self.show_image() def reset_image(self): # 重置图像 self.show_image() def show_image(self): # 将OpenCV图像转换为Tkinter图像 if self.img is not None: img = cv2.cvtColor(self.img, cv2.COLOR_BGR2RGB) img = Image.fromarray(img) self.tk_img = ImageTk.PhotoImage(img) self.canvas.create_image(0, 0, anchor="nw", image=self.tk_img) if __name__ == '__main__': root = tk.Tk() app = App(root) root.mainloop() ``` 这个示例程序,我们创建了一个tkinter应用程序,包含了一个图像显示区域和一些按钮,用于打开图像、灰度化、边缘检测和重置图像。当用户点击打开图像按钮时,程序会打开文件对话框,让用户选择一个图像文件,并将其读取到OpenCV。当用户点击灰度化或边缘检测按钮时,程序会对当前图像进行相应处理,并在图像显示区域显示处理结果。当用户点击重置按钮时,程序会恢复原始图像
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值