用Python编写一个GUI界面,主界面有打开文件,打开文件后点击相关按钮可以对图片分别进行彩色转灰度图,调亮度、直方图均衡化、图像平移、旋转、仿射、插值缩放、透视、加噪、去噪点、Sobel边缘检测
时间: 2023-12-28 14:16:31 浏览: 89
好的,我们可以使用Python的Tkinter模块来实现GUI界面,使用OpenCV库来处理图片。以下是一个简单的示例代码,可以根据需要进行修改和扩展。
```python
import cv2
import numpy as np
import tkinter as tk
from tkinter import filedialog
class ImageProcessor:
def __init__(self):
self.img = None
self.processed_img = None
def open_file(self):
filepath = filedialog.askopenfilename(filetypes=[("Image files", "*.jpg;*.jpeg;*.png")])
if filepath:
self.img = cv2.imread(filepath)
self.processed_img = self.img.copy()
self.show_img(self.processed_img)
def save_file(self):
if self.processed_img is not None:
filepath = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG file", "*.png")])
if filepath:
cv2.imwrite(filepath, self.processed_img)
def show_img(self, img):
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
def gray(self):
if self.img is not None:
self.processed_img = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
self.show_img(self.processed_img)
def brightness(self, value):
if self.img is not None:
hsv = cv2.cvtColor(self.img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
v = np.clip(v + value, 0, 255)
hsv = cv2.merge([h, s, v])
self.processed_img = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
self.show_img(self.processed_img)
def equalize_hist(self):
if self.img is not None:
gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
self.processed_img = cv2.equalizeHist(gray)
self.show_img(self.processed_img)
def translate(self, x, y):
if self.img is not None:
rows, cols = self.img.shape[:2]
M = np.float32([[1, 0, x], [0, 1, y]])
self.processed_img = cv2.warpAffine(self.img, M, (cols, rows))
self.show_img(self.processed_img)
def rotate(self, angle):
if self.img is not None:
rows, cols = self.img.shape[:2]
M = cv2.getRotationMatrix2D((cols/2, rows/2), angle, 1)
self.processed_img = cv2.warpAffine(self.img, M, (cols, rows))
self.show_img(self.processed_img)
def affine(self, pts1, pts2):
if self.img is not None:
rows, cols = self.img.shape[:2]
M = cv2.getAffineTransform(pts1, pts2)
self.processed_img = cv2.warpAffine(self.img, M, (cols, rows))
self.show_img(self.processed_img)
def resize(self, width, height):
if self.img is not None:
self.processed_img = cv2.resize(self.img, (width, height), interpolation=cv2.INTER_LINEAR)
self.show_img(self.processed_img)
def perspective(self, pts1, pts2):
if self.img is not None:
rows, cols = self.img.shape[:2]
M = cv2.getPerspectiveTransform(pts1, pts2)
self.processed_img = cv2.warpPerspective(self.img, M, (cols, rows))
self.show_img(self.processed_img)
def add_noise(self):
if self.img is not None:
rows, cols = self.img.shape[:2]
noise = np.random.normal(0, 50, (rows, cols))
self.processed_img = cv2.add(self.img, noise.astype(np.uint8))
self.show_img(self.processed_img)
def remove_noise(self):
if self.img is not None:
gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
self.processed_img = cv2.medianBlur(gray, 5)
self.show_img(self.processed_img)
def sobel(self):
if self.img is not None:
gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=5)
sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=5)
self.processed_img = cv2.magnitude(sobelx, sobely)
self.show_img(self.processed_img)
class App:
def __init__(self):
self.root = tk.Tk()
self.root.title("Image Processor")
self.processor = ImageProcessor()
self.create_menu()
self.create_toolbar()
self.create_canvas()
self.create_buttons()
self.root.mainloop()
def create_menu(self):
menubar = tk.Menu(self.root)
filemenu = tk.Menu(menubar, tearoff=0)
filemenu.add_command(label="Open", command=self.processor.open_file)
filemenu.add_command(label="Save", command=self.processor.save_file)
filemenu.add_separator()
filemenu.add_command(label="Exit", command=self.root.quit)
menubar.add_cascade(label="File", menu=filemenu)
self.root.config(menu=menubar)
def create_toolbar(self):
toolbar = tk.Frame(self.root)
toolbar.pack(side="top", fill="x")
gray_button = tk.Button(toolbar, text="Gray", command=self.processor.gray)
gray_button.pack(side="left")
brightness_scale = tk.Scale(toolbar, from_=-255, to=255, orient="horizontal")
brightness_scale.pack(side="left")
brightness_button = tk.Button(toolbar, text="Brightness", command=lambda: self.processor.brightness(brightness_scale.get()))
brightness_button.pack(side="left")
equalize_hist_button = tk.Button(toolbar, text="Equalize Hist", command=self.processor.equalize_hist)
equalize_hist_button.pack(side="left")
toolbar.add_separator()
translate_x_scale = tk.Scale(toolbar, from_=-100, to=100, orient="horizontal")
translate_x_scale.pack(side="left")
translate_y_scale = tk.Scale(toolbar, from_=-100, to=100, orient="horizontal")
translate_y_scale.pack(side="left")
translate_button = tk.Button(toolbar, text="Translate", command=lambda: self.processor.translate(translate_x_scale.get(), translate_y_scale.get()))
translate_button.pack(side="left")
rotate_scale = tk.Scale(toolbar, from_=-180, to=180, orient="horizontal")
rotate_scale.pack(side="left")
rotate_button = tk.Button(toolbar, text="Rotate", command=lambda: self.processor.rotate(rotate_scale.get()))
rotate_button.pack(side="left")
affine_button = tk.Button(toolbar, text="Affine", command=lambda: self.processor.affine(pts1, pts2))
affine_button.pack(side="left")
toolbar.add_separator()
resize_width_scale = tk.Scale(toolbar, from_=50, to=500, orient="horizontal")
resize_width_scale.pack(side="left")
resize_height_scale = tk.Scale(toolbar, from_=50, to=500, orient="horizontal")
resize_height_scale.pack(side="left")
resize_button = tk.Button(toolbar, text="Resize", command=lambda: self.processor.resize(resize_width_scale.get(), resize_height_scale.get()))
resize_button.pack(side="left")
perspective_button = tk.Button(toolbar, text="Perspective", command=lambda: self.processor.perspective(pts1, pts2))
perspective_button.pack(side="left")
toolbar.add_separator()
add_noise_button = tk.Button(toolbar, text="Add Noise", command=self.processor.add_noise)
add_noise_button.pack(side="left")
remove_noise_button = tk.Button(toolbar, text="Remove Noise", command=self.processor.remove_noise)
remove_noise_button.pack(side="left")
sobel_button = tk.Button(toolbar, text="Sobel", command=self.processor.sobel)
sobel_button.pack(side="left")
def create_canvas(self):
self.canvas = tk.Canvas(self.root, width=800, height=600)
self.canvas.pack(side="left", fill="both", expand=True)
self.canvas.bind("<Button-1>", self.on_canvas_click)
self.canvas.bind("<B1-Motion>", self.on_canvas_drag)
self.canvas.bind("<ButtonRelease-1>", self.on_canvas_release)
self.canvas.bind("<Configure>", self.on_canvas_resize)
def create_buttons(self):
self.reset_button = tk.Button(self.root, text="Reset", command=self.reset_canvas)
self.reset_button.pack(side="bottom")
def reset_canvas(self):
self.canvas.delete("all")
self.pts1 = []
self.pts2 = []
def on_canvas_click(self, event):
x, y = self.canvas.canvasx(event.x), self.canvas.canvasy(event.y)
self.canvas.create_oval(x-5, y-5, x+5, y+5, fill="red")
if len(self.pts1) < 4:
self.pts1.append((x, y))
elif len(self.pts2) < 4:
self.pts2.append((x, y))
def on_canvas_drag(self, event):
if len(self.pts1) < 4 and len(self.pts2) < 4:
x, y = self.canvas.canvasx(event.x), self.canvas.canvasy(event.y)
self.canvas.create_oval(x-5, y-5, x+5, y+5, fill="red")
if len(self.pts1) < 4:
self.pts1.append((x, y))
elif len(self.pts2) < 4:
self.pts2.append((x, y))
def on_canvas_release(self, event):
if len(self.pts1) == 4 and len(self.pts2) == 4:
self.canvas.create_polygon(self.pts1, outline="green", fill="", width=2)
self.canvas.create_polygon(self.pts2, outline="blue", fill="", width=2)
def on_canvas_resize(self, event):
self.canvas.config(scrollregion=self.canvas.bbox("all"))
if __name__ == "__main__":
app = App()
```
在代码中,我们定义了一个ImageProcessor类来处理图像,包括打开文件、保存文件、灰度化、调亮度、直方图均衡化、图像平移、旋转、仿射、插值缩放、透视、加噪、去噪点、Sobel边缘检测等功能。然后我们定义了一个App类来实现GUI界面,包括菜单、工具栏、画布和按钮等组件,并且将ImageProcessor类的方法与这些组件进行绑定。在画布上,我们可以用鼠标左键来选择四个点,然后点击Affine或Perspective按钮来进行仿射或透视变换。
注意:在Windows系统中,使用OpenCV库显示图像时需要调用cv2.waitKey(0)函数来等待用户按下键盘,否则图像会无法显示。在其他系统中,可能需要调用cv2.imshow()函数来显示图像。
阅读全文