# -*- coding: utf-8 -*- """ Spyder 编辑器
这是一个临时脚本文件。 """
import tkinter as tk import numpy as np from PIL import Image,ImageTk import tkinter.filedialog as tkfd import tkinter.simpledialog as askdiag import const class window(tk.Tk): ? ? def __init__(self): ? ? ? ? tk.Tk.__init__(self) ? ? ? ?? ? ? ? ? self.resizable(0, 0) ? ? ? ? self.title('main window') ? ? ? ? self.geometry('640x480') ? ? ? ? ? ? menuBar=tk.Menu(self) ? #创建一个菜单实例, ? ? ? ? self['menu']=menuBar ? ?#将菜单置于运行窗口中,一个窗口只能有一个菜单,并默认置于顶端 ?? ? ? ? ? menu01=tk.Menu(menuBar,tearoff=False) ? #创建一个二级菜单,置于menuBar中 ? ? ? ? menuBar.add_cascade(label='文件',menu=menu01) ?#在menu0中添加一个label='文件' 为项目的级联菜单 ? ? ? ? menu01.add_command(label='打开',command=self.openfile) #添加二级菜单项 ? ? ? ? menu01.add_separator()#分割线 ? ? ? ? menu01.add_command(label='保存',command=self.savefile) #添加二级菜单项 ? ? ? ? menu01.add_separator()#分割线 ? ? ? ? menu01.add_command(label='退出',command=self.exitsys) ?#添加二级菜单项 ? ? ? ?? ? ? ? ? menu02=tk.Menu(menuBar,tearoff=False) ? #创建一个二级菜单,置于menuBar中 ? ? ? ?? ? ? ? ? menuBar.add_cascade(label='图像操作',menu=menu02) ?#在menuBar中添加一个label='文件' 为项目的级联菜单 ? ? ? ? menu02.add_command(label='灰度化处理',command=self.gray) ?#添加二级菜单项 ? ? ? ? menu02.add_separator()#分割线 ? ? ?? ? ? ? ? menu02.add_command(label='显示直方图',command=self.hist) #添加二级菜单项 ? ? ? ? menu02.add_separator()#分割线 ? ? ? ? menu02.add_command(label='阈值二值化',command=self.binProc) #添加二级菜单项 ? ? ? ? menu02.add_separator()#分割线 ? ? ? ? menu02.add_command(label='阈值区间二值化',command=self.binProc2) ?#添加二级菜单项 ? ? ? ?? ? ? ? ? menu03=tk.Menu(menuBar,tearoff=False) ? #创建一个二级菜单,置于menuBar中 ?? ? ? ? ? menu03.add_command(label='直方图均衡化',command=self.histogram_match) ? ? ? ? menu03.add_separator()#分割线 ? ? ? ? menuBar.add_cascade(label='亮度操作',menu=menu03) ?#在menu01中添加一个label='文件' 为项目的级联菜单 ? ? ? ? menu03.add_command(label='对比度调节',command=self.contrast_bright) ? ? ? ? menu03.add_separator()#分割线 ? ? ? ? menu03.add_command(label='对比度调节',command=self.contrast_bright) ? ? ? ?? ? ? ? ? menu04=tk.Menu(menuBar,tearoff=False) ? #创建一个二级菜单,置于menuBar中 ? ? ? ? ? menuBar.add_cascade(label='边缘检测',menu=menu04) ?#在menu01中添加一个label='文件' 为项目的级联菜单 ? ? ? ? menu04.add_command(label='robert算子',command=self.robert) ? ? ? ? menu04.add_separator()#分割线 ? ? ? ? ? ? ? ? menu04.add_command(label='sobel算子',command=self.sobel) ? ? ? ? menu04.add_separator()#分割线 ? ? ? ? menu04.add_command(label='Laplace算子',command=self.laplace) ? ? ? ?? ? ? ? ? tp=tk.Frame(self) ? ? ? ? tp.pack() ? ? ? ?? ? ? ? ? self.w=None ? ? ? ? self.h=None ? ? ? ? self.resizeimg=None #固定640*480大小图像,在窗口显示 ? ? ? ? self.imgarray=None ?# 加载图像的数组形式? ? ? ? ? self.photo=None ? #加载的图像? ? ? ? ? #self.canvasimg=None #使用PhotoImage转换为画布显示图像,用于画布显示? ? ? ? ? #使用Canvas显示图像 ? ? ? ? ? ? ? ? self.canvas=tk.Canvas(tp, width=640,height=480) ? ? ? ? ? ? ? self.canvas.pack(fill = 'both',expand ='yes') ? ? ? ? self.canvas_on_image=self.canvas.create_image(0, 0, anchor='nw', image=None) ? ? # robert 算子[[-1,-1],[1,1]] ? ? def robert(self): ? ? ? ? r_suanzi = [[-1,-1],[1,1]] # ? ? ? ?for x in range(self.h-1): # ? ? ? ? ? ?for y in range(self.w-1): ? ? ? ? ? ? ? ? ? ? # ? ? ? ? ? ? ? ? ? ?self.imgarray[x, y,1] = abs(np.sum(r_suanzi*self.imgarray[x:x+2, y:y+2,1])) ? ?# 求和加绝对值 ? ? ? ? g=self.imgarray[:,:,1] ? ? ? ? for i in range(g.shape[0]-1): ? ? ? ? ? ? for j in range(g.shape[1]-1): ? ? ? ? ? ? ? ? g[i,j]=abs(int(g[i+1,j])-int(g[i,j]))+abs(int(g[i,j+1])-int(g[i,j])) ? ? ? ? ? ? ? ? # ? ? ? ?self.imgarray[:,:,0]=self.imgarray[:,:,1] # ? ? ? ?self.imgarray[:,:,2]=self.imgarray[:,:,1] ? ? ? ? self.imgarray[:,:,0]=g ? ? ? ? self.imgarray[:,:,1]=g ? ? ? ? self.imgarray[:,:,2]=g ? ? ? ? self.canvas_draw() ? ? ? ? return ? ? ? ? ? ? ? ? ? ? ? # # sobel算子的实现 ? ? def sobel(self): ? ? ? ? ? ? ? ? s_suanziX = np.array([[-1,0,1],[-2,0,2],[-1,0,1]]) ? ? ?# X方向 ? ? ? ? s_suanziY = np.array([[-1,-2,-1],[0,0,0],[1,2,1]]) ? ? ? ? for i in range(self.h-2): ? ? ? ? ? ? for j in range(self.w-2): ? ? ?? ? ? ? ? ? ? ? ? ? ? new_imageX = abs(np.sum(self.imgarray[i:i+3, j:j+3,1] * s_suanziX)) ? ? ? ? ? ? ? ? ? ? new_imageY = abs(np.sum(self.imgarray[i:i+3, j:j+3,1] * s_suanziY)) ? ? ? ? ? ? ? ? ? ? self.imgarray[i, j,1] = (new_imageX*new_imageX + new_imageY*new_imageY)**0.5 ? ? ? ? ? ? ? ? ? ?? ? ? ? ? self.imgarray[:,:,0]=self.imgarray[:,:,1] ? ? ? ? self.imgarray[:,:,2]=self.imgarray[:,:,1] ? ? ? ? self.canvas_draw() ? ? ? ? return? ? ? ? # Laplace算子 ? ? # 常用的Laplace算子模板 ?[[0,1,0],[1,-4,1],[0,1,0]] ? [[1,1,1],[1,-8,1],[1,1,1]] ? ? def laplace(self): ? ? ? ? ? L_suanzi = np.array([[0,-1,0],[-1,4,-1],[0,-1,0]]) ? ?? ? ? ? ? # L_sunnzi = np.array([[1,1,1],[1,-8,1],[1,1,1]]) ? ? ? # ? ? ? ?for i in range(self.h-2): # ? ? ? ? ? ?for j in range(self.w-2): ?? # ? ? ? ? ? ? ? ? ? ?self.imgarray[i, j,1] = abs(np.sum( L_suanzi*self.imgarray[i:i+3, j:j+3,1] )) ? ? ? ? g=self.imgarray[:,:,1] ? ? ? ? for i in range(1,g.shape[0]-1): ? ? ? ? ? ? for j in range(1,g.shape[1]-1): ? ? ? ? ? ? ? ? g[i-1,j-1]=abs(4*int(g[i,j])-int(g[i-1,j])-int(g[i,j+1])-int(g[i+1,j])-int(g[i,j-1])) ? ? ? ? ? ? ? ? if g[i-1,j-1]>255: ? ? ? ? ? ? ? ? ? ? g[i-1,j-1]=255 ? ? ? ? ? ? ? ? ? ? ? ? self.imgarray[:,:,1]=g ? ? ? ? self.imgarray[:,:,0]=self.imgarray[:,:,1] ? ? ? ? self.imgarray[:,:,2]=self.imgarray[:,:,1] ? ? ? ? self.canvas_draw() ? ? ? ? return?
? ? def histogram_match(self): ?#直方图均衡化处理 ? ? ? ? ? self.imgarray=np.array(self.photo) ? ? ? ? r=np.zeros(256) ? ? ? ? g=np.zeros(256) ? ? ? ? b=np.zeros(256) ? ? ? ? ? tempr=np.zeros(256) ? ? ? ? tempg=np.zeros(256) ? ? ? ? tempb=np.zeros(256) ? ? ? ? tr=np.zeros(256) ? ? ? ? tg=np.zeros(256) ? ? ? ? tb=np.zeros(256) ? ? ? ? for i in range(self.imgarray.shape[0]): ? ? ? ? ? ? for j in range(self.imgarray.shape[1]): ? ? ? ? ? ? ? ? ? r[self.imgarray[i][j][0]]+=1 ? ? ? ? ? ? ? ? ? g[self.imgarray[i][j][1]]+=1 ? ? ? ? ? ? ? ? ? b[self.imgarray[i][j][2]]+=1 ? ? ? ? ? r=r/(self.w*self.h) ? ? ? ? g=g/(self.w*self.h) ? ? ? ? b=b/(self.w*self.h) ? ? ? ? ? ? ? ? tempr[0]=r[0] ? ? ? ? tempg[0]=g[0] ? ? ? ? tempb[0]=b[0] ? ? ? ? for i in range(1,256): ? ? ? ? ? ? tempr[i]=tempr[i-1]+r[i] ? ? ? ? ? ? tempg[i]=tempg[i-1]+g[i] ? ? ? ? ? ? tempb[i]=tempb[i-1]+b[i] ? ? ? ? ? ? tr[i]=int(tempr[i]*255+0.5) ? ? ? ? ? ? tg[i]=int(tempg[i]*255+0.5) ? ? ? ? ? ? tb[i]=int(tempb[i]*255+0.5) ? ? ? ? for i in range(self.imgarray.shape[0]): ? ? ? ? ? ? for j in range(self.imgarray.shape[1]): ? ? ? ? ? ? ? ? self.imgarray[i][j][0]=tr[self.imgarray[i][j][0]] ? ? ? ? ? ? ? ? self.imgarray[i][j][1]=tg[self.imgarray[i][j][1]] ? ? ? ? ? ? ? ? self.imgarray[i][j][2]=tb[self.imgarray[i][j][2]] ? ? ? ? self.canvas_draw() ? ? ? ? return ? ? ? ? ? ? ? ? def contrast_bright(self): #对比度 ? ? ? ? stk=tk.Tk() ? ? ? ? ? ? ? stk.title('对比度和亮度调整') ? ? ? ? stk.geometry('200x100') ? ? ? ? ? yr= np.array(self.imgarray[:,:,0])#创建新的数组,值为self.imgarray[:,:,0] ? ? ? ? yg= np.array(self.imgarray[:,:,1]) ? ? ? ? yb= np.array(self.imgarray[:,:,2]) ? ? ? ? thredr=np.mean(yr) ? ? ? ? thredg=np.mean(yg) ? ? ? ? thredb=np.mean(yb) ? ? ? ? ? ? ? ? def getval(super):? ? ? ? ? ? ? cnum=int(s1.get()) ? ? ? ? ? ? bnum=int(s2.get()) ? ? ? ? ? ? r,g,b=(yr,yg,yb) ? ? ? ? ? ? #(像素值-像素均值)*对比度系数+像素均值*明亮度系数 ? ? ? ? ? ? r=r+np.trunc((r-thredr)*cnum/255+thredr*bnum/255) ? ? ? ? ? ? g=g+np.trunc((r-thredg)*cnum/255+thredg*bnum/255) ? ? ? ? ? ? b=b+np.trunc((r-thredb)*cnum/255+thredb*bnum/255) ? ? ? ? ? ? for i in [r,g,b]: ? ? ? ? ? ? ? ? i[i>255]=255 ? ? ? ? ? ? ? ? i[i<0]=0 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? self.imgarray[:,:,0]=r ? ? ? ? ? ? self.imgarray[:,:,1]=g ? ? ? ? ? ? self.imgarray[:,:,2]=b ? ? ? ? ? ? ? ? ? ? ? ? self.canvas_draw() ? ? ? ? ? ? ? ? ? ? ? ? return? ? ? ? ?? ? ? ? ? tk.Label(stk, text="对比度:").grid(row=0, column=0, padx=5, pady=5, sticky='W') ? ? ? ? ? ? ? ? s1=tk.Scale(stk,length=120, command=getval,from_=-255, to=255,orient="horizontal",relief='flat') ? ? ? ? s1.grid(row=0, column=1) ? ? ? ? ? ? ? ? tk.Label(stk,text='亮 ?度:').grid(row=1, column=0, padx=5, pady=5, sticky='W') ? ? ? ? ? ? ? ? s2 = tk.Scale(stk,length=120, command=getval,from_=-255, to=255,orient="horizontal",relief='flat') ? ? ? ? s2.grid(row=1, column=1) ? ? ? ? stk.mainloop() ? ? ? ? return ? ? ? ? ? ? def brightness(self): ? ? ? ? pass ? ? def gray(self): ?#彩色图像灰度化处理 ? ? ? ? ? ? ? ? #self.imgarray=np.array(self.photo) # ? ? ? ?for i in range(self.imgarray.shape[0]): # ? ? ? ? ? ?for j in range(self.imgarray.shape[1]): # ? ? ? ? ? ? ? ?c=self.imgarray[i][j][0]*0.3+self.imgarray[i][j][1]*0.6+self.imgarray[i][j][2]*0.1 # ? ? ? ? ? ? ? ?self.imgarray[i][j][0]=c # ? ? ? ? ? ? ? ?self.imgarray[i][j][1]=c # ? ? ? ? ? ? ? ?self.imgarray[i][j][2]=c ? ? ?? ? ? ? ? c=self.imgarray[:,:,0]*0.3+self.imgarray[:,:,1]*0.6+self.imgarray[:,:,2]*0.1 ? ? ? ? c=np.trunc(c) ?#将元素值取整 ? ?? # ? ? ? ?a = np.reshape(c,(c.shape[0],c.shape[1],1))#将二维矩阵转为一层的三维矩阵 # ? ? ? ?self.imgarray= np.concatenate([a,a,a],2)#将3个三维矩阵按照第三轴叠加 ? ? ? ? self.imgarray[:,:,0]=c ? ? ? ? self.imgarray[:,:,2]=c ? ? ? ? self.imgarray[:,:,1]=c ? ? ? ? self.canvas_draw() ? ? ? ? return ? ? def binProc(self):#阈值二值化 ? ? ? ? threshold=askdiag.askinteger('阈值二值化','输入二分阈值',initialvalue=128) ? ? ? ? g=self.imgarray[:,:,1] ? ? ? ? g[g>threshold ]=255 ? ? ? ? g[g<threshold]=0 ? ? ? ? self.imgarray[:,:,0]=g ? ? ? ? self.imgarray[:,:,1]=g ? ? ? ? self.imgarray[:,:,2]=g ? ? ? ? self.canvas_draw() ? ? ? ? pass ? ? def hist(self): ?#彩色直方图 ? ? ? ? histtk=tk.Tk() ? ? ? ? histtk.title('彩色直方图') ? ? ? ? histtk.geometry('900x300') ? ? ? ? canvas=tk.Canvas(histtk, width=900,height=300) ? ? ? ? ? ? ? canvas.pack(fill = 'both',expand ='yes') ? ? ? ? canvas.create_text(100,20, text=str('R')) ? ? ? ? ? canvas.create_text(400,20, text=str('G')) ? ? ? ? ? canvas.create_text(700,20, text=str('B')) ? ? ? ? ? canvas.create_rectangle(10,30,265,280) ? ? ? ? canvas.create_rectangle(300,30,555,280) ? ? ? ? canvas.create_rectangle(600,30,855,280) ? ? ? ?# photo= Image.open('3d水滴.jpg') ?#加载的图像 ?? ? ? ? ? self.imgarray=np.array(self.photo) ? ? ? ? r=np.zeros(256) ? ? ? ? g=np.zeros(256) ? ? ? ? b=np.zeros(256) ? ? ? ? x=np.arange(0,256) ? ? ? ?? ? ? ? ? for i in range(self.imgarray.shape[0]): ? ? ? ? ? ? for j in range(self.imgarray.shape[1]): ? ? ? ? ? ? ? ? ? r[self.imgarray[i][j][0]]+=1 ? ? ? ? ? ? ? ? ? g[self.imgarray[i][j][1]]+=1 ? ? ? ? ? ? ? ? ? b[self.imgarray[i][j][2]]+=1 ? ? ? ?? ? ? ? ? r=r/np.max(r) ? ? ? ? ? ? ? ? r=np.int_(r*250) ? ? ? ? g=g/np.max(g) ? ? ? ? g=np.int_(g*250) ? ? ? ? ? b=b/np.max(b) ? ? ? ? b=np.int_(b*250) ? ? ? ? ? ? ? ? ? ? for i in range(256): ? ? ? ? ? ? canvas.create_line(10+x[i],280,10+x[i],280-r[i],width=1,fill='red') ? ? ? ? ? ? canvas.create_line(300+x[i],280,300+x[i],280-g[i],width=1,fill='green') ? ? ? ? ? ? canvas.create_line(600+x[i],280,600+x[i],280-b[i],width=1,fill='blue') ? ? ? ? for i in range(0,201,50): ? ? ? ? ? ? ? ? ? ? ? ? canvas.create_text(10+x[i],290, text=str(x[i]))? ? ? ? ? ? ? canvas.create_text(300+x[i],290, text=str(x[i]))? ? ? ? ? ? ? canvas.create_text(600+x[i],290, text=str(x[i]))? ? ? ? ? canvas.create_text(10+255,290, text=str(255)) ?? ? ? ? ? canvas.create_text(300+255,290, text=str(255)) ? ? ? ? ? canvas.create_text(600+255,290, text=str(255))? ? ? ? ? pass ? ? def binProc2(self): ?#阈值区间二值化 ? ? ? ? hk=tk.Tk() ? ? ? ? hk.title('阈值区间二值化') ? ? ? ? hk.geometry('200x100') ? ? ? ? lab1 = tk.Label(hk, text="值1:") ? ? ? ? lab1.grid(row=0, column=0, padx=5, pady=5, sticky='W') ? ? ? ? ? ? ? ? low = tk.IntVar()#绑定对象到Entry ? ? ? ? ent1 = tk.Entry(hk, textvariable=low) ? ? ? ? ? ? ? ? ent1.grid(row=0, column=1, sticky='ew', columnspan=2) ? ? ? ?? ? ? ? ? lab2 = tk.Label(hk, text="值1:") ? ? ? ? lab2.grid(row=1, column=0, padx=5, pady=5, sticky='W') ? ? ?? ? ? ? ? high = tk.IntVar() #绑定对象到Entry ? ? ? ? ent2 = tk.Entry(hk, textvariable=high) ? ? ? ? ent2.grid(row=1, column=1, sticky='ew', columnspan=2) ? ? ? ? ? ? ? ? def on_click(): ? ? ? ? ? ? for i in range(self.imgarray.shape[0]): ? ? ? ? ? ? ? ? for j in range(self.imgarray.shape[1]): ? ? ? ? ? ? ? ? ? ? c=self.imgarray[i][j][1] ?#以G分量为基础进行阈值区间二值化 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if c>=int(ent1.get()) and c<=int(ent2.get()): ? ? ? ? ? ? ? ? ? ? ? ? c=255 ? ? ? ? ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? ? ? ? ? c=0 ? ? ? ? ? ? ? ? ? ? self.imgarray[i][j][0]=c ? ? ? ? ? ? ? ? ? ? self.imgarray[i][j][1]=c ? ? ? ? ? ? ? ? ? ? self.imgarray[i][j][2]=c? ? ? ? ? ? ? self.canvas_draw() ? ? ? ? ? ? hk.quit() ? ? ? ? ? ? hk.destroy() ? ? ? ? ? ? return ? ? ? ? bntok=tk.Button(hk,text='确定',command=on_click) ? ? ? ? bntok.grid(row=2, column=1) ?? ? ? ? ? hk.mainloop() ? ? ? ? return ? ? ? ??
? ? def openfile(self): ? ? ? ? filetype = [('JPGE Files', '*.jpg'), ? ? ? ? ? ? ? ? ? ? ('PNG Files', '*.png'), ? ? ? ? ? ? ? ? ? ? ('All Files', '*.*')] ? ? ? ? filename = tkfd.askopenfilename(filetypes = filetype) ? ? ? ? self.photo= Image.open(filename) ?#加载的图像 ? ? ? ? ? self.imgarray=np.array(self.photo)#图像数据转换为数组 ? ? ? ?? ? ? ? ? self.w,self.h=self.photo.size ?#获得图像实际大小 ? ? ? ? self.canvas_draw()#绘制图像 ? ? ? ? return ? ? def savefile(self): ? ? ? ? filetype = [('JPGE Files', '*.jpg'), ? ? ? ? ? ? ? ? ? ? ('PNG Files', '*.png'),] ? ? ? ? filename=tk.StringVar() ? ? ? ? filepath=tkfd.asksaveasfilename(filetypes = filetype,defaultextension='.png') ? ? ? ? filename.set(filepath) ? ? ? ? img= Image.fromarray(self.imgarray.astype('uint8')) ? ? ? ? img.save(str(filename.get())) ? ? ? ?? ? ? ? ? return ? ? def exitsys(self): ? ? ? ? self.quit() ? ? ? ? self.destroy() ? ? ? ? pass ? ? def canvas_draw(self): ? ? ? ? if self.w>640 and self.h>480: ? ? ? ? ? ? ?width=640 ?#尺寸大于640*480的以640*480大小显示 ? ? ? ? ? ? ?high=480 ? ? ? ? elif self.w>640 and self.h<=480: ? ? ? ? ? ? rat=self.w/self.h ?#宽大于640,高对应缩放 ? ? ? ? ? ? width=640 ? ? ? ? ? ? high=int(640/rat) ? ? ? ? elif self.w<=640 and self.h>480: ? ? ? ? ? ? rat=self.w/self.h #高大于480,宽对应缩放 ? ? ? ? ? ? width=int(480*rat) ? ? ? ? ? ? high=480 ? ? ? ? else: ? ? ? ? ? ? width=self.w ? ? ? ? ? ? high=self.h ? ? ? ? ? ? ? ? ? ? ? ? ?#numpy数组数据转换为PIL.Image形式 ? ? ? ? self.photo= Image.fromarray(self.imgarray.astype('uint8')).convert('RGB') ? ? ? ? resizeimg =self.photo.resize((width,high)) ?# 规定显示图片大小为640*480? ? ? ? ? self.canvasimg = ImageTk.PhotoImage(resizeimg) ? ? ? ? #更新画布图像数据 ? ? ? ?? ? ? ? ? self.canvas.itemconfig(self.canvas_on_image,image=self.canvasimg) ? ? ? ? return if __name__=='__main__': ? ? w=window() ? ? w.mainloop() ?? ''' 给个photoshop调节对比度的公式, nRGB = RGB + (RGB - Threshold) * Contrast / 255 其中nRGB代表了r,g,b各自重新计算后的值。Threshold是平均亮度,一般我们不会特意算图像的平均亮度,一来耗时,二来大部分图片是在100~150之间。我们取127,与实际相近。Contrast取值范围为[-255,255]。 所以当Contrast为0时,rgb值不变,表示当前的一个对比度。 为-255时,rgb都为127,亮度都一样,没有差别,呈灰色。 为255时,在Threshold之上的像素点会变得更亮,反之变得更暗。 '''
加载图像
图像灰度化等处理
?
?直方图
?
图像对比度,亮度和边缘算子处理
|