简单Photoshop软件的wxpython+OpenCV实现

一、设计要求

简易PS设计要求

二、原理

1、底片化效果

底片化效果即图像反转,用最大灰度级255减去改点灰度值即可得到。

2、浮雕效果

浮雕效果可通过左下角的像素点灰度值减去右上角的像素点灰度值来实现。

3、灰度增强

灰度增强可以通过很多种方法实现,伽马变换是其中一种。伽马变换通过将图像归一化后,利用np.power()函数对数组求0.4次幂运算,参数可改。

4、高斯平滑

滤波的一种啦,还有中值滤波、均值滤波、K近邻均值滤波器等等。高斯滤波适用于高斯噪声多的图像处理,减小噪声的同时会模糊细节,可以利用OpenCV自带的函数实现;中值滤波适用于椒盐噪声多的图像处理,减小噪声的同时能更好地保持图像细节;K近邻均值滤波器既减小噪声又能保持细节,效果好,但相对运算时间更长。

三、步骤

Step1: 搭建一个基本界面;
Step2: 添加菜单栏等信息;
Step3: 基础功能的实现;
Step4: 测试;
Step5: 通过pyinstaller编译成可执行文件.exe

我的文件夹管理如下:
在这里插入图片描述

四、运行结果

在这里插入图片描述
菜单栏功能:
About——
在这里插入图片描述
Exit——退出

File——弹出文件夹窗口,选择图片
在这里插入图片描述
点击image,选择图片:
在这里插入图片描述
在这里插入图片描述
点击Process功能菜单进行处理:
在这里插入图片描述
底片化效果、浮雕效果如下:
在这里插入图片描述
伽马变换、高斯平滑(磨皮呗)效果如下:
在这里插入图片描述

换lena的图试试
在这里插入图片描述
在这里插入图片描述

五、程序代码

# -*- coding: utf-8 -*-
#-----------------SimplePs.py-------------------
import wx
import os
import cv2 as cv
import sys
import string
import numpy as np

