基于python+pyqt+深度学习实现图像转素描【附部分源码】


前言

本文主要实现图像转素描,支持相机取图或者载入图像取图
环境配置:
python3.6 64位
paddlepaddle2.3.1
chainer
7.8.1
cupy-cuda==7.8
halcon12.0
visualstudio code


视频演示

基于pyqt+深度学习,实现图像转素描并得到一系列坐标点


一、ui配置

本文的UI配置因为比较简单,因此基本是纯代码写界面
本工程ui配置的文件如下:
在这里插入图片描述


1.left_button.py源码

首先左边侧边栏按钮代码:

import os
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *

class PyPushButton(QPushButton):
    def __init__(self, text = "", height = 40, minimum_width = 50, text_padding = 55,icon_path = "",is_active = False,
        text_color = "#c3ccdf", icon_color = "#c3ccdf", btn_color = "#44475a", btn_hover = "#4f5368", btn_pressed = "#282a36"
    ):
        super().__init__()

        self.setText(text)
        self.setMaximumHeight(height)
        self.setMinimumHeight(height)
        self.setCursor(Qt.PointingHandCursor)

        self.minimum_width = minimum_width
        self.text_padding = text_padding
        self.text_color = text_color
        self.icon_path = icon_path
        self.icon_color = icon_color
        self.btn_color = btn_color
        self.btn_hover = btn_hover
        self.btn_pressed = btn_pressed
        self.is_active = is_active

        self.set_style(
            text_padding = self.text_padding,
            text_color = self.text_color,
            btn_color = self.btn_color,
            btn_hover = self.btn_hover,
            btn_pressed = self.btn_pressed,
            is_active = self.is_active
        )

    def set_style(
        self,
        text_padding = 55,
        text_color = "#c3ccdf",
        btn_color = "#44475a",
        btn_hover = "#4f5368",
        btn_pressed = "#282a36",
        is_active = False
    ):
        style = f"""
        QPushButton {{
            color: {text_color};
            background-color: {btn_color};
            padding-left: {text_padding}px;
            text-align: left;
            border: none;
        }}
        QPushButton:hover {{
            background-color: {btn_hover};
        }}
        QPushButton:pressed {{
            background-color: {btn_pressed};
        }}
        """

        active_style = f"""
        QPushButton {{
            background-color: {btn_hover};
            border-right: 5px solid #282a36;
        }}
        """
        if not is_active:
            self.setStyleSheet(style)
        else:
            self.setStyleSheet(style + active_style)

    def set_active(self, is_active_menu):
        self.set_style(
            text_padding = self.text_padding,
            text_color = self.text_color,
            btn_color = self.btn_color,
            btn_hover = self.btn_hover,
            btn_pressed = self.btn_pressed,
            is_active = is_active_menu
        )

    def paintEvent(self, event):
        QPushButton.paintEvent(self, event)
        qp = QPainter()
        qp.begin(self)
        qp.setRenderHint(QPainter.Antialiasing)
        qp.setPen(Qt.NoPen)
        rect = QRect(0,0, self.minimum_width, self.height())
        self.draw_icon(qp, self.icon_path, rect, self.icon_color)
        qp.end()

    def draw_icon(self, qp, image, rect, color):
        app_path = os.path.abspath(os.getcwd())
        icon_path = os.path.normpath(image)

        icon = QPixmap(icon_path)
        painter = QPainter(icon)
        painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
        painter.fillRect(icon.rect(), color)
        qp.drawPixmap(
            (rect.width() - icon.width()) / 2,
            (rect.height() - icon.height()) / 2,
            icon
        )
        painter.end()

2.switch_btn.py源码


from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *

