机器视觉编程作业02(01)(原创)

背景:机器视觉课堂编程作业之二

功能:实现边界检测、直线检测、圆检测

使用平台:python36  opencv34

注意事项:python36下的opencv34出现了一些函数的用法变动

总体效果还是很好的。

显示效果:

源代码:

  1 #-*- coding:utf-8 -*-
  2 #edited by Mufasa
  3 
  4 import tkinter as tk
  5 import tkinter.filedialog
  6 from PIL import Image, ImageTk
  7 import numpy as np
  8 from  tkinter import ttk
  9 import time,threading
 10 import matplotlib.pyplot as plt
 11 from mpl_toolkits.mplot3d import Axes3D
 12 from tkinter import messagebox
 13 import cv2
 14 import os
 15 
 16 class main_:
 17     # def ui_():
 18         
 19     def btn_begin():
 20         global root
 21         btn_select = tk.Button(root,text='打开文件',width=15,command=assist.select).grid(row=0,column=0)
 22         btn_about = tk.Button(root,text='关于程序',width=15,command=assist.about).grid(row=0,column=4)
 23     def show_photo():
 24         global root
 25         label = tk.Label(root)
 26     def btn_then():
 27         global root
 28         btn_about = tk.Button(root,text='显示灰度原图',width=15,command=assist.show_gray).grid(row=0,column=1)
 29         btn_about = tk.Button(root,text='数据还原',width=15,command=assist.restart).grid(row=0,column=2)
 30         btn_about = tk.Button(root,text='当前图像保存',width=15,command=assist.storage).grid(row=0,column=3)
 31         
 32         btn_about = tk.Button(root,text='高斯滤波',width=15,command=filter.GaussianBlur).grid(row=1,column=0)
 33         btn_about = tk.Button(root,text='均值滤波',width=15,command=filter.MeanBlur).grid(row=1,column=1)
 34         btn_about = tk.Button(root,text='中值滤波',width=15,command=filter.medianBlur).grid(row=1,column=2)
 35         btn_about = tk.Button(root,text='双边滤波',width=15,command=filter.bilateralFilter).grid(row=1,column=3)
 36         btn_about = tk.Button(root,text='2d滤波器',width=15,command=filter.filter2D).grid(row=1,column=4)
 37         
 38         btn_about = tk.Button(root,text='laplacian',width=15,command=algorithm.laplacian).grid(row=2,column=0)
 39         btn_about = tk.Button(root,text='canny',width=15,command=algorithm.canny).grid(row=2,column=1)
 40         btn_about = tk.Button(root,text='形态学',width=15,command=algorithm.morphology).grid(row=2,column=2)
 41         btn_about = tk.Button(root,text='sobel算子',width=15,command=algorithm.sobel).grid(row=2,column=3)
 42         btn_about = tk.Button(root,text='检测原理解释',width=15,command=assist.describe_edge).grid(row=2,column=4)
 43         
 44         
 45         btn_about = tk.Button(root,text='梯度模型1',width=15,command=lambda:algorithm.gradient(n=0)).grid(row=3,column=0)
 46         btn_about = tk.Button(root,text='梯度模型2',width=15,command=lambda:algorithm.gradient(n=1)).grid(row=3,column=1)
 47         btn_about = tk.Button(root,text='梯度模型3',width=15,command=lambda:algorithm.gradient(n=2)).grid(row=3,column=2)
 48         btn_about = tk.Button(root,text='梯度模型4',width=15,command=lambda:algorithm.gradient(n=3)).grid(row=3,column=3)
 49         btn_about = tk.Button(root,text='梯度算法介绍',width=15,command=assist.describe_gradient).grid(row=3,column=4)
 50         
 51         btn_about = tk.Button(root,text='霍夫曼直线',width=15,command=algorithm.HoughLines).grid(row=4,column=0)
 52         btn_about = tk.Button(root,text='概率霍夫曼直线',width=15,command=algorithm.HoughLinesP).grid(row=4,column=1)
 53         btn_about = tk.Button(root,text='霍夫曼圆检测',width=15,command=algorithm.HoughCircles).grid(row=4,column=2)
 54         btn_about = tk.Button(root,text='直方图谱',width=15,command=assist._2D_out).grid(row=4,column=3)
 55         btn_about = tk.Button(root,text='3D图谱显示',width=15,command=assist._3D_out).grid(row=4,column=4)
 56         
 57         
 58         
 59 class assist:
 60     def select():
 61         global data,path,im            #data是图像的灰度值
 62         path = tkinter.filedialog.askopenfilename(initialdir = '',filetypes=( ("Audio files", "*.jpg;*.bmp"),("All files", "*.*")))
 63         
 64         image = Image.open(path)
 65         im = ImageTk.PhotoImage(image)
 66         tk.Label(root, image = im).grid(row=5,column=0,columnspan=5)
 67         
 68         data = cv2.imdecode(np.fromfile(path,dtype=np.uint8),-1)
 69         if len(data.shape) >= 3:
 70             data = cv2.cvtColor(data,cv2.COLOR_BGR2GRAY)
 71         main_.btn_then()
 72         
 73     def show_gray():
 74         global data
 75         cv2.imshow(u"original", data)
 76         cv2.waitKey()
 77         cv2.destroyAllWindows()
 78         
 79     def _3D_out():
 80         global data
 81         fig = plt.figure()
 82         ax = Axes3D(fig)
 83         x = [i for i in range(len(data[0]))]
 84         y = [j for j in range(len(data))]
 85 
 86         X = np.mat(x)
 87         Y = np.mat(y)
 88         X, Y = np.meshgrid(X, Y)    #变成二维矩阵
 89         Z = np.mat(data)
 90         ax.plot_surface(X, Y, Z, rstride=5, cstride=5, cmap='rainbow')
 91         plt.show()
 92         
 93     def _2D_out():
 94         global data
 95         d_array = [0]*256
 96         for i in data:
 97             for j in i:
 98                 d_array[j] = d_array[j] + 1
 99         plt.title(u"Ash rectangle",fontsize=24)