class MainWindow(wx.Frame):
    """We simply derive a new class of Frame."""
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title = title, size = (750, 750))
        #self.CreateStatusBar()    # 创建位于窗口的底部的状态栏
        self.Centre()  # 设置窗口居中
        vbox = wx.BoxSizer(wx.VERTICAL)

        # 设置菜单
        filemenu1 = wx.Menu()

        # wx.ID_ABOUT和wx.ID_EXIT是wxWidgets提供的标准ID
        filemenu1.AppendSeparator()
        menuImage = filemenu1.Append(wx.ID_FILE, "&Image", \
                                    " Open the Image")  # (ID, 项目名称, 状态栏信息)
        menuAbout = filemenu1.Append(wx.ID_ABOUT, "&About", \
            " Information about this program")    # (ID, 项目名称, 状态栏信息)
        filemenu1.AppendSeparator()
        menuExit = filemenu1.Append(wx.ID_EXIT, "&Exit", \
            " Terminate the program")    # (ID, 项目名称, 状态栏信息)

        # 创建菜单栏
        menuBar = wx.MenuBar()
        menuBar.Append(filemenu1, "&File")    # 在菜单栏中添加filemenu菜单
        self.SetMenuBar(menuBar)    # 在frame中添加菜单栏

        filemenu2 = wx.Menu()
        filemenu2.AppendSeparator()
        menuFilm = filemenu2.Append(wx.ID_ANY, "&Filming", \
                                    " Negative effect")  # (ID, 项目名称, 状态栏信息)
        menuRel = filemenu2.Append(wx.ID_ANY, "&Relief", \
                                    " Relief effect")  # (ID, 项目名称, 状态栏信息)
        menuGray = filemenu2.Append(wx.ID_ANY, "&Gray enhancement", \
                                   " Gray enhancement")  # (ID, 项目名称, 状态栏信息)
        menuBlur = filemenu2.Append(wx.ID_ANY,"&Blur",\
                                    "Smoothing")

        menuBar.Append(filemenu2, "&Process")  # 在菜单栏中添加filemenu菜单
        self.SetMenuBar(menuBar)  # 在frame中添加菜单栏

        # 设置events
        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)
        self.Bind(wx.EVT_MENU, self.OnExit, menuExit)
        self.Bind(wx.EVT_MENU, self.OnOpen, menuImage)
        self.Bind(wx.EVT_MENU, self.OnFilm, menuFilm)
        self.Bind(wx.EVT_MENU, self.OnRel, menuRel)
        self.Bind(wx.EVT_MENU, self.OnGray, menuGray)
        self.Bind(wx.EVT_MENU,self.OnBlur,menuBlur)

        self.panel = wx.Panel(parent=self)
        self.Show(True)
        self.FitInside()
        self.bmp = wx.Bitmap('logo/sheep.jpg', wx.BITMAP_TYPE_ANY)
        self.src = wx.StaticBitmap(self.panel, -1, self.bmp)

    def OnAbout(self, e):
        # 创建一个带"OK"按钮的对话框。wx.OK是wxWidgets提供的标准ID
        dlg = wx.MessageDialog(self, "A simple version of Photoshop writed by Jessica.", \
            "About Sample Editor", wx.OK)    # 语法是(self, 内容, 标题, ID)
        dlg.ShowModal()    # 显示对话框
        dlg.Destroy()    # 当结束之后关闭对话框

    def OnExit(self, e):
        self.Close(True)    # 关闭整个frame

    def OnOpen(self, e):
        """ Open a file"""
        self.dirname = 'images/'
        dlg = wx.FileDialog(self, "Choose a file", self.dirname, "", "*.*", wx.FD_OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            self.filename = dlg.GetFilename()
            self.dirname = dlg.GetDirectory()
            self.image = cv.imread(self.dirname+'/'+self.filename)
            imgInfo = self.image.shape
            self.height = imgInfo[0]
            self.width = imgInfo[1]
            self.bmp = wx.Bitmap(self.dirname+'/'+self.filename, wx.BITMAP_TYPE_ANY)
            self.src = wx.StaticBitmap(self.panel, -1, self.bmp)
            hbox = wx.BoxSizer(wx.HORIZONTAL)
            hbox.Add(self.src, proportion=3, flag=wx.CENTER | wx.EXPAND)
            self.panel.SetSizer(hbox)
        dlg.Destroy()

    def OnFilm(self,e):
        '''底片化效果'''
        dist = 255 - self.image
        cv.imshow('Film',dist)


    def OnRel(self,e):
        '''浮雕效果'''
        gray = cv.cvtColor(self.image, cv.COLOR_BGR2GRAY)
        dst = np.zeros((self.height, self.width, 1), np.uint8)
        for i in range(self.height):
            for j in range(self.width - 1):
                grayP0 = int(gray[i, j])
                grapP1 = int(gray[i, j + 1])
                newP = grayP0 - grapP1 + 150
                newP = min(255, newP)
                newP = max(0, newP)
                dst[i, j] = newP
        temp = cv.cvtColor(dst,cv.COLOR_GRAY2BGR)

        cv.imshow('Relief', temp)

    def OnGray(self,e):
        '''灰度增强'''
        fi = self.image / 255.0
        # 伽马变换
        gamma = 0.4
        out = np.power(fi, gamma)
        cv.imshow("Gamma Transform", out)

    def OnBlur(self,e):
        Gauss = cv.GaussianBlur(self.image, (3, 3), 0)  # sigmaX = 0时,标准差大小由高斯核大小自动确定
        cv.imshow('Gaus', Gauss)


app = wx.App(False)
frame = MainWindow(None, title = "SimplePS")
frame.Show()
app.MainLoop()

之后用pyinstaller编译成可执行文件.exe就可以双击运行了。
在这里插入图片描述

六、一些话

    在学着做这个作业的时候,找了很多wxpython的教程,有很多大佬写的博客、一
    些全英的课程,啃了好久,最终还是只能做出来这样的学术垃圾orz。一开始想要
    实现在界面上同时显示处理前和处理后的图像,但我卡在图片格式转换上,最终
    还是没能实现就交作业了,最后以OpenCV的cv.imshow()函数弹出处理后的图像
    结果来实现,有大佬能ddw嘛。害,太菜了。网上对于wxpython的教程好像都比
    较乱而且少,所以就Mark一下,万一有用呢。如有出错,欢迎批评指正。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值