class SwitchButton(QWidget):
    #信号
    checkedChanged = Signal (bool)
    def __init__(self,parent=None,width=60,height=20):
        super(SwitchButton, self).__init__(parent)

        self.checked = False
        self.bgColorOff = QColor(255, 255, 255)
        self.bgColorOn = QColor(0, 0, 0)

        self.sliderColorOff = QColor(100, 100, 100)
        self.sliderColorOn = QColor(100, 184, 255)

        self.textColorOff = QColor(143, 143, 143)
        self.textColorOn = QColor(255, 255, 255)

        self.textOff = "OFF"
        self.textOn = "ON"

        self.space = 2
        self.rectRadius = 5

        self.step = self.width() / 50
        self.startX = 0
        self.endX = 0

        self.timer = QTimer(self)  # 初始化一个定时器
        self.timer.timeout.connect(self.updateValue)  # 计时结束调用operate()方法

        #self.timer.start(5)  # 设置计时间隔并启动

        self.setFont(QFont("Microsoft Yahei", 10))

        #self.resize(55,22)

        self.setMinimumWidth(width)
        self.setMaximumWidth(width)
        self.setMinimumHeight(height)
        self.setMaximumHeight(height)

    def updateValue(self):
        if self.checked:
            if self.startX < self.endX:
                self.startX = self.startX + self.step
            else:
                self.startX = self.endX
                self.timer.stop()
        else:
            if self.startX  > self.endX:
                self.startX = self.startX - self.step
            else:
                self.startX = self.endX
                self.timer.stop()

        self.update()


    def mousePressEvent(self,event):
        self.checked = not self.checked
        #发射信号
        self.checkedChanged.emit(self.checked)

        # 每次移动的步长为宽度的50分之一
        self.step = self.width() / 50
        #状态切换改变后自动计算终点坐标
        if self.checked:
            self.endX = self.width() - self.height()
        else:
            self.endX = 0
        self.timer.start(5)

    def paintEvent(self, evt):
        #绘制准备工作, 启用反锯齿
            painter = QPainter()



            painter.begin(self)

            painter.setRenderHint(QPainter.Antialiasing)


            #绘制背景
            self.drawBg(evt, painter)
            #绘制滑块
            self.drawSlider(evt, painter)
            #绘制文字
            self.drawText(evt, painter)

            painter.end()


    def drawText(self, event, painter):
        painter.save()

        if self.checked:
            painter.setPen(self.textColorOn)
            painter.drawText(0, 0, self.width() / 2 + self.space * 2, self.height(), Qt.AlignCenter, self.textOn)
        else:
            painter.setPen(self.textColorOff)
            painter.drawText(self.width() / 2, 0,self.width() / 2 - self.space, self.height(), Qt.AlignCenter, self.textOff)

        painter.restore()


    def drawBg(self, event, painter):
        painter.save()
        painter.setPen(Qt.NoPen)

        if self.checked:
            painter.setBrush(self.bgColorOn)
        else:
            painter.setBrush(self.bgColorOff)

        rect = QRect(0, 0, self.width(), self.height())
        #半径为高度的一半
        radius = rect.height() / 2
        #圆的宽度为高度
        circleWidth = rect.height()

        path = QPainterPath()
        path.moveTo(radius, rect.left())
        path.arcTo(QRectF(rect.left(), rect.top(), circleWidth, circleWidth), 90, 180)
        path.lineTo(rect.width() - radius, rect.height())
        path.arcTo(QRectF(rect.width() - rect.height(), rect.top(), circleWidth, circleWidth), 270, 180)
        path.lineTo(radius, rect.top())

        painter.drawPath(path)
        painter.restore()

    def drawSlider(self, event, painter):
        painter.save()

        if self.checked:
            painter.setBrush(self.sliderColorOn)
        else:
            painter.setBrush(self.sliderColorOff)

        rect = QRect(0, 0, self.width(), self.height())
        sliderWidth = rect.height() - self.space * 2
        sliderRect = QRect(self.startX + self.space, self.space, sliderWidth, sliderWidth)
        painter.drawEllipse(sliderRect)

        painter.restore()

3.主页面重要代码

