一、设计要求
二、原理
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一下,万一有用呢。如有出错,欢迎批评指正。