tkinter 基本控件與使用
我們將學習如何使用Tkinter包編寫一些圖形用戶界面程序。Tkinter是Python的一個標準包,因此我們并不需要安裝它。我們將從創(chuàng)建一個窗口開始,然后我們在其之上加入一些小組件,比如按鈕,復選框等,并使用它們的一些屬性。話不多說,讓我們開始吧!
from tkinter import *
tkinter基本控件
Button按鈕控件
普通的按鈕是非常簡單易用的。你所需要做的就是指定 Button 的內(nèi)容(文本、位圖或者圖片),并且關(guān)聯(lián)當按鈕被按下時應(yīng)該調(diào)用的函數(shù)或方法:
def callback():
print("你點擊了按鈕")
window=Tk()#創(chuàng)建一個窗口
buttion1=Button(window, text='press', command=callback)#如果command還沒有實現(xiàn)好功能,可以先填入'disabled'
buttion1.pack()#打包組件
window.mainloop()#維持窗口直至手動關(guān)閉
你得到了一個小家伙,但后面我們會遇到棘手的大家伙的!
實現(xiàn)了簡單的按鈕之后,你可能會不滿足于此。的確,每個人都希望他的window可以大小適中,按鈕也符合規(guī)律的排布。下面的代碼實現(xiàn)了你渴望的功能——
def callback():
print("點贊,關(guān)注,投幣,評論,轉(zhuǎn)發(fā)")
win = Tk()
win.title('一個大小合適的窗口')
win.geometry('800x600') # size
win['bg'] = 'pink' # background color
win.attributes('-alpha', 0.9) # 虛化
button = Button(win,text='這是一個按鈕',
padx=100,pady=100,command=callback)
#,height=2,width=50,command=callback)
button.grid(row=1, column=11)
win.mainloop()
canvas
canvas畫布為tkinter的圖像繪制提供了基礎(chǔ)。canvas是一個高度靈活的組件,可以用來繪制圖形和圖表,創(chuàng)建圖形編輯器,實現(xiàn)各種自定義小部件。
我們話不多說,演示如下代碼查看結(jié)果:
win=Tk()
win.geometry('800x600')
w=Canvas(win,width=100,height=300)
w.pack()
w.create_line(0, 50, 200, 50, fill = "yellow")
#畫一條紅色的豎線(虛線)
w.create_line(100, 0, 100, 100, fill = "red", dash = (4, 4))
#中間畫一個藍色的矩形
w.create_rectangle(50, 25, 150, 75, fill = "blue")
win.mainloop()
Label
相信聰明的小伙伴應(yīng)該知道下面的代碼怎么用啦
Label(標簽)組件用于在屏幕上顯示文本或圖像。Label 組件僅能顯示單一字體的文本,但文本可以跨越多行。另外,還可以為其中的個別字符加上下劃線(例如用于表示鍵盤快捷鍵)。
一個基礎(chǔ)示例
w=Label(win,text='這只是這個label的文本').pack()
一個換行實例
longtext = """
Label 可以顯示多行文本,你可以直接使用換行符
或使用 wraplength 選項來實現(xiàn)。當文本換行的時
候,你可以使用 anchor 和 justify 選項來使得
文本如你所希望的顯示出來。
"""
w = Label(master, text=longtext, anchor="w", justify="left")
一個展示圖片實例
下面這個程序需要你輸入圖片地址(不可以是jpg)
win=Tk()
#from PIL import ImageTk
#img=Image.open('pics/1.jpg')
#photo=ImageTk.PhotoImage(img)
#a=Label(win,image=photo).pack()
photo = PhotoImage(file="python.gif")
w = Label(win, image=photo)
w.pack()
win.mainloop()
看了上面的代碼,聰明的同學已經(jīng)知道怎么使得輸入變成jpg了
emm可能你比較懶,ok我們這里還有一份可以運行的不用修改的最最最關(guān)鍵的是對jpg文件有效的
聰明的小伙伴已經(jīng)在修改窗口大小以驗證下面某行代碼的必要性啦
win=Tk()
img=Image.open('pics/1.jpg')
size=img.size
win.geometry('{}x{}'.format(size[0]+100,size[1]+100))#沒錯就是我,我就是這行
photo=ImageTk.PhotoImage(img)
a=Label(win,image=photo).pack()
win.mainloop()
好啦,你已經(jīng)學了這么多知識了,是時候再再再補充一點知識啦——
補充知識
這一部分我會慢慢完善的
布局管理器grid
grid 管理器可以說是 Tkinter 這三個布局管理器中最靈活多變的。如果你只希望學習使用一個布局管理器,那么 grid 絕對是首選。當你在設(shè)計對話框的時候,使用 gird 尤其便捷。如果你此前一直在用 pack 構(gòu)造窗口布局,那么學習完 grid 你會悔恨當初為啥不早學它。使用一個 grid 就可以簡單的實現(xiàn)你用很多個框架和 pack 搭建起來的效果。
細心的讀者可能已經(jīng)發(fā)現(xiàn)了,在button控件中,我們使用了兩種不同的布局方式:pack, grid
使用 grid 排列組件,只需告訴它你想要將組件放置的位置(行/列,row 選項指定行,cloumn 選項指定列)。此外,你并不用提前指出網(wǎng)格(grid 分布給組件的位置稱為網(wǎng)格)的尺寸,因為管理器會自動計算。
root = Tk()
# column 默認值是 0
tk.Label(root, text="用戶名").grid(row=0)
tk.Label(root, text="密碼").grid(row=1)
#tk.Label(root, text="用戶名").grid(row=0, sticky="w") #細心的讀者可以用下面的代碼塊代替上面兩行
#tk.Label(root, text="密碼").grid(row=1, sticky="w")
tk.Entry(root).grid(row=0, column=1)
tk.Entry(root, show="*").grid(row=1, column=1)
#photo = tk.PhotoImage(file="logo.gif")
#tk.Label(root, image=photo).grid(row=0, column=2, rowspan=2, padx=5, pady=5) #rowspan=2 跨兩行
tk.Button(text="提交", width=10).grid(row=2, columnspan=3, pady=5) #columnspan=3 跨三列
root.mainloop()
使用tkinter+opencv 制作交互式程序
小試牛刀
ok,現(xiàn)在你真的學了很多知識了,讓我們開始第一部:
制作一個界面,使得用戶可以打開指定圖片并展示
阿這,你們肯定想,這么簡單的東西還用我教么!
好的,那我們直接下一個部分——
不過~
寫代碼切忌眼高手低??!
win=Tk()
win.geometry('100x80')
global message
message=0
def getpathandshow():
global message
global a
message=input('please input a pic path')
print(message)
if len(message)>0:
# assert os.path.exists(message), '路徑不存在'
img=Image.open(message)
size=img.size
win.geometry('{}x{}'.format(size[0]+100,size[1]+100))
photo=ImageTk.PhotoImage(img)
if a==None:
a=Label(win,image=photo)
a.image=photo
a.pack()
else:
a.configure(image=photo)
a.image=photo
a=None
b=Button(win,text='點擊輸入圖片路徑',command=getpathandshow).pack()
win.mainloop()
為了更好的選擇圖片,我們使用了filedialog包
獲取path修改為:
path=filedialog.askopenfilename()
ok,相信你應(yīng)該明白該把這句話修改在何處,聰明的讀者。
下面我們更加仔細,更加美觀地實現(xiàn)了上面所述功能
from tkinter import *
import time
import os
from PIL import Image, ImageTk
import cv2 as cv
from tkinter import filedialog
def button2():
global lab1
path = entry1.get()
print(path)
if len(path) > 0:
img = Image.open(path)
size = img.size
if size[0] > 800 or size[1] > 600:
rate = max(size[0] / 800, size[1] / 600)
rsize = (int(size[0] / rate), int(size[1] / rate))
img = img.resize(rsize)
# win.geometry('{}x{}'.format(size[0] + 100, size[1] + 100))
photo = ImageTk.PhotoImage(img)
if lab1 == None:
lab1 = Label(win, image=photo)
lab1.image = photo
lab1.grid(row=3, columnspan=5)
else:
lab1.configure(image=photo)
lab1.image = photo
def button1():
global lab1
# message='pics/1.jpg'#input('please input a pic path')
path = filedialog.askopenfilename()
print(path)
if len(path) > 0:
img = Image.open(path)
size = img.size
if size[0] > 800 or size[1] > 600:
rate = max(size[0] / 800, size[1] / 600)
rsize = (int(size[0] / rate), int(size[1] / rate))
img = img.resize(rsize)
# win.geometry('{}x{}'.format(size[0] + 100, size[1] + 100))
photo = ImageTk.PhotoImage(img)
if lab1 == None:
lab1 = Label(win, image=photo)
lab1.image = photo
lab1.grid(row=3, columnspan=5)
else:
lab1.configure(image=photo)
lab1.image = photo
win = Tk()
win.geometry('800x650')
global lab1
lab1 = None
entry1 = Entry(win, width=20)
entry1.grid(row=0, column=1)
lab2 = Label(win, text='輸入圖片路徑', width=20).grid(row=0, column=0)
lab2 = Label(win, text='手動選擇路勁', width=20).grid(row=0, column=3)
b1 = Button(win, text='選擇路徑', command=button1, width=20).grid(row=0, column=4)
b2 = Button(win, text='確認路徑', command=button2, width=20).grid(row=0, column=2)
win.mainloop()
利用滑塊旋轉(zhuǎn)圖片,提供保存按鈕
ok,相信你已經(jīng)學到了很多,并且躍躍欲試——
現(xiàn)在!開始嘗試并實現(xiàn)一下功能:
#打開,保存,退出,轉(zhuǎn)灰度
#幾何變換:鏡像,平移,剪切,旋轉(zhuǎn),縮放
下面的這段代碼實現(xiàn)了打開指定路徑下的圖片,并實現(xiàn)旋轉(zhuǎn)操作
(其實是我寫好了怕以后出bug無處參考哈哈)文章來源:http://www.zghlxwxcb.cn/news/detail-498158.html
#測試旋轉(zhuǎn)框函數(shù)的可行性
# l1.configure(image=img1)
a=tk.Tk()
global path
img=Image.open(path)
img=ImageTk.PhotoImage(img)
#這次我們換一個思路,先加最關(guān)鍵的控件
#最終畫布
l1=tk.Label(a,image=img)
l1.grid(row=3,columnspan=2)
#角度
agl=tk.IntVar()
agl.set(0)
#定義setangle函數(shù),為滑塊提供反饋
def setangle(value):
agl.set(value)
#滑塊
scale24=tk.Scale(a,from_=0,to=360,orient=tk.HORIZONTAL,showvalue=0,tickinterval=45,
resolution=1,command=setangle)
scale24.grid(row=2,columnspan=2,stick=tk.EW)
#按鈕函數(shù)組件1:旋轉(zhuǎn)圖像函數(shù)
def rotimg():
#angle.path
img=cv.imread(path)
angle=agl.get()
(h,w)=img.shape[:2]
center=(w//2,h//2)
M=cv.getRotationMatrix2D(center,angle,1.0)
rotedimg=cv.warpAffine(img,M,(w,h))
rgb_img=cv.cvtColor(rotedimg,cv.COLOR_BGR2RGB)
img=Image.fromarray(rgb_img)
return img
#利用組件函數(shù),構(gòu)建按鈕函數(shù)
def button24():
img=rotimg()
#img.show()
img=ImageTk.PhotoImage(img)
l1.configure(image=img)
a.mainloop()
#按鈕控件
b1=tk.Button(a,width=20,command=button24,text='顯示旋轉(zhuǎn)圖')
b1.grid(row=1,column=1,stick=tk.EW)
#角度顯示盤
la=tk.Label(a,textvariable=str(agl),bg='pink')
la.grid(row=1,column=0,stick=tk.EW)
#好的,既然我們實現(xiàn)了困難的部分,下面開始實現(xiàn)簡單的部分,保存路徑輸入框entry
entry01=tk.Entry(a)
entry01.grid(row=0,column=0,stick=tk.EW)
#下面的部分是保存圖片的按鈕,會利用到之前的rotimg函數(shù),和之前一樣,先寫按鈕函數(shù)
def button02():
path=entry01.get()
if len(path) == 0:
print('保存失敗')
return 0
img=rotimg()
img.save(path)
#保存成功我們希望有個彈窗
winmessage=tk.Toplevel(a)
winmessage.geometry('300x200')
tk.Message(winmessage,text='恭喜你,或者說恭喜這個熬了很久的猿,你們保存成功了').grid(sticky=tk.NSEW)
#這里就是保存圖片按鈕了
b02=tk.Button(a,text='左側(cè)輸入,點此保存',command=button02)
b02.grid(row=0,column=1,stick=tk.EW)
a.mainloop()
一個實現(xiàn)好的作品
我懶了,懶得寫了,下面是我的一個完成品,界面簡潔,功能也實現(xiàn)了不少。文章來源地址http://www.zghlxwxcb.cn/news/detail-498158.html
import tkinter as tk
import os
from PIL import Image, ImageTk
import cv2 as cv
from tkinter import filedialog
import numpy as np
from functools import partial
from tools import *
# 下面的是為了直方圖均衡化
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import NavigationToolbar2Tk, FigureCanvasTkAgg
# 打開,保存,退出,轉(zhuǎn)灰度
# 幾何變換:鏡像,平移,剪切,旋轉(zhuǎn),縮放
# 空間濾波:平滑處理,銳化處理
# 直方圖,計算,顯示,均衡化
# 頻域變換:Fourier變換,離散余弦變換,反變換(顯示頻譜圖)
# 頻域濾波:低通濾波,高通濾波
# 以顏色直方圖為特征,搜索本地圖片,反饋相似圖片并排序
def buttonSaveImg(img, entry):
path = entry.get()
# try:
img.save(path)
win22 = tk.Toplevel()
win22.rowconfigure(0, weight=1)
win22.columnconfigure(0, weight=1)
win22.geometry('200x200')
tk.Message(win22, text='保存成功').grid()
# except:
# win22 = tk.Toplevel()
# win22.geometry('200x200')
# tk.Message(win22, text='圖片路徑無效').grid()
# win22.mainloop()
def gsnoise():
global path
if len(path) > 0:
img = getimg(path)[1]
size = img.shape
noise = np.array(np.random.randint(20, size=size[0:-1]) - 10, dtype=np.uint8)
noise = noise.reshape(size[0], size[1], 1)
img = img + noise
img = Image.fromarray(img)
wings = tk.Toplevel()
photo = ImageTk.PhotoImage(img)
tk.Label(wings, image=photo).grid()
wings.mainloop()
def button1():
global lab1, path
path = filedialog.askopenfilename()
if len(path) > 0:
img = getimg(path)[0]
photo = ImageTk.PhotoImage(img)
if lab1 == None:
lab1 = tk.Label(win, image=photo)
lab1.image = photo
# lab1.rowconfigure()
lab1.grid(row=3, columnspan=5,sticky=tk.NSEW)
else:
lab1.configure(image=photo)
lab1.image = photo
def button2():
global lab1, path
path = entry1.get()
print(path)
if len(path) > 0:
img = getimg(path)[0]
photo = ImageTk.PhotoImage(img)
if lab1 == None:
lab1 = tk.Label(win, image=photo)
lab1.image = photo
lab1.grid(row=3, columnspan=5,sticky=tk.NSEW)
else:
lab1.configure(image=photo)
lab1.image = photo
def button21(): # 參考faster rcnn RandomHorizontalFlip
global path
if len(path) == 0:
return 0
img = getimg(path)[1] # Image.fromarray
img = np.flip(img, axis=1)
img = Image.fromarray(img)
win21 = tk.Toplevel() # 此處不能寫Tk()因為根部窗口只能有一個
win21.rowconfigure((1), weight=1)
win21.columnconfigure((0, 1,2), weight=1)
tk.Label(win21, text='輸入圖片保存路徑', width=20).grid(row=0, column=0,sticky=tk.EW)
entry21 = tk.Entry(win21)
entry21.grid(row=0, column=1,sticky=tk.EW)
tk.Button(win21, width=20, text='保存', command=partial(buttonSaveImg, img, entry21)).grid(row=0, column=2,sticky=tk.EW)
photo21 = ImageTk.PhotoImage(img)
tk.Label(win21, image=photo21).grid(row=1, columnspan=3,sticky=tk.NSEW)
win21.mainloop()
def button22():
if len(path) > 0:
win22 = tk.Toplevel()
win22.rowconfigure(0, weight=1)
win22.columnconfigure(0, weight=1)
win22.geometry('200x200')
tk.Message(win22, text='想象一下,已經(jīng)平移了,只不過我們以它的中心為參照點').grid()
win22.mainloop()
def button23():
# 剪切這個功能因為需要獲取圖片的坐標,實現(xiàn)鼠標拖動剪切,實際上很不好做”
pass
# l1.update()
# w.update()
def button24(): # 旋轉(zhuǎn)——做出拖動條
global path
if len(path)==0:
return 0
# 測試旋轉(zhuǎn)框函數(shù)的可行性
# l1.configure(image=img1)
a = tk.Toplevel(win)
a.rowconfigure(3, weight=1)
a.columnconfigure((0, 1), weight=1)
img = Image.open(path)
img = ImageTk.PhotoImage(img)
# 這次我們換一個思路,先加最關(guān)鍵的控件
# 最終畫布
l1 = tk.Label(a, image=img)
l1.grid(row=3, columnspan=2,sticky=tk.NSEW)
# 角度
agl = tk.IntVar()
agl.set(0)
# 定義setangle函數(shù),為滑塊提供反饋
def setangle(value):
agl.set(value)
# 滑塊
scale24 = tk.Scale(a, from_=0, to=360, orient=tk.HORIZONTAL, showvalue=0, tickinterval=45,
resolution=1, command=setangle)
scale24.grid(row=2, columnspan=2, sticky=tk.EW)
# 按鈕函數(shù)組件1:旋轉(zhuǎn)圖像函數(shù)
def rotimg():
# angle.path
img = cv.imread(path)
angle = agl.get()
(h, w) = img.shape[:2]
center = (w // 2, h // 2)
M = cv.getRotationMatrix2D(center, angle, 1.0)
rotedimg = cv.warpAffine(img, M, (w, h))
rgb_img = cv.cvtColor(rotedimg, cv.COLOR_BGR2RGB)
img = Image.fromarray(rgb_img)
return img
# 利用組件函數(shù),構(gòu)建按鈕函數(shù)
def button24():
img = rotimg()
# img.show()
img = ImageTk.PhotoImage(img)
l1.configure(image=img)
a.mainloop()
# 按鈕控件
b1 = tk.Button(a, width=20, command=button24, text='顯示旋轉(zhuǎn)圖')
b1.grid(row=1, column=1, sticky=tk.EW)
# 角度顯示盤
la = tk.Label(a, textvariable=str(agl), bg='pink')
la.grid(row=1, column=0, sticky=tk.EW)
# 好的,既然我們實現(xiàn)了困難的部分,下面開始實現(xiàn)簡單的部分,保存路徑輸入框entry
entry01 = tk.Entry(a)
entry01.grid(row=0, column=0, sticky=tk.EW)
# 下面的部分是保存圖片的按鈕,會利用到之前的rotimg函數(shù),和之前一樣,先寫按鈕函數(shù)
def button02():
path = entry01.get()
if len(path) == 0:
print('保存失敗')
return 0
img = rotimg()
img.save(path)
# 保存成功我們希望有個彈窗
winmessage = tk.Toplevel(a)
winmessage.rowconfigure(0, weight=1)
winmessage.columnconfigure(0, weight=1)
winmessage.geometry('300x200')
tk.Message(winmessage, text='恭喜你,或者說恭喜這個熬了很久的猿,你們保存成功了').grid(sticky=tk.NSEW)
# 這里就是保存圖片按鈕了
b02 = tk.Button(a, text='左側(cè)輸入,點此保存', command=button02, bg='pink')
b02.grid(row=0, column=1, sticky=tk.EW)
a.mainloop()
def button25(): # 縮放,我們希望設(shè)置兩個方法——輸入縮放比或者做成可視化的那種拖動條
global path
if len(path)==0:
return 0
# 縮放功能
a = tk.Toplevel()
a.rowconfigure(3, weight=1)
a.columnconfigure((0, 1), weight=1)
img = Image.open(path)
img = ImageTk.PhotoImage(img)
# 顯而易見,當我們已經(jīng)可以實現(xiàn)旋轉(zhuǎn)功能時,縮放就不在話下了
# 第一步:定義圖片展示窗口(畢竟咱是按照邏輯順序)
# 最終畫布
l31 = tk.Label(a, image=img)
l31.grid(row=3, columnspan=2,sticky=tk.NSEW)
# 比例
rate = tk.DoubleVar()
rate.set(1.0)
# 定義setangle函數(shù),為滑塊提供反饋
def setangle(value):
rate.set(value)
# 滑塊
scale24 = tk.Scale(a, from_=1, to=5, orient=tk.HORIZONTAL, showvalue=1, tickinterval=1,
resolution=0.1, command=setangle)
scale24.grid(row=2, columnspan=2, sticky=tk.EW)
# 定義組件函數(shù),實現(xiàn)縮放功能
def shrink():
# 收縮比例,路徑
r = rate.get()
img = Image.open(path)
size = img.size
# print(size)
img2 = img.resize((int(size[0] / r), int(size[1] / r)))
return img2
def button22():
img = shrink()
# img.show()
img = ImageTk.PhotoImage(img)
l31.configure(image=img)
a.mainloop()
# 按鈕控件
b22 = tk.Button(a, width=20, command=button22, text='顯示縮放圖')
b22.grid(row=1, column=1, sticky=tk.EW)
# 角度顯示盤
l21 = tk.Label(a, textvariable=str(rate), bg='pink')
l21.grid(row=1, column=0, sticky=tk.EW)
# 好的,既然我們實現(xiàn)了困難的部分,下面開始實現(xiàn)簡單的部分,保存路徑輸入框entry
entry01 = tk.Entry(a)
entry01.grid(row=0, column=0, sticky=tk.EW)
# 下面的部分是保存圖片的按鈕,會利用到之前的rotimg函數(shù),和之前一樣,先寫按鈕函數(shù)
def button02():
path = entry01.get()
if len(path) == 0:
print('保存失敗')
return 0
img = shrink()
img.save(path)
# 保存成功我們希望有個彈窗
winmessage = tk.Toplevel(a)
winmessage.rowconfigure(0, weight=1)
winmessage.columnconfigure(0, weight=1)
winmessage.geometry('300x200')
tk.Message(winmessage, text='恭喜你,或者說恭喜這個熬了很久的猿,你們保存成功了').grid(sticky=tk.NSEW)
# 這里就是保存圖片按鈕了
b02 = tk.Button(a, text='左側(cè)輸入,點此保存', command=button02, bg='pink')
b02.grid(row=0, column=1, sticky=tk.EW)
a.mainloop()
# 至此,縮放功能實現(xiàn)完畢button25
def button31(): # 平滑(模糊)
# 平滑功能
global path
if len(path) is 0:
return 0
a = tk.Toplevel()
a.rowconfigure(3, weight=1)
a.columnconfigure((0, 1), weight=1)
img = Image.open(path)
img = ImageTk.PhotoImage(img)
# 顯而易見,當我們已經(jīng)可以實現(xiàn)旋轉(zhuǎn)功能時,縮放就不在話下了
# 第一步:定義圖片展示窗口(畢竟咱是按照邏輯順序)
kernels = [np.ones((i, i), np.float32) / (i * i) for i in range(1, 11)]
# 最終畫布
l31 = tk.Label(a, image=img)
l31.grid(row=3, columnspan=2,sticky=tk.NSEW)
# 卷積核的大小比例
rate = tk.IntVar()
rate.set(1)
# 定義setangle函數(shù),為滑塊提供反饋
def setkernel(value):
rate.set(value)
# 滑塊
scale31 = tk.Scale(a, from_=1, to=11, orient=tk.HORIZONTAL, showvalue=1, tickinterval=2,
command=setkernel)
scale31.grid(row=2, columnspan=2, sticky=tk.EW)
# 定義組件函數(shù),實現(xiàn)縮放功能
def averaging():
# 核大小,圖片
r = (rate.get() - 1) // 2
img = cv.imread(path)
kernel = kernels[r]
avgimg = cv.filter2D(img, -1, kernel)
rgb_img = cv.cvtColor(avgimg, cv.COLOR_BGR2RGB)
img = Image.fromarray(rgb_img)
return img
def button22():
img = averaging()
img = ImageTk.PhotoImage(img)
l31.configure(image=img)
a.mainloop()
# 按鈕控件
b22 = tk.Button(a, width=20, command=button22, text='顯示縮放圖')
b22.grid(row=1, column=1, sticky=tk.EW)
# 顯示盤
l21 = tk.Label(a, textvariable=str(rate), bg='pink')
l21.grid(row=1, column=0, sticky=tk.EW)
# 好的,既然我們實現(xiàn)了困難的部分,下面開始實現(xiàn)簡單的部分,保存路徑輸入框entry
entry01 = tk.Entry(a)
entry01.grid(row=0, column=0, sticky=tk.EW)
# 下面的部分是保存圖片的按鈕,會利用到之前的rotimg函數(shù),和之前一樣,先寫按鈕函數(shù)
def button02():
path = entry01.get()
if len(path) == 0:
print('保存失敗')
return 0
img = averaging()
img.save(path)
# 保存成功我們希望有個彈窗
winmessage = tk.Toplevel(a)
winmessage.rowconfigure(0, weight=1)
winmessage.columnconfigure(0, weight=1)
winmessage.geometry('300x200')
tk.Message(winmessage, text='恭喜你,或者說恭喜這個熬了很久的猿,你們保存成功了').grid(sticky=tk.NSEW)
# 這里就是保存圖片按鈕了
b02 = tk.Button(a, text='左側(cè)輸入,點此保存', command=button02)
b02.grid(row=0, column=1, sticky=tk.EW)
a.mainloop()
# 至此,平滑功能實現(xiàn)完畢
def button32(): # 銳化
# 銳化功能
global path
if len(path) is 0:
return 0
a = tk.Toplevel()
a.rowconfigure(3,weight=1)
a.columnconfigure((0, 1), weight=1)
# global path
img = Image.open(path)
img = ImageTk.PhotoImage(img)
# 顯而易見,當我們已經(jīng)可以實現(xiàn)旋轉(zhuǎn)功能時,縮放就不在話下了
# 第一步:定義高通濾波核
kernel0 = -np.ones((3, 3), np.float32)
kernel0[1, 1] += 9
kernel1 = -np.ones((5, 5), np.float32)
kernel1[1:4, 1:4] = -kernel0
kernel1[2, 2] = 8
kernel2 = -np.ones((5, 5), np.float32)
kernel2[2, 2] += 25
kernels = [kernel0, kernel1, kernel2]
# 最終畫布
l31 = tk.Label(a, image=img)
l31.grid(row=3, columnspan=2,sticky=tk.NSEW)
# 卷積核的大小比例
rate = tk.IntVar()
rate.set(1)
# 定義setangle函數(shù),為滑塊提供反饋
def setkernel(value):
rate.set(value)
# 滑塊
scale31 = tk.Scale(a, from_=1, to=3, orient=tk.HORIZONTAL, showvalue=1, tickinterval=1,
resolution=1, command=setkernel)
scale31.grid(row=2, columnspan=2, sticky=tk.EW)
# 定義組件函數(shù),實現(xiàn)縮放功能
def averaging():
# 核大小,圖片
r = rate.get() - 1
img = cv.imread(path)
kernel = kernels[r]
avgimg = cv.filter2D(img, -1, kernel)
rgb_img = cv.cvtColor(avgimg, cv.COLOR_BGR2RGB)
img = Image.fromarray(rgb_img)
return img
def button22():
img = averaging()
img = ImageTk.PhotoImage(img)
l31.configure(image=img)
a.mainloop()
# 按鈕控件
b22 = tk.Button(a, width=20, command=button22, text='顯示縮放圖')
b22.grid(row=1, column=1, sticky=tk.EW)
# 顯示盤
l21 = tk.Label(a, textvariable=str(rate), bg='pink')
l21.grid(row=1, column=0, sticky=tk.EW)
# 好的,既然我們實現(xiàn)了困難的部分,下面開始實現(xiàn)簡單的部分,保存路徑輸入框entry
entry01 = tk.Entry(a)
entry01.grid(row=0, column=0, sticky=tk.EW)
# 下面的部分是保存圖片的按鈕
def button02():
path = entry01.get()
if len(path) == 0:
print('保存失敗')
return 0
img = averaging()
img.save(path)
# 保存成功我們希望有個彈窗
winmessage = tk.Toplevel(a)
winmessage.rowconfigure(0, weight=1)
winmessage.columnconfigure(0, weight=1)
winmessage.geometry('300x200')
tk.Message(winmessage, text='恭喜你,或者說恭喜這個熬了很久的猿,你們保存成功了').grid(sticky=tk.NSEW)
# 這里就是保存圖片按鈕了
b02 = tk.Button(a, text='左側(cè)輸入,點此保存', command=button02)
b02.grid(row=0, column=1, sticky=tk.EW)
a.mainloop()
# 至此,銳化功能實現(xiàn)完畢
def button23(): # 直方圖均衡化
global path
if len(path) is 0:
return 0
# 利用cv內(nèi)置工具獲得直方圖,已經(jīng)均衡化后的圖像
img_ori=cv.imread(path)
for i in range(3):
im=img_ori[:,:,i]
equ=cv.equalizeHist(im)
try:
im_box.append(equ)
except:
im_box=[equ]
im_box=np.stack((im_box[2],im_box[1],im_box[0]),axis=2)
#獲得直方圖三尺度均衡化后的圖片
rgb_im=Image.fromarray(im_box)
#rgb_im.show()
img = cv.imread(path, 0)
hist = cv.calcHist([img], [0], None, [256], [0, 256])
equ = cv.equalizeHist(img)
histequ = cv.calcHist([equ], [0], None, [256], [0, 256])
# 第二步,把這些圖像放到一個figure上
f = Figure(figsize=(10, 8), dpi=100)
a11 = f.add_subplot(221) # 添加子圖:1行1列第1個
# a11.title='原圖像素值直方圖'
x = np.arange(256)
y = hist
a11.plot(x, y)
a12 = f.add_subplot(222)
# a12.title='原圖灰度圖'
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
a12.imshow(rgb_img)
a21 = f.add_subplot(223)
# a21.title('均衡化后的直方圖')
y = histequ
a21.plot(x, y)
a22 = f.add_subplot(224)
# a22.title('均衡化后的圖像')
rgb_equ = cv.cvtColor(equ, cv.COLOR_BGR2RGB)
a22.imshow(rgb_equ)
# 第三步,建立和tkinter的聯(lián)系,提供保存方法
#顯示均衡化的彩圖
def button10():
img=rgb_im
aa=tk.Toplevel()
img=ImageTk.PhotoImage(img)
aal=tk.Label(aa,image=img)
aal.grid()
aa.mainloop()
#保存均衡化彩圖
def button11():
path = entry00.get()
rgb_im.save(path)
winmessage = tk.Toplevel(a)
winmessage.geometry('300x200')
tk.Message(winmessage, text='恭喜你,或者說恭喜這個熬了很久的猿,你們保存成功了').grid(sticky=tk.NSEW)
a = tk.Toplevel()
a.rowconfigure((2),weight=1)
a.columnconfigure((0,1),weight=1)
img_real=ImageTk.PhotoImage(rgb_im)
b = tk.Frame(a)
canvas1 = FigureCanvasTkAgg(f, b)
canvas1.draw()
canvas1.get_tk_widget().grid()
b.grid(row=2, columnspan=2, sticky=tk.NSEW)
b10=tk.Button(a,text='展示均衡化彩圖',command=button10).grid(row=1,column=0,sticky=tk.EW)
b11=tk.Button(a,text='保存均衡化彩圖',command=button11).grid(row=1,column=1,sticky=tk.EW)
# 提供保存方法
def button01():
path = entry00.get()
cv.imwrite(path, equ)
winmessage = tk.Toplevel(a)
winmessage.rowconfigure(0, weight=1)
winmessage.columnconfigure(0, weight=1)
winmessage.geometry('300x200')
tk.Message(winmessage, text='恭喜你,或者說恭喜這個熬了很久的猿,你們保存成功了').grid(sticky=tk.NSEW)
entry00 = tk.Entry(a)
entry00.grid(row=0, column=0, sticky=tk.EW)
b01 = tk.Button(a, text='點此保存均衡化的圖片', command=button01)
b01.grid(row=0, column=1,sticky=tk.EW)
a.mainloop()
def button33():#低通濾波
'''低通濾波,基本組件:
文字框,保存圖片按鈕
滑塊數(shù)值展示,展示圖片
滑塊
圖片'''
# 判斷函數(shù)
if len(path) is 0:
return 0
if path.endswith('.jpg') is not True:
return 0
# 讀取圖片
a = tk.Toplevel()
img = Image.open(path)
img = ImageTk.PhotoImage(img)
# 可以調(diào)節(jié)界面
a.rowconfigure(3, weight=1)
for j in range(2):
a.columnconfigure(j, weight=1)
# 畫布
l30 = tk.Label(a, image=img)
l30.grid(row=3, columnspan=2, sticky=tk.NSEW)
# 定義一個變量
kernelwidth = tk.IntVar()
kernelwidth.set(1)
# 定義滑塊函數(shù)
def setwidth(value):
kernelwidth.set(value)
# 定義滑塊
scale20 = tk.Scale(a, from_=1, to=5, orient=tk.HORIZONTAL, showvalue=1,
resolution=1, tickinterval=1, command=setwidth)
scale20.grid(row=2, columnspan=2, sticky=tk.EW)
# 滑塊數(shù)值顯示器
l10 = tk.Label(a, textvariable='濾波核寬度為' + str(kernelwidth.get() * 20), bg='pink')
l10.grid(row=1, column=0, sticky=tk.EW)
# 按鈕函數(shù)組件1:低通濾波器
def low_filter():
width = kernelwidth.get() * 10
img = cv.imread(path)
rows, cols = img.shape[:2]
mask = np.zeros((rows,cols), np.uint8)
mask[(rows // 2 - width):(rows // 2 + width)][:, (cols // 2 - width):(cols // 2 + width)] = 1
img_l = [1, 2, 3]
for i in range(3):
f1 = np.fft.fft2(img[:, :, i])
f1shift = np.fft.fftshift(f1) * mask
f2shift = np.fft.ifftshift(f1shift)
img_new = np.fft.ifft2(f2shift)
img_new = np.abs(img_new)
img_new = (img_new - np.amin(img_new)) / (np.amax(img_new) - np.amin(img_new))
img_new *= 255
img_l[i] = np.array(img_new, np.uint8)
img = np.stack((img_l[0], img_l[1], img_l[2]), axis=2)
img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
img = Image.fromarray(img)
return img
def button11():
img = low_filter()
img = ImageTk.PhotoImage(img)
l30.configure(image=img)
a.mainloop()
b11 = tk.Button(a, text='點此展示濾波效果', command=button11)
b11.grid(row=1, column=1, sticky=tk.EW)
# 保存
entry01 = tk.Entry(a)
entry01.grid(row=0, column=0, sticky=tk.EW)
# 下面的部分是保存圖片的按鈕,會利用到之前的rotimg函數(shù),和之前一樣,先寫按鈕函數(shù)
def button02():
path = entry01.get()
if len(path) == 0:
print('保存失敗')
return 0
img = low_filter()
img.save(path)
# 保存成功我們希望有個彈窗
winmessage = tk.Toplevel(a)
winmessage.rowconfigure(0, weight=1)
winmessage.columnconfigure(0, weight=1)
winmessage.geometry('300x200')
tk.Message(winmessage, text='恭喜你,或者說恭喜這個熬了很久的猿,你們保存成功了').grid(sticky=tk.NSEW)
# 這里就是保存圖片按鈕了
b02 = tk.Button(a, text='左側(cè)輸入,點此保存', command=button02)
b02.grid(row=0, column=1, sticky=tk.EW)
a.mainloop()
def button35():#低通濾波
# 判斷函數(shù)
if len(path) is 0:
return 0
if path.endswith('.jpg') is not True:
return 0
# 讀取圖片
a = tk.Toplevel()
img = Image.open(path)
img = ImageTk.PhotoImage(img)
# 可以調(diào)節(jié)界面
a.rowconfigure(3, weight=1)
for j in range(2):
a.columnconfigure(j, weight=1)
# 畫布
l30 = tk.Label(a, image=img)
l30.grid(row=3, columnspan=2, sticky=tk.NSEW)
# 定義一個變量
kernelwidth = tk.IntVar()
kernelwidth.set(1)
# 定義滑塊函數(shù)
def setwidth(value):
kernelwidth.set(value)
# 定義滑塊
scale20 = tk.Scale(a, from_=1, to=5, orient=tk.HORIZONTAL, showvalue=1,
resolution=1, tickinterval=1, command=setwidth)
scale20.grid(row=2, columnspan=2, sticky=tk.EW)
# 滑塊數(shù)值顯示器
l10 = tk.Label(a, textvariable='濾波核寬度為' + str(kernelwidth.get() * 20), bg='pink')
l10.grid(row=1, column=0, sticky=tk.EW)
# 按鈕函數(shù)組件1:低通濾波器
def low_filter():
width = kernelwidth.get() * 10
img = cv.imread(path)
rows, cols = img.shape[:2]
mask = np.ones((rows,cols), np.uint8)
mask[(rows // 2 - width):(rows // 2 + width)][:, (cols // 2 - width):(cols // 2 + width)] = 0
img_l = [1, 2, 3]
for i in range(3):
f1 = np.fft.fft2(img[:, :, i])
f1shift = np.fft.fftshift(f1) * mask
f2shift = np.fft.ifftshift(f1shift)
img_new = np.fft.ifft2(f2shift)
img_new = np.abs(img_new)
img_new = (img_new - np.amin(img_new)) / (np.amax(img_new) - np.amin(img_new))
img_new *= 255
img_l[i] = np.array(img_new, np.uint8)
img = np.stack((img_l[0], img_l[1], img_l[2]), axis=2)
img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
img = Image.fromarray(img)
return img
def button11():
img = low_filter()
img = ImageTk.PhotoImage(img)
l30.configure(image=img)
a.mainloop()
b11 = tk.Button(a, text='點此展示濾波效果', command=button11)
b11.grid(row=1, column=1, sticky=tk.EW)
# 保存
entry01 = tk.Entry(a)
entry01.grid(row=0, column=0, sticky=tk.EW)
# 下面的部分是保存圖片的按鈕,會利用到之前的rotimg函數(shù),和之前一樣,先寫按鈕函數(shù)
def button02():
path = entry01.get()
if len(path) == 0:
print('保存失敗')
return 0
img = low_filter()
img.save(path)
# 保存成功我們希望有個彈窗
winmessage = tk.Toplevel(a)
winmessage.rowconfigure(0, weight=1)
winmessage.columnconfigure(0, weight=1)
winmessage.geometry('300x200')
tk.Message(winmessage, text='恭喜你,或者說恭喜這個熬了很久的猿,你們保存成功了').grid(sticky=tk.NSEW)
# 這里就是保存圖片按鈕了
b02 = tk.Button(a, text='左側(cè)輸入,點此保存', command=button02)
b02.grid(row=0, column=1, sticky=tk.EW)
a.mainloop()
win = tk.Tk()
win.rowconfigure((3),weight=1)
win.columnconfigure((0,1,2,3,4),weight=1)
path = ''
lab1 = tk.Label(win,width=30,height=30).grid(row=3,column=0,sticky=tk.NSEW,columnspan=5)
entry1 = tk.Entry(win, width=20)
entry1.grid(row=0, column=1, sticky=tk.EW)
lab2 = tk.Label(win, text='輸入圖片路徑', width=20).grid(row=0, column=0,sticky=tk.EW)
lab2 = tk.Label(win, text='手動選擇路勁', width=20).grid(row=0, column=3,sticky=tk.EW)
b1 = tk.Button(win, text='選擇路徑', command=button1, width=20).grid(row=0, column=4,sticky=tk.EW)
b2 = tk.Button(win, text='確認路徑', command=button2, width=20).grid(row=0, column=2,sticky=tk.EW)
b21 = tk.Button(win, text='鏡像', command=button21, width=20).grid(row=1, column=0,sticky=tk.EW)
b22 = tk.Button(win, text='平移', command=button22, width=20).grid(row=1, column=1,sticky=tk.EW)
b23 = tk.Button(win, text='直方圖均衡化', command=button23, width=20).grid(row=1, column=2,sticky=tk.EW)
b24 = tk.Button(win, text='順時針旋轉(zhuǎn)', command=button24, width=20).grid(row=1, column=3,sticky=tk.EW)
b25 = tk.Button(win, text='縮放', command=button25, width=20).grid(row=1, column=4,sticky=tk.EW)
b31 = tk.Button(win, text='圖像平滑', command=button31, width=20).grid(row=2, column=0,sticky=tk.EW)
b32 = tk.Button(win, text='圖像銳化', command=button32, width=20).grid(row=2, column=1,sticky=tk.EW)
b33 = tk.Button(win, text='低通濾波', command=button33, width=20).grid(row=2, column=2,sticky=tk.EW)
b34 = tk.Button(win, text='高斯噪聲', command=gsnoise, width=20).grid(row=2, column=3,sticky=tk.EW)
b35 = tk.Button(win, text='高通濾波', command=button35, width=20).grid(row=2, column=4,sticky=tk.EW)
win.mainloop()
到了這里,關(guān)于python opencv+tkinter 使用tkinter實現(xiàn)交互式圖像處理工具的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!