图像边缘检测_pygame实现

2024-05-07

使用python中cv2库实现图像边缘检测 ```python

import pygame
import cv2
import numpy as np
import tkinter as tk
from tkinter import filedialog

pygame.init()

screen = pygame.display.set_mode((200, 210))

filetypes_images = [("Image Files", "*.jpg *.jpeg *.png *.bmp")]
TITLE = "画出边缘"
ICON = pygame.image.load('skd1.png')
font2 = pygame.font.SysFont("SimSun", 25, bold=False)

pygame.display.set_caption(TITLE)
pygame.display.set_icon(ICON)

image_needto_change = None
image_needto_save = None

def choose_image():
    global image_needto_change
    root = tk.Tk()
    root.withdraw()  # 隐藏主窗口,只显示文件对话框
    file_path = filedialog.askopenfilename(filetypes = filetypes_images)
    if file_path:
        print("选定的图片文件路径:", file_path)
    else:
        print("未选择任何文件。")
    root.destroy()  # 关闭Tkinter窗口
    image_needto_change = file_path

def function_save_image():
    root = tk.Tk()
    root.withdraw()

    # 弹出保存文件对话框让用户选择保存位置和文件名
    file_path = filedialog.asksaveasfilename(
        defaultextension = ".png",  # 默认文件扩展名
        filetypes = filetypes_images,  # 支持的文件类型
        title = "保存当前显示的图片"  # 对话框标题
    )
    # 如果用户选择了文件路径,则保存图片
    if file_path:
        try:
            image_needto_save = pygame.image.load(image_needto_save)
            pygame.image.save(image_needto_save, file_path)
            print(f"Image saved successfully at {file_path}")
        except Exception as e:
            print(f"Error saving image: {e}")

def edge_detection():
    global image_needto_change, image_needto_save
    # 读取图像并确保其为彩色模式
    image = cv2.imread(image_needto_change, cv2.IMREAD_COLOR)
    
    # 确保图像成功加载
    if image is None:
        print(f"Error: Could not load image '{image_needto_change}'")
        return

    # 将图像转换为灰度
    image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
    edges = cv2.Canny(image_gray, 100, 200) # 100,200是阈值,根据需要改变
    white_image = np.ones_like(image_gray) * 255
    result = np.where(edges > 0, white_image, image_gray)
    result_rgb = np.dstack((result, result, result))
    
    # 显示图像
    # cv2.imshow('Original Image', image)
    # cv2.imshow('Edges', edges)
    cv2.imshow('画出边缘', result_rgb)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    image_needto_save = image_needto_change

class Button:
    def __init__(self, x, y, width, height, text, action=None):
        self.x, self.y = x, y
        self.width, self.height = width, height
        self.text = text
        self.action = action  # 按钮的回调函数
        self.color = (255, 255, 255)
        self.hover_color = (220, 220, 220)  # 鼠标悬停时的颜色
        self.is_hovered = False
        self.is_pressed = False
        self.clicked_once = False  # 回到初始逻辑,每个按钮一个布尔值

    def draw(self, screen):
        if self.is_pressed:
            color = (180, 180, 180)
        elif self.is_hovered:
            color = self.hover_color
        else:
            color = self.color

        # 绘制按钮的边框
        pygame.draw.rect(screen, (0, 0, 0), pygame.Rect(self.x, self.y, self.width, self.height), 2)

        # 绘制按钮的填充
        pygame.draw.rect(screen, color, pygame.Rect(self.x + 1, self.y + 1, self.width - 2, self.height - 2))

        # 绘制文本
        text_surface = font2.render(self.text, True, (0, 0, 0))
        screen.blit(text_surface, (self.x + (self.width - text_surface.get_width()) // 2,
                                self.y + (self.height - text_surface.get_height()) // 2))

    def update(self, mouse_pos, events):
        button_rect = pygame.Rect(self.x, self.y, self.width, self.height)
        
        # 检查鼠标是否悬停在按钮上
        self.is_hovered = button_rect.collidepoint(mouse_pos)
        
        # 检查是否有鼠标按下事件,并且点击位置位于按钮上
        for event in events:
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                if button_rect.collidepoint(event.pos) and not self.clicked_once and self.action is not None:
                    self.clicked_once = True  # 标记按钮已被点击
                    self.action()  # 执行回调函数
                    return

Button1 = Button(100 - 65, 20, 130, 50, "选择图片", action=choose_image)
Button2 = Button(100 - 65, 200 - 120, 130, 50, "画出边缘", action=edge_detection)
Button3 = Button(100 - 50, 200 - 60, 100, 50, "保存", action=function_save_image)

while True:
    screen.fill((109, 171, 228))

    mouse_pos = pygame.mouse.get_pos()
    events = pygame.event.get()

    buttons = [Button1, Button2, Button3]
    for button in buttons:
        button.draw(screen)

    for button in buttons:
        button.update(mouse_pos, events)
        button.draw(screen)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
        elif event.type == pygame.MOUSEBUTTONUP:  # 在鼠标松开时重置所有按钮的clicked_once状态
            for button in buttons:
                button.clicked_once = False

    pygame.display.update()