本篇博客将介绍如何使用wxPython模块和OpenCV库来实现对图像进行灰度化、二值化、伽马校正、色彩空间转换和图像反转这5种效果的合并程序。程序可以通过wxPython提供的GUI界面来选择图片路径和效果类型,程序会将处理后的图像保存到指定路径并打开。
步骤一:安装wxPython和OpenCV库
首先需要安装wxPython和OpenCV库。可以使用pip命令来安装:
pip install wxPython
pip install opencv-contrib-python
步骤二:创建GUI界面
我们可以使用wxPython来创建一个GUI界面,包括一个选择文件路径的按钮、一个下拉框来选择效果类型、一个处理按钮和一个输出路径文本框。代码如下:
import cv2
import wx
import os
class ImageTransformer(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='Image Transformer')
self.panel = wx.Panel(self)
self.image_path = None
self.effect_choice = None
self.create_widgets()
self.Show()
def create_widgets(self):
# 创建选择文件按钮
self.file_picker = wx.FilePickerCtrl(self.panel, wildcard='Image files (*.jpg;*.jpeg;*.png)|*.jpg;*.jpeg;*.png')
self.file_picker.Bind(wx.EVT_FILEPICKER_CHANGED, self.on_file_pick)
# 创建效果选择下拉框
self.effects = ['Oil Painting', 'Watercolor', 'Sketch', 'Cartoon', 'Dreamy']
self.effect_choice = wx.Choice(self.panel, choices=self.effects)
# 创建转换按钮
self.transform_button = wx.Button(self.panel, label='Transform', size=(100, 30))
self.transform_button.Bind(wx.EVT_BUTTON, self.on_transform)
# 创建状态栏
self.status_bar = self.CreateStatusBar()
# 创建布局
main_sizer = wx.BoxSizer(wx.VERTICAL)
main_sizer.Add(self.file_picker, 0, wx.ALL|wx.EXPAND, 5)
main_sizer.Add(self.effect_choice, 0, wx.ALL|wx.CENTER, 5)
main_sizer.Add(self.transform_button, 0, wx.ALL|wx.CENTER, 5)
self.panel.SetSizer(main_sizer)
def on_file_pick(self, event):
# 获取选择的文件路径
self.image_path = event.GetPath()
self.status_bar.SetStatusText(f'Selected file: {self.image_path}')
这是一个基于wxPython库的图像转换应用程序的代码。它创建了一个名为"Image Transformer"的窗口,并提供了以下功能:
-
创建选择文件按钮:使用
wx.FilePickerCtrl
创建一个按钮,允许用户选择图像文件。通过设置wildcard
参数,只显示特定类型的图像文件(.jpg、.jpeg、.png)。 -
创建效果选择下拉框:使用
wx.Choice
创建一个下拉框,供用户选择要应用的图像效果。下拉框中提供了"Oil Painting"、"Watercolor"、"Sketch"、"Cartoon"和"Dreamy"这些选项。 -
创建转换按钮:使用
wx.Button
创建一个按钮,标有"Transform",用于触发图像转换操作。 -
创建状态栏:使用
CreateStatusBar
方法创建一个状态栏,用于显示当前选择的图像文件路径。 -
创建布局:使用
wx.BoxSizer
创建一个垂直布局管理器,将上述组件添加到主面板中,并设置相应的边距和对齐方式。 -
on_file_pick
方法:当用户选择图像文件时,该方法将获取所选文件的路径,并在状态栏中显示该路径。
步骤三:实现图像处理
在OnProcess函数中,我们需要实现图像的处理。我们可以使用OpenCV库来实现灰度化、二值化、伽马校正、色彩空间转换和图像反转这5种效果。代码如下:
import cv2
import wx
import os
class ImageTransformer(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='Image Transformer')
self.panel = wx.Panel(self)
self.image_path = None
self.effect_choice = None
self.create_widgets()
self.Show()
def create_widgets(self):
# 创建选择文件按钮
self.file_picker = wx.FilePickerCtrl(self.panel, wildcard='Image files (*.jpg;*.jpeg;*.png)|*.jpg;*.jpeg;*.png')
self.file_picker.Bind(wx.EVT_FILEPICKER_CHANGED, self.on_file_pick)
# 创建效果选择下拉框
self.effects = ['Oil Painting', 'Watercolor', 'Sketch', 'Cartoon', 'Dreamy']
self.effect_choice = wx.Choice(self.panel, choices=self.effects)
# 创建转换按钮
self.transform_button = wx.Button(self.panel, label='Transform', size=(100, 30))
self.transform_button.Bind(wx.EVT_BUTTON, self.on_transform)
# 创建状态栏
self.status_bar = self.CreateStatusBar()
# 创建布局
main_sizer = wx.BoxSizer(wx.VERTICAL)
main_sizer.Add(self.file_picker, 0, wx.ALL|wx.EXPAND, 5)
main_sizer.Add(self.effect_choice, 0, wx.ALL|wx.CENTER, 5)
main_sizer.Add(self.transform_button, 0, wx.ALL|wx.CENTER, 5)
self.panel.SetSizer(main_sizer)
def on_file_pick(self, event):
# 获取选择的文件路径
self.image_path = event.GetPath()
self.status_bar.SetStatusText(f'Selected file: {self.image_path}')
def on_transform(self, event):
# 获取选择的效果
effect = self.effect_choice.GetStringSelection()
# 应用所选效果
if effect == 'Oil Painting':
result = self.apply_oil_painting_effect()
elif effect == 'Watercolor':
result = self.apply_watercolor_effect()
elif effect == 'Sketch':
result = self.apply_sketch_effect()
elif effect == 'Cartoon':
result = self.apply_cartoon_effect()
elif effect == 'Dreamy':
result = self.apply_dreamy_effect()
else:
self.status_bar.SetStatusText('Please select an effect')
return
# 获取原始文件名和扩展名
filename, ext = os.path.splitext(self.image_path)
# 拼接输出文件名
output_path = f'{filename}_{effect}{ext}'
# 保存结果
cv2.imwrite(output_path, result)
# 打开转换后的图片
os.startfile(output_path)
# def apply_oil_painting_effect(self, brush_radius=6, intensity=1):
# # 加载图像
# image = cv2.imread(self.image_path)
# # 应用油画效果
# oil_painting = cv2.xphoto.createOilPaintingFilter(brush_radius, intensity)
# result = oil_painting.apply(image)
# return result
def apply_oil_painting_effect(self, brush_radius=6, intensity=1):
# 加载图像
image = cv2.imread(self.image_path)
# 转换为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 应用中值模糊
gray = cv2.medianBlur(gray, brush_radius + 1)
# 增强对比度
gray = cv2.addWeighted(gray, 2.5, cv2.GaussianBlur(gray, (0, 0), brush_radius / 30), -0.5, 0)
# 将灰度图像转换为彩色图像
result = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
return result
def apply_watercolor_effect(self, sigma_s=60, sigma_r=0.4):
# 加载图像
image = cv2.imread(self.image_path)
# 应用水彩效果
watercolor = cv2.stylization(image, sigma_s=sigma_s, sigma_r=sigma_r)
result = cv2.cvtColor(watercolor, cv2.COLOR_BGR2RGB)
return result
def apply_sketch_effect(self):
# 加载图像
image = cv2.imread(self.image_path)
# 将图像转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 将灰度图像转换为边缘图像
edges = cv2.Canny(gray_image, 30, 100)
# 将边缘图像转换为彩色图像
sketch = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)
return sketch
def apply_cartoon_effect(self):
# 加载图像
image = cv2.imread(self.image_path)
# 将图像转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 应用均值迁移滤波器以平滑图像
filtered = cv2.pyrMeanShiftFiltering(image, 20, 50)
#将平滑图像转换为灰度图像
gray_filtered = cv2.cvtColor(filtered, cv2.COLOR_BGR2GRAY)
# 应用边缘检测
edges = cv2.adaptiveThreshold(gray_filtered, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 9, 5)
# 应用双边滤波器以增强边缘
colored_edges = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)
cartoon = cv2.bitwise_and(filtered, colored_edges)
return cartoon
def apply_dreamy_effect(self, blend_alpha=0.5):
# 加载图像
image = cv2.imread(self.image_path)
# 将图像转换为浮点数格式
image = image.astype(float) / 255.0
# 应用高斯模糊以减少噪声
blurred = cv2.GaussianBlur(image, (7, 7), 0)
# 将图像与模糊图像混合
dreamy = cv2.addWeighted(image, 1 - blend_alpha, blurred, blend_alpha, 0)
return dreamy
if __name__ == '__main__':
app = wx.App()
transformer = ImageTransformer()
app.MainLoop()
这是一个Python类中的几个方法,用于应用不同的图像效果。每个方法都需要一个指向图像文件的路径作为输入,并返回处理后的图像。
-
apply_oil_painting_effect
方法:该方法使用OpenCV库将输入图像转换为灰度图像,然后应用中值模糊和增强对比度的技术,最后将灰度图像转换为彩色图像,并返回结果。 -
apply_watercolor_effect
方法:该方法使用OpenCV库实现水彩效果,通过调节参数sigma_s
和sigma_r
来控制效果的强度,并将结果转换为RGB格式并返回。 -
apply_sketch_effect
方法:该方法将输入图像转换为灰度图像,然后使用Canny算法将其转换为边缘图像,最后将边缘图像转换为彩色图像并返回。 -
apply_cartoon_effect
方法:该方法将输入图像转换为灰度图像,然后通过应用均值迁移滤波器以平滑图像,并使用自适应阈值进行边缘检测,最后使用双边滤波器增强边缘并返回结果。 -
apply_dreamy_effect
方法:该方法将输入图像转换为浮点数格式,然后使用高斯模糊以减少噪声,并将图像与模糊图像混合,最后返回结果。混合系数由参数blend_alpha
控制。
到此,我们的程序就完成了。您可以将上述代码保存到一个名为photoconvert5type.py的文件中,并运行它来测试程序。当程序运行时,您可以使用GUI界面中的打开按钮来选择一个图像文件,然后选择一个效果类型,最后点击处理按钮。程序将会创建一个新的文件,保存处理后的图像,并打开它。
总结
本篇博客介绍了如何使用wxPython模块和OpenCV库来实现对图像进行灰度化、二值化、伽马校正、色彩空间转换和图像反转这5种效果的合并程序。程序可以通过wxPython提供的GUI界面来选择图片路径和效果类型,程序会将处理后的图像保存到指定路径并打开。如果您对这个程序感兴趣,可以尝试添加一些额外的效果,例如边缘检测或图像平滑。