100         plt.xlabel("Ash values",fontsize=10)
101         plt.ylabel("Numbers",fontsize=10)
102         plt.plot(d_array,linewidth=1)
103         plt.show()
104         
105     def restart():
106         global data
107         data = cv2.imdecode(np.fromfile(path,dtype=np.uint8),-1)
108         if len(data.shape) >= 3:
109             data = cv2.cvtColor(data,cv2.COLOR_BGR2GRAY)
110         
111     def about():
112         tk.messagebox.showinfo(title='关于程序', message=(
113         '程序名称:边界检测
程序平台:python3.6、opencv3.4
编辑者:Mufasa
编辑时间:2017.12.24

主要功能:
1)灰度直方图、3D图谱显示;
2)高斯、均值、中值、双边、2d滤波器滤波;
3)Laplacian、Canny、形态学方法、sobel方法;
4)霍夫线变换、概率霍夫变换、霍夫圆变换;'
114         ))
115         
116     def describe_edge():
117         tk.messagebox.showinfo(title='算法简析', message=('Laplacian算法:计算灰度各个方向变化的二阶导数,将二阶导数的0值设置为边界
Canny算法:去噪声、计算梯度幅值和方向、进行非极大值抑制
形态学方法:将分别腐蚀和膨胀之后的图片进行相减处理
sobel算子:应用sobel算子对灰度图像进行卷积处理'))
118         
119     def describe_gradient():
120         tk.messagebox.showinfo(title='梯度算法', message=('梯度算法:
1)原理与sobel算子基本一致
2)可以分为垂直水平和45度135度角的两种方向
3)差值的取和方式分为算术和取最大值两种等多种形式'))
121         
122     def storage():
123         global data,path,name
124         p,f=os.path.split(path)
125         # print(p)
126         num = os.path.splitext(str(time.time()))[0]
127         # print(num)
128         # print(name)
129         # cv2.imwrite(p+'\'+name+'\'+num+'.jpg', data)    #python3版本下无法使用
130         cv2.imencode('.jpg', data)[1].tofile(p+'//'+name+"_"+num+'.jpg')
131         
132         
133 class filter:
134     def GaussianBlur():        #高斯滤波
135         global data,name
136         data = cv2.GaussianBlur(data,(5,5),0)
137         cv2.imshow(u"GaussianBlur", data)
138         name = "GaussianBlur"
139         cv2.waitKey()
140         cv2.destroyAllWindows()
141         
142     def MeanBlur():        #均值滤波
143         global data,name
144         data = cv2.blur(data,(3,5))
145         cv2.imshow(u"MeanBlur", data)
146         name = "MeanBlur"
147         cv2.waitKey()
148         cv2.destroyAllWindows()
149         
150     def filter2D():        #2D滤波器
151         global data,name
152         name = "filter2D"
153         kernel = np.ones((5,5),np.float32)/25
154         data = cv2.filter2D(data,-1,kernel)
155         cv2.imshow(u"filter2D", data)
156         cv2.waitKey()
157         cv2.destroyAllWindows()
158         
159     def bilateralFilter():        #双边滤波
160         global data,name
161         name = "bilateralFilter"
162         data = cv2.bilateralFilter(data,9,75,75)
163         cv2.imshow(u"bilateralFilter", data)
164         cv2.waitKey()
165         cv2.destroyAllWindows()
166         
167     def medianBlur():        #中值滤波
168         global data,name
169         name = "medianBlur"
170         
171         data = cv2.medianBlur(data,5)
172         cv2.imshow(u"medianBlur", data)
173         cv2.waitKey()
174         cv2.destroyAllWindows()
175         
176 class algorithm:
177     def laplacian():
178         global data,name
179         name = "laplacian"
180         gray_lap = cv2.Laplacian(data,cv2.CV_16S,ksize = 3)
181         data = cv2.convertScaleAbs(gray_lap)
182         cv2.imshow('laplacian',data)
183         cv2.waitKey()
184         cv2.destroyAllWindows()
185         
186     def canny():
187         global data,name
188         name = "canny"
189         data = cv2.Canny(data, 50, 100)
190         cv2.imshow('canny',data)
191         cv2.waitKey()
192         cv2.destroyAllWindows()
193     
194     def morphology():        #形态学边界检测,膨胀和腐蚀后的图片相减
195         global data,name
196         name = "morphology"
197         element = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))  
198         dilate = cv2.dilate(data, element)      # 扩大;膨胀;详述
199         erode = cv2.erode(data, element)      # 腐蚀,侵蚀
200         data = cv2.absdiff(dilate,erode)
201         cv2.imshow('morphology',data)
202         cv2.waitKey()
203         cv2.destroyAllWindows()
204     
205     def gradient(n):
206         if n == 0:
207             flag1,flag2 =0,0
208         elif n == 1:
209             flag1,flag2 =0,1
210         elif n == 2:
211             flag1,flag2 =1,0
212         elif n == 3:
213             flag1,flag2 =1,1
214             
215         global data,name
216         name = "gradient"
217         
218         w = data.shape[0]
219         h = data.shape[1]
220         size = (w,h)    #(575, 768)
221         iSharp = np.zeros(size, dtype='uint8')
222         t = 3
223         for i in range(0,w-t):    #高度减1!    #这里需要注意    i——(0,768-1-1=766)
224             for j in range(0,h-t):            #宽度也减1        j——(0,575-1-1=573)
225                 if flag2 == 0:
226                     x = abs(int(data[i,j+t])-int(data[i,j]))
227                     y = abs(int(data[i+t,j])-int(data[i,j]))    #index 575 is out of bounds for axis 0 with size 575
228                 else:
229                     x = abs(int(data[i+t,j+t])-int(data[i,j]))
230                     y = abs(int(data[i+t,j])-int(data[i,j+t]))
231                 
232                 if flag1 == 0:
233                     iSharp[i,j] = max(x,y)
234                 elif int(x)+int(y)>255:
235                     iSharp[i,j] = 255            #内存溢出可能出现的地点
236                 else:
237                     iSharp[i,j] = x+y
238         data = iSharp
239         cv2.imshow('gradient',data)
240         cv2.waitKey()
241         cv2.destroyAllWindows()
242         
243     def sobel():
244         global data,name
245         name = "sobel"
246         
247         x = cv2.Sobel(data,cv2.CV_16S,1,0)
248         y = cv2.Sobel(data,cv2.CV_16S,0,1)
249         absX = cv2.convertScaleAbs(x)# 转回uint8  
250         absY = cv2.convertScaleAbs(y)
251         data = cv2.addWeighted(absX,1,absY,1,0)
252         cv2.imshow('sobel',data)
253         cv2.waitKey()
254         cv2.destroyAllWindows()
255         
256     def HoughLines():
257         global data,name
258         name = "HoughLines"
259         
260         img = cv2.GaussianBlur(data,(3,3),0)    #先进行高斯滤波,这里必须要先进行这一项
261         img = cv2.Canny(img, 50, 150, apertureSize = 3)        #canny算子边界检测
262         lines = cv2.HoughLines(img,1,np.pi/180,100) #这里对最后一个参数使用了经验型的值
263         result = data.copy()
264         for i in lines:
265             for j in i:
266                 rho = j[0] #第一个元素是距离rho
267                 theta= j[1] #第二个元素是角度theta
268             if  (theta < (np.pi/4. )) or (theta > (3.*np.pi/4.0)): #垂直直线
269                 pt1 = (int(rho/np.cos(theta)),0)
270                 #该直线与最后一行的焦点
271                 pt2 = (int((rho-result.shape[0]*np.sin(theta))/np.cos(theta)),result.shape[0])
272                 #绘制一条白线
273                 cv2.line( result, pt1, pt2, (255))
274             else: #水平直线
275                 # 该直线与第一列的交点
276                 pt1 = (0,int(rho/np.sin(theta)))
277                 #该直线与最后一列的交点
278                 pt2 = (result.shape[1], int((rho-result.shape[1]*np.cos(theta))/np.sin(theta)))
279                 #绘制一条直线
280                 cv2.line(result, pt1, pt2, (255), 1)
281         data = result
282         cv2.imshow('HoughLines',data)
283         cv2.waitKey()
284         cv2.destroyAllWindows()
285         
286     def HoughLinesP():
287         global data,name
288         name = "HoughLinesP"
289         
290         edges = cv2.Canny(data, 50, 150, apertureSize = 3)  
291         minLineLength = 60
292         maxLineGap = 10
293         lines = cv2.HoughLinesP(edges,1,np.pi/180,80,minLineLength,maxLineGap)  
294         for i in lines:
295             for x1,y1,x2,y2 in i:  
296                 cv2.line(data,(x1,y1),(x2,y2),(255),2)  
297         cv2.imshow('HoughLinesP',data)
298         cv2.waitKey()
299         cv2.destroyAllWindows()
300         
301     def HoughCircles():
302         global data,name
303         name = "HoughCircles"
304         
305         edge = cv2.medianBlur(data, 5)
306         circles = cv2.HoughCircles(edge, cv2.HOUGH_GRADIENT, 1, 120, param1=100, param2 = 30, minRadius = 0,  maxRadius = 0)
307         circles = np.uint16(np.around(circles))
308         for i in circles[0,:,:]:
309             cv2.circle(data, (i[0], i[1]), i[2],(255),1)
310             cv2.circle(data, (i[0], i[1]), 1, (255), 1)
311         cv2.imshow("HoughCircles", data)
312         cv2.waitKey()
313         cv2.destroyAllWindows()
314         
315 global data,path,root,name
316 name = 'original'
317 
318 root = tk.Tk()
319 main_.btn_begin()
320 root.mainloop()

源程序及exe可执行程序链接

 链接:https://pan.baidu.com/s/1cptezW 密码:iukp

探究未知是最大乐趣
原文地址:https://www.cnblogs.com/Mufasa/p/8150053.html