专栏首页月小水长wxPython+opencv 打造自己的画图板

wxPython+opencv 打造自己的画图板

去年期末因为项目需要,自己动手写代码制作了一款简单的图片处理工具。其效果图如下:

整个软件的 GUI 采用 wxPython框架,图像处理模块采用 opencv,

主要的功能及实现

从系统任意文件夹加载图片

这个采用tkinter库的filedialog模块很容易实现

    image_path = filedialog.askopenfilename(initialdir=r"..\\", title="select an image whose filename endwiths .jpg/png",filetypes=[ ("JPG", ".jpg"),("PNG", ".png")])

参数一:initialdir是打开文件资源管理器的初始路径,可以不设置

参数二: title是打开的文件资源管理器的最左上方的标题

参数三: filetypes,比如我上面的设置过滤掉了其他非.jpg.png文件

askopenfilename的返回值就是你选择的文件路径

注意文件路径中最好不要有中文,否则即使你选中了图片,这个函数也会返回 None ,当然这个 bug 通过一个 if 判断解决。

图像处理

我主要加了图片涂鸦、图片黑白化、图片裁剪这几个功能,具体效果参考最上面的效果图,实现的话算法+业务逻辑很容易。这里简单描述下怎么实现这三个功能:

图片涂鸦:

核心思路是利用 opencv 在向图片上输出像素点,直观地来说是线,线的大小和颜色都是可以在设置里改变的,但是一旦将图片设置为灰度图之后,线的颜色设置就会失效,一律变成灰色。

图片黑白化:

这里主要用到了二值化操作,当然,这个算法 opencv 已经帮我们实现,我们只需要调用 cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY) 这个函数就能实现图片黑白化,由于从彩色图片转成黑白照片是不可逆的,请谨慎操作。

图片裁剪:

主要依靠 wxPython 的鼠标监听事件和事件分发来实现,操作比较人性化,鼠标左键开始裁剪,右键停止,以左键所在的位置为矩形的左上角顶点,右键所在的位置为矩形的右下角顶点,以此构成的矩形就是裁剪的图片大小,而且裁剪过程会有矩形框大小提示。

其他诸如图片保存就不赘述了。整体而言,算法算是比较简单的算法,但是业务逻辑和其中不少的坑是只有动手后才能深有体会的,这里贴出这部分的主要代码:

def OnImageGrayClicked(self,event):
    if self.isLoaded == True:
        dlg = wx.MessageDialog(self, u"this Operation cannot be undo", u"Warning", wx.YES_NO)
        value = dlg.ShowModal()
        if value == wx.ID_YES:
            self.setImage(cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY))
            self.editMenu.Check(ID_IMAGE_GRAY, True)
            self.image_gray.Enable(False)
        else:
            self.editMenu.Check(ID_IMAGE_GRAY, False)
        dlg.Destroy()
    else:
        wx.MessageDialog(self, u"please make sure you have loaded the image successfully", u"Warning", wx.OK).ShowModal()
        self.editMenu.Check(ID_IMAGE_GRAY, False)

def OnImageDrawClicked(self,event):
    if self.isLoaded == True:
        self.canDraw = not self.canDraw
        if self.canDraw == True:
            self.image_draw.SetItemLabel("disabel drawing on the image")
            self.image_cut.Enable(False)
        else:
            self.image_draw.SetItemLabel("enabel drawing on the image")
            self.image_cut.Enable(True)
        pass
    else:
        wx.MessageDialog(self, u"please make sure you have loaded the image successfully", u"Warning", wx.OK).ShowModal()

def OnImageCutClicked(self,event):
    if self.isLoaded == True:
        self.canCut = not self.canCut
        if self.canCut == True:
            self.image_copy = self.image.copy()
            self.image_cut.SetItemLabel("disabel cutting on the image")
            self.image_draw.Enable(False)
        else:
            self.image_cut.SetItemLabel("enabel cutting on the image")
            self.image_draw.Enable(True)
        return
    else:
        wx.MessageDialog(self, u"please make sure you have loaded the image successfully", u"Warning", wx.OK).ShowModal()