if not parent.objectName():
     parent.setObjectName("MainWindow")
 self.img_path = img_path

 parent.resize(1280, 680)
 parent.setMinimumSize(1280, 680)

 #主页frame - 主
 self.central_frame = QFrame()
 self.main_layout = QHBoxLayout(self.central_frame)
 self.main_layout.setContentsMargins(0,0,0,0)
 self.main_layout.setSpacing(0)

 #主页frame - 中间页面
 self.content = QFrame()
 self.content.setStyleSheet("background-color: #282a36")
 self.content_layout = QVBoxLayout(self.content)
 self.content_layout.setContentsMargins(0, 0, 0, 0)
 self.content_layout.setSpacing(0)

 # 主页frame - 上方标题栏
 self.top_bar = QFrame()
 self.top_bar.setMinimumHeight(30)
 self.top_bar.setMaximumHeight(30)
 self.top_bar.setStyleSheet("background-color: #21232d; color: #6272a4")
 self.top_bar_layout = QHBoxLayout(self.top_bar)
 self.top_bar_layout.setContentsMargins(10, 0, 10, 0)

 # 主页frame - 下方状态栏
 self.bottom_bar = QFrame()
 self.bottom_bar.setMinimumHeight(30)
 self.bottom_bar.setMaximumHeight(30)
 self.bottom_bar.setStyleSheet("background-color: #21232d; color: #6272a4")
 self.bottom_bar_layout = QHBoxLayout(self.bottom_bar)
 self.bottom_bar_layout.setContentsMargins(10, 0, 10, 0)

 # 侧边栏-主
 self.left_menu = QFrame()
 self.left_menu.setStyleSheet("background-color: #44475a")
 self.left_menu.setMaximumWidth(50)
 self.left_menu.setMinimumWidth(50)
 self.left_menu_layout = QVBoxLayout(self.left_menu)
 self.left_menu_layout.setContentsMargins(0,0,0,0)
 self.left_menu_layout.setSpacing(0)

 # 侧边栏- 按钮
 self.left_menu_top_frame = QFrame()
 self.left_menu_top_frame.setMinimumHeight(40)
 self.left_menu_top_frame.setObjectName("left_menu_top_frame")
 self.left_menu_top_layout = QVBoxLayout(self.left_menu_top_frame)
 self.left_menu_top_layout.setContentsMargins(0,0,0,0)
 self.left_menu_top_layout.setSpacing(0)

 # 侧边栏- 下方设置
 self.left_menu_bottom_frame = QFrame()
 self.left_menu_bottom_frame.setMinimumHeight(40)
 self.left_menu_bottom_frame.setObjectName("left_menu_bottom_frame")
 self.left_menu_bottom_layout = QVBoxLayout(self.left_menu_bottom_frame)
 self.left_menu_bottom_layout.setContentsMargins(0, 0, 0, 0)
 self.left_menu_bottom_layout.setSpacing(0)

二、界面功能

1.初始化模型

def InitModel(modelPath):
    global ctu_seg, ctu_remark, ctu_draw,LoadModelFinish
    try:
        ctu_seg = Ctu_SegAI(USEGPU='0', image_size=513, Model_Path=modelPath)
    except:
       ctu_seg = None
    try:
        ctu_remark = Ctu_FaceRemark(modelPath)
    except:
        ctu_remark = None
    ctu_draw = Ctu_LineDrawing(USEGPU=-1, image_size=512)
    ctu_draw.LoadModel(modelPath)
    LoadModelFinish=True

2.初始化模型

深度学习模型检测

def DL_Check(check_cut_AI,check_remark):
    global ctu_seg,ctu_draw,ctu_remark,cv_img_show,cv_img_show_o,DLCheckFinish,DLCheckFinish_Camera
    origin_img = cv_img_show_o.copy()
    cv2_img_remark = None
    try:
        if check_cut_AI:
            origin_img = ctu_seg.predict_cut(origin_img)
    except:
        pass
    if ctu_draw is not None:
        origin_img,cv2_img_remark = ctu_draw.predict(origin_img)
    try:
        if check_remark and cv2_img_remark is not None:
            remark = ctu_remark.predict(cv2_img_remark)
            for key,value_face in remark.items():
                origin_img = cv2.rectangle(origin_img, value_face['face'][0],value_face['face'][1], color=(0,0,0), thickness=1)
                for each_point in value_face['point']:
                    cv2.circle(origin_img, each_point, 1, color=(0, 255, 0))
        if cv2_img_remark is not None:
            del cv2_img_remark
    except:
        pass

    cv_img_show = origin_img.copy()
    del origin_img
    DLCheckFinish=True
    DLCheckFinish_Camera=True

3.相机采图

def get_Image(cap):
    global cv_img_show_o,get_image_Flag
    while get_image_Flag:
        try:
            _, cv_img_show_o = cap.read()
            cv2.waitKey(30)
        except:
            pass

4.获取坐标点

def get_result_DL(file_name, Px_list, Py_list,Qx_list,Qy_list, use_HmatFlag,  base_file,chara_split):
    global result_data_list_json,result_data_list_str,DLGetResultFinish
    try:
        result_data_list_json,result_data_list_str = get_result(file_name, Px_list, Py_list,Qx_list,Qy_list, use_HmatFlag,  base_file,chara_split)
    except:
        result_data_list_json = result_data_list_str = ''
    DLGetResultFinish = True

总结

因代码篇幅过长,感兴趣的可以私聊沟通一起

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习的广东仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值