Python+QT美颜工具源码

 程序示例精选

Python+QT美颜工具源码

如需安装运行环境或远程调试,见文章底部微信名片,由专业技术人员远程协助!

前言

这篇博客针对《Python+QT美颜》编写代码,功能包括了亮度,磨皮,风格化,铅笔化等多种特征修饰,代码整洁,规则,易读。 学习与应用推荐首选。


文章目录

        一、所需工具软件

        二、使用步骤

                1. 引入库

                2. 显示图片

                3. 美颜特征函数定义

                4. 运行结果

         三在线协助


一、所需工具软件

          1. Python3.6以上

          2. Pycharm代码编辑器

          3. PyQt, OpenCV库

二、使用步骤

1.引入库

代码如下(示例):

from PyQt5 import Qt
from PyQt5 import QtCore,QtWidgets,QtGui
import sys
import PyQt5
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QFileDialog, QGraphicsRectItem, QGraphicsScene
from PyQt5.QtCore import QSize
import cv2
import numpy as np
from matplotlib import pyplot as plt

2.显示图片

代码如下(示例):

# 显示图片
    def show_image(self):
        img_cv = cv2.cvtColor(self.current_img, cv2.COLOR_RGB2BGR)
        img_width, img_height, a = img_cv.shape
        ratio_img = img_width/img_height
        ratio_scene = self.ui.graphicsView.width()/self.ui.graphicsView.height()
        if ratio_img > ratio_scene:
            width = int(self.ui.graphicsView.width())
            height = int(self.ui.graphicsView.width() / ratio_img)
        else:
            width = int(self.ui.graphicsView.height() * ratio_img)
            height = int(self.ui.graphicsView.height())
        img_resize = cv2.resize(img_cv, (height-5, width-5), interpolation=cv2.INTER_AREA)
        h, w, c = img_resize.shape
        bytesPerLine = w * 3
        qimg = QImage(img_resize.data, w, h, bytesPerLine, QImage.Format_RGB888)
        self.scene = QGraphicsScene()
        pix = QPixmap(qimg)
        self.scene.addPixmap(pix)
        self.ui.graphicsView.setScene(self.scene)

3.美颜特征函数定义:

代码如下(示例):

# 饱和度
    def change_saturation(self):
        if self.raw_image is None:
            return 0

        value = self.ui.horizontalSlider.value()
        img_hsv = cv2.cvtColor(self.current_img, cv2.COLOR_BGR2HLS)
        if value > 2:
            img_hsv[:, :, 2] = np.log(img_hsv[:, :, 2] /255* (value - 1)+1) / np.log(value + 1) * 255
        if value < 0:
            img_hsv[:, :, 2] = np.uint8(img_hsv[:, :, 2] / np.log(- value + np.e))
        self.current_img = cv2.cvtColor(img_hsv, cv2.COLOR_HLS2BGR)

# 明度调节
    def change_darker(self):
        if self.raw_image is None:
            return 0
        value = self.ui.horizontalSlider_4.value()
        img_hsv = cv2.cvtColor(self.current_img, cv2.COLOR_BGR2HLS)
        if value > 3:
            img_hsv[:, :, 1] = np.log(img_hsv[:, :, 1] /255* (value - 1)+1) / np.log(value + 1) * 255
        if value < 0:
            img_hsv[:, :, 1] = np.uint8(img_hsv[:, :, 1] / np.log(- value + np.e))
        self.last_image = self.current_img
        self.current_img = cv2.cvtColor(img_hsv, cv2.COLOR_HLS2BGR)

# 人脸识别
    def detect_face(self):
        img = self.raw_image
        face_cascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')

        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, 1.3, 5)
        return faces

# 皮肤识别
    def detect_skin(self):
        img = self.raw_image
        rows, cols, channals = img.shape
        for r in range(rows):
            for c in range(cols):
                B = img.item(r, c, 0)
                G = img.item(r, c, 1)
                R = img.item(r, c, 2)
                if (abs(R - G) > 15) and (R > G) and (R > B):
                    if (R > 95) and (G > 40) and (B > 20) and (max(R, G, B) - min(R, G, B) > 15):
                        self.imgskin[r, c] = (1, 1, 1)
                    elif (R > 220) and (G > 210) and (B > 170):
                        self.imgskin[r, c] = (1, 1, 1)

# 皮肤磨皮(value1精细度,value2程度)
    def dermabrasion(self, value1=3, value2=2):
        value1 = self.ui.horizontalSlider_14.value()
        value2 = 11 - self.ui.horizontalSlider_11.value()
        if value1 == 0 and value2 == 0:
            return 0
        if value2 == 0:
            value2 = 2
        if value1 == 0:
            value1 = 3
        img = self.current_img
        dx = value1 * 5
        fc = value1 * 12.5
        p = 50
        temp1 = cv2.bilateralFilter(img, dx, fc, fc)
        temp2 = (temp1 - img + 128)
        temp3 = cv2.GaussianBlur(temp2, (2 * value2 - 1, 2 * value2 - 1), 0, 0)
        temp4 = img + 2 * temp3 - 255
        dst = np.uint8(img * ((100 - p) / 100) + temp4 * (p / 100))


        imgskin_c = np.uint8(-(self.imgskin - 1))

        dst = np.uint8(dst * self.imgskin + img * imgskin_c)
        self.current_img = dst