def OnSettingsLineWeightClicked(self,event):
    self.lineWeight = wx.GetNumberFromUser(message="input the line_weight(from 1 to 10)",
                                   prompt="lineWeight", caption="drawer settings",
                                   value=self.lineWeight,
                                   parent=self.bmp, max=, min=)
    print("SLW")
    pass

去掉 opencv 自带的窗口,把图片绑定到 wxPython 框架上

我感觉这部分是最复杂的,需要两个实例,image = cv2.imread()和bitmap = wx.bitmap(),从而搭起一个从opencv到wxPython的桥梁

这里最核心的代码是

def setImage(self,img):
    self.image = img
    img_height, img_width = img.shape[:]
    try:
        image1 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    except:
        image1 = cv2.cvtColor(img,cv2.COLOR_GRAY2RGB)
    finally:
        pic = wx.Bitmap.FromBuffer(img_width, img_height, image1)
    # 显示图片在panel上
    self.bmp.SetBitmap(pic)

关于代码

设计代码的初衷

在实验室接触到了opencv这个库,感觉太强大了,于是想自己做一款功能比较全面的图片编辑软件,但是一个人的力量有限,我写了一个晚上,只写好了框架和图片裁剪图片黑白化图片涂鸦这几个功能,现有代码行数在 300 行左右,可塑性强,需要添加什么功能直接模仿现有函数就 ok,不过可能具体的算法要自己实现,希望以后有小伙伴一起参与进来 。

暂时不考虑开源,不过可以下载exe程序体验,后台回复 画图板 即可获得下载链接

代码更新优化

关于修复闪屏的问题

发现使用 matplotlib 绑定到 wxPython 上再使用 canvas 绘图,比用cv2画图再转成 bitmap 强制刷新到 wxPython 上要好得多,后者容易闪屏。

往期精选 自己动手打造mini型QQ(一):动手实现局域网仿QQ互联 自己动手打造mini型QQ(二):从局域网到互联网的miniQQ Python 获取微信好友地区、性别、签名信息并将结果可视化 500行python代码打造刷脸考勤系统

点击下方好看,或者转发,谢谢资瓷

本文分享自微信公众号 - 月小水长(inspurer),作者:BuyiXiao

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 自己动手打造mini型QQ(一):动手实现局域网仿QQ互联

    这个项目的由来是来自计算机网络课程学习的大作业,基于socket套接字写一个超小型的QQ,晚上8点到12点的奋战,编码工作大致做完了,GUI框架也有了,特此分享...

    月小水长
  • Python 数据可视化实战:使用 PyQt5 和 Echarts 打造股票数据看板

    数据可视化大致可分为两类,一类是 excel、powerBI 这类不需要写代码的,另一类是需要写代码的;而对于 Python 来说,数据可视化框架,我个人觉得大...

    月小水长
  • 500行python代码打造刷脸考勤系统

    “员工刷脸考勤”系统,采用python语言开发,可以通过摄像头添加员工面部信息,这里就涉及到两个具体的个问题,一个是应该以什么样的数据来标识每一个员工的面部信息...

    月小水长
  • 验证码

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    云雀叫了一整天
  • 强化学习FrozenLake求解

    大概情景是湖面结冰不结实、黑色圆圈表示踩到就会跌落、白色圆圈表示目标、红色小圆圈代表agent

    万木逢春
  • python爬虫之验证码识别

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    云雀叫了一整天
  • python中HashMap的一个实现

    py3study
  • pyqt4实现tab界面切换

    de ># -*- coding: utf-8 -*- from PyQt4.QtGui import * from PyQt4.QtCore import...

    marsggbo
  • 用python实现漂亮的烟花demo

    py3study
  • 从PEP-8学习Python编码风格

    Python3中应当总是使用UTF-8。(Python2使用ASCII。)在使用了规定编码后不需要再声明文件编码。

    py3study

扫码关注云+社区

领取腾讯云代金券