# 美白算法(皮肤识别)
    def whitening_skin(self, value=30):
        # value = 30
        value = self.ui.horizontalSlider_13.value()
        img = self.current_img
        imgw = np.zeros(img.shape, dtype='uint8')
        imgw = img.copy()
        midtones_add = np.zeros(256)

        for i in range(256):
            midtones_add[i] = 0.667 * (1 - ((i - 127.0) / 127) * ((i - 127.0) / 127))

        lookup = np.zeros(256, dtype="uint8")

        for i in range(256):
            red = i
            red += np.uint8(value * midtones_add[red])
            red = max(0, min(0xff, red))
            lookup[i] = np.uint8(red)



        rows, cols, channals = img.shape
        for r in range(rows):
            for c in range(cols):

                if self.imgskin[r, c, 0] == 1:
                    imgw[r, c, 0] = lookup[imgw[r, c, 0]]
                    imgw[r, c, 1] = lookup[imgw[r, c, 1]]
                    imgw[r, c, 2] = lookup[imgw[r, c, 2]]
        self.current_img = imgw

# 美白算法(人脸识别)
    def whitening_face(self, value=30):
        # value = 30
        value = self.ui.horizontalSlider_8.value()
        img = self.current_img
        imgw = np.zeros(img.shape, dtype='uint8')
        imgw = img.copy()
        midtones_add = np.zeros(256)

        for i in range(256):
            midtones_add[i] = 0.667 * (1 - ((i - 127.0) / 127) * ((i - 127.0) / 127))

        lookup = np.zeros(256, dtype="uint8")

        for i in range(256):
            red = i
            red += np.uint8(value * midtones_add[red])
            red = max(0, min(0xff, red))
            lookup[i] = np.uint8(red)

        # faces可全局变量
        faces = self.faces

        if faces == ():
            rows, cols, channals = img.shape
            for r in range(rows):
                for c in range(cols):
                    imgw[r, c, 0] = lookup[imgw[r, c, 0]]
                    imgw[r, c, 1] = lookup[imgw[r, c, 1]]
                    imgw[r, c, 2] = lookup[imgw[r, c, 2]]

        else:
            x, y, w, h = faces[0]
            rows, cols, channals = img.shape
            x = max(x - (w * np.sqrt(2) - w) / 2, 0)
            y = max(y - (h * np.sqrt(2) - h) / 2, 0)
            w = w * np.sqrt(2)
            h = h * np.sqrt(2)
            rows = min(rows, y + h)
            cols = min(cols, x + w)
            for r in range(int(y), int(rows)):
                for c in range(int(x), int(cols)):
                    imgw[r, c, 0] = lookup[imgw[r, c, 0]]
                    imgw[r, c, 1] = lookup[imgw[r, c, 1]]
                    imgw[r, c, 2] = lookup[imgw[r, c, 2]]

            processWidth = int(max(min(rows - y, cols - 1) / 8, 2))
            for i in range(1, processWidth):
                alpha = (i - 1) / processWidth
                for r in range(int(y), int(rows)):
                    imgw[r, int(x) + i - 1] = np.uint8(
                        imgw[r, int(x) + i - 1] * alpha + img[r, int(x) + i - 1] * (1 - alpha))
                    imgw[r, int(cols) - i] = np.uint8(
                        imgw[r, int(cols) - i] * alpha + img[r, int(cols) - i] * (1 - alpha))
                for c in range(int(x) + processWidth, int(cols) - processWidth):
                    imgw[int(y) + i - 1, c] = np.uint8(
                        imgw[int(y) + i - 1, c] * alpha + img[int(y) + i - 1, c] * (1 - alpha))
                    imgw[int(rows) - i, c] = np.uint8(
                        imgw[int(rows) - i, c] * alpha + img[int(rows) - i, c] * (1 - alpha))
        self.current_img = imgw

# Gamma矫正
    def gamma_trans(self):
        gamma = (self.ui.horizontalSlider_5.value() + 10) / 10
        img = self.current_img
        gamma_table = [np.power(x / 255.0, gamma) * 255.0 for x in range(256)]
        gamma_table = np.round(np.array(gamma_table)).astype(np.uint8)
        self.current_img = cv2.LUT(img, gamma_table)
        self.show_image()
        self.show_histogram()

# 响应滑动条的变化
    def slider_change(self):
        if self.raw_image is None:
            return 0

        self.current_img = self.raw_image

        # 伽马变换
        if self.ui.horizontalSlider_5.value() != 0:
            self.gamma_trans()

        # 饱和度
        if self.ui.horizontalSlider.value() != 0:
            self.change_saturation()

        if self.ui.horizontalSlider_2.value() != 0:
            pass

        # 边缘保持
        if self.ui.horizontalSlider_3.value() != 0:
            self.edge_preserve()

        # 亮度
        if self.ui.horizontalSlider_4.value() != 0:
            self.change_darker()

        # 美白(人脸识别)
        if self.ui.horizontalSlider_8.value() != 0:
            self.whitening_face()

        # 美白(皮肤识别)
        if self.ui.horizontalSlider_13.value() != 0:
            self.whitening_skin()


        # 风格化
        if self.ui.horizontalSlider_2.value() != 0:
            self.stylize()

        # 细节增强
        if self.ui.horizontalSlider_6.value() != 0:
            self.detail_enhance()

        # 铅笔画
        if self.ui.horizontalSlider_12.value() != 0:
            self.pencil_color()
        self.show_image()


# 计算人脸识别和皮肤识别的基本参数
    def calculate(self):
        if self.raw_image is None:
            return 0
        if self.calculated is False:
            self.faces = self.detect_face()
            if self.faces != ():
                self.detect_skin()
            self.calculated = True

# 怀旧滤镜
    def reminiscene(self):
        if self.raw_image is None:
            return 0
        if self.ui.horizontalSlider_10.value() == 0:
            self.current_img = self.raw_image
            self.show_image()
            return 0
        img = self.raw_image.copy()
        rows, cols, channals = img.shape
        for r in range(rows):
            for c in range(cols):
                B = img.item(r, c, 0)
                G = img.item(r, c, 1)
                R = img.item(r, c, 2)
                img[r, c, 0] = np.uint8(min(max(0.272 * R + 0.534 * G + 0.131 * B, 0), 255))
                img[r, c, 1] = np.uint8(min(max(0.349 * R + 0.686 * G + 0.168 * B, 0), 255))
                img[r, c, 2] = np.uint8(min(max(0.393 * R + 0.769 * G + 0.189 * B, 0), 255))
        self.current_img = img
        self.show_image()

# 木刻滤镜
    def woodcut(self):
        if self.raw_image is None:
            return 0
        if self.ui.horizontalSlider_9.value() == 0:
            # self.current_img = self.raw_image
            self.show_image()
            return 0
        self.gray_image = cv2.cvtColor(self.raw_image, cv2.COLOR_BGR2GRAY)
        gray = self.gray_image
        value = 70 + self.ui.horizontalSlider_9.value()
        rows, cols = gray.shape
        for r in range(rows):
            for c in range(cols):
                if gray[r, c] > value:
                    gray[r, c] = 255
                else:
                    gray[r, c] = 0
        self.gray_image = gray
        self.show_grayimage()

# 铅笔画(灰度)
    def pencil_gray(self):
        if self.raw_image is None:
            return 0
        if self.ui.horizontalSlider_7.value() == 0:
            # self.current_img = self.raw_image
            self.show_image()
            return 0
        value = self.ui.horizontalSlider_7.value() * 0.05
        dst1_gray, dst1_color = cv2.pencilSketch(self.current_img, sigma_s=50, sigma_r=value, shade_factor=0.04)
        self.gray_image = dst1_gray
        self.show_grayimage()

# 铅笔画(彩色)
    def pencil_color(self):
        if self.raw_image is None:
            return 0
        if self.ui.horizontalSlider_12.value() == 0:
            self.current_img = self.raw_image
            self.show_image()
            return 0
        value = self.ui.horizontalSlider_12.value() * 0.05
        dst1_gray, dst1_color = cv2.pencilSketch(self.current_img, sigma_s=50, sigma_r=value, shade_factor=0.04)
        self.current_img = dst1_color


# 风格化
    def stylize(self):
        if self.raw_image is None:
            return 0
        if self.ui.horizontalSlider_2.value() == 0:
            self.current_img = self.raw_image
            self.show_image()
            return 0
        value = self.ui.horizontalSlider_2.value() * 0.05
        self.current_img = cv2.stylization(self.current_img, sigma_s=50, sigma_r=value)


# 细节增强
    def detail_enhance(self):
        if self.raw_image is None:
            return 0
        if self.ui.horizontalSlider_6.value() == 0:
            self.current_img = self.raw_image
            self.show_image()
            return 0
        value = self.ui.horizontalSlider_6.value() * 0.05
        self.current_img = cv2.detailEnhance(self.current_img, sigma_s=50, sigma_r=value)

# 边缘保持
    def edge_preserve(self):
        if self.raw_image is None:
            return 0
        if self.ui.horizontalSlider_3.value() == 0:
            self.current_img = self.raw_image
            self.show_image()
            return 0
        value = self.ui.horizontalSlider_3.value() * 0.05
        self.current_img = cv2.edgePreservingFilter(self.current_img, flags=1, sigma_s=50, sigma_r=value)

# 显示摄像照片
    def show_camera(self):
        flag, self.camera_image = self.cap.read()
        show = cv2.resize(self.image, (640, 480))
        show = cv2.cvtColor(show, cv2.COLOR_BGR2RGB)
        showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0], QtGui.QImage.Format_RGB888)
        self.label_show_camera.setPixmap(QtGui.QPixmap.fromImage(showImage))

4.运行结果如下: 

三、在线协助: 

如需安装运行环境或远程调试,见文章底部微信名片,由专业技术人员远程协助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

荷塘月色2

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

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

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

打赏作者

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

抵扣说明:

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

余额充值