Python证件照背景自定义改色,带Tkinter界面,代码全文解释!

直接点先上效果。

创作不易,转载请注明出处 ,代码解释在后面。

源码:

import tkinter
import numpy as np
import tkinter.messagebox
import os
import cv2


def center_window(root, width, height):
    screenwidth = root.winfo_screenwidth()
    screenheight = root.winfo_screenheight()
    size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
    root.geometry(size)


window = tkinter.Tk()
window.title('证件照改色')
center_window(window, 500, 500)


def bet_read():
    if EImg.get() == '':
        tkinter.messagebox.showerror('错误', '请输入文件路径')
    else:
        if os.path.exists(EImg.get()):
            original = cv2.imread(EImg.get())
            cv2.imshow("original", original)
            tkinter.messagebox.showinfo(title='提示', message='查看成功')
        else:
            tkinter.messagebox.showerror('错误', '请输入正确文件路径')


def bet_revamp():
    if EImg.get() == '':
        tkinter.messagebox.showerror('错误', '请输入文件路径')
    else:
        state_color = int(var.get())
        if state_color == 0:
            tkinter.messagebox.showerror('错误', '请选择背景颜色')
        else:
            if os.path.exists(EImg.get()):
                if Eb.get() == '' or Eg.get() == '' or Er.get() == '' 
                        or int(Eb.get()) > 255 or int(Eg.get()) > 255 or int(Eb.get()) > 255 
                        or int(Eb.get()) < 0 or int(Eg.get()) < 0 or int(Eb.get()) < 0:
                    tkinter.messagebox.showerror('错误', '请输入正确图片BGR值')
                else:
                    img = cv2.imread(EImg.get())
                    rows, cols, channels = img.shape
                    cv2.imshow('img', img)
                    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
                    # cv2.imshow('hsv',hsv)
                    if state_color == 1:
                        lower_red = np.array([0, 135, 135])
                        upper_red = np.array([180, 245, 230])
                        mask = cv2.inRange(hsv, lower_red, upper_red)
                    if state_color == 2:
                        lower_blue = np.array([90, 70, 70])
                        upper_blue = np.array([110, 255, 255])
                        mask = cv2.inRange(hsv, lower_blue, upper_blue)
                    if state_color == 3:
                        lower_white = np.array([230, 230, 230])
                        upper_white = np.array([256, 256, 256])
                        mask = cv2.inRange(img, lower_white, upper_white)
                    erode = cv2.erode(mask, None, iterations=1)
                    # cv2.imshow('erode',erode)
                    for i in range(rows):
                        for j in range(cols):
                            if erode[i, j] == 255:
                                img[i, j] = (Eb.get(), Eg.get(), Er.get())
                    cv2.imshow('res', img)
                    tkinter.messagebox.showinfo(title='提示', message='修改成功')
            else:
                tkinter.messagebox.showerror('错误', '请输入正确文件路径')


labImg = tkinter.Label(window, text='输入图片路径,目前支持标准证件照背景', bg='white', font=('Arial', 12), width=30, height=2)
labImg.pack()
EImg = tkinter.Entry(window, width=40)
EImg.pack()

bet_read = tkinter.Button(window, text='查看图片', bg='pink', width=15, height=2, command=bet_read)
bet_read.pack()

lab3 = tkinter.Label(window, text='请输入BGR值 为0-255', bg='red', font=('Arial', 12), width=20, height=2)
lab3.pack()

lab = tkinter.Label(window, text='输入背景要修改的 B 值', bg='green', font=('Arial', 12), width=20, height=2)
lab.pack()

Eb = tkinter.Entry(window, width=10)
Eb.pack()

lab1 = tkinter.Label(window, text='输入背景要修改的 G 值', bg='green', font=('Arial', 12), width=20, height=2)
lab1.pack()

Eg = tkinter.Entry(window, width=10)
Eg.pack()

lab2 = tkinter.Label(window, text='输入背景要修改的 R 值', bg='green', font=('Arial', 12), width=20, height=2)
lab2.pack()
Er = tkinter.Entry(window, width=10)
Er.pack()

bet_revamp = tkinter.Button(window, text='修改图片', bg='pink', width=15, height=2, command=bet_revamp)
bet_revamp.pack()

var = tkinter.StringVar()
var.set(0)
r1 = tkinter.Radiobutton(window, text='背景色红', variable=var, value='1')
r1.pack()
r2 = tkinter.Radiobutton(window, text='背景色蓝', variable=var, value='2')
r2.pack()
r3 = tkinter.Radiobutton(window, text='背景色白', variable=var, value='3')
r3.pack()
tkinter.messagebox.showinfo(title='创作不易,转载注明出处', message='欢迎访问我的CSDN主页@Youzhe_Jiang')

window.mainloop()

基于Python的证件照实现

第一章 功能介绍

1.1使用选中的证件照进行自定义的背景色转换,目前只支持标准证件照背景色

第二章 代码解释

2.1 主界面代码解释

引入显示窗口的库文件tkinter。

import tkinter

定义一个函数def center_window

def center_window(root, width, height):

# 获取显示屏高度和宽度

    screenwidth = root.winfo_screenwidth()
    screenheight = root.winfo_screenheight()

# 设置窗口居中参数

# 让窗口居中显示

    size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
    root.geometry(size)

# 创建主窗口

# 设置窗口显示的名称

# 设置窗口大小

window = tkinter.Tk()
window.title('证件照改色')
center_window(window, 500, 500)

# 显示主窗口

window.mainloop()

# 显示效果如图

2.2 主界面控件代码解释

例1  Label标签

windows 为标签所属的主界面,text 为标签所显示文字,bg 为标签背景色,font 为文字字体,width为宽,height为高 ,lab.pack()将定义的Label摆放到容器上。

lab = tkinter.Label(window, text='输入背景要修改的 B 值', bg='green', font=('Arial', 12), width=20, height=2)
lab.pack()

例2  Entry 输入框

windows 为标签所属的主界面,width为宽,默认height高的值为 1,Er.pack()将定义的Entry 摆放到容器上。

Er = tkinter.Entry(window, width=10)
Er.pack()

例3  Button 按钮

windows 为按钮所属的主界面,text 为按钮所显示文字,bg 为标签背景色,width为宽,height为高 ,command 为当按钮点击绑定的事件,bet_revamp.pack()将定义的Button 摆放到容器上。

bet_read = tkinter.Button(window, text='查看图片', bg='pink', width=15, height=2, command=bet_read)
bet_read.pack()

例4 Radiobutton单选按钮

windows 为按钮所属的主界面,text 为按钮所显示文字,variable 为按钮的绑定组,在此绑定组中只能有一个值,value为按钮的唯一值,var.set(0)为默认选择的值为0,r1.pack()将按钮摆放到容器上。

var = tkinter.StringVar()
var.set(0)
r1 = tkinter.Radiobutton(window, text='背景色红', variable=var, value='1')
r1.pack()
r2 = tkinter.Radiobutton(window, text='背景色蓝', variable=var, value='2')
r2.pack()
r3 = tkinter.Radiobutton(window, text='背景色白', variable=var, value='3')
r3.pack()

# 显示效果如图

2.3 按钮点击事件的实现

查看图片

第一步,引入提示消息框的库文件tkinter.messagebox,用作路径判断的库文件os,用作计算机视觉的库文件cv2。

import tkinter.messagebox
import os
import cv2

第二步,新建一个函数,和之前的Button 按钮绑定好点击事件bet_read。

第三步,获取输入名为EImg的Entry 输入框内容,判断是否为空,如为空则使用tkinter库中的messagebox的showerror方法弹出错误提示。如不为空则进入第二个判断,调用os.path.exists方法判断文件是否存在,如果存在则其值为true,运行cv2的imread方法读取图片,使用imshow方法将其显示,并提示查看成功。不存在则为false,提示文件路径错误。

def bet_read():
    if EImg.get() == '':
        tkinter.messagebox.showerror('错误', '请输入文件路径')
    else:
        if os.path.exists(EImg.get()):
            original = cv2.imread(EImg.get())
            cv2.imshow("original", original)
            tkinter.messagebox.showinfo(title='提示', message='查看成功')
        else:
            tkinter.messagebox.showerror('错误', '请输入正确文件路径')

修改图片

第一步,新建一个函数,和之前的Button 按钮绑定好点击事件bet_revamp。

第二步,获取输入名为EImg的Entry 输入框内容,判断是否为空,如为空则弹出错误提示。如不为空则进入第二个判断,获取单选按钮var控件的值,判断你是否选择了背景颜色,如果不为0则进入第三个判断,调用os.path.exists方法判断文件是否存在,如果存在则其值为true进行第四个判断,判断输入的BGR值是否为空且值是否在0-255的范围区间,如输入正确进入修改背景程序

def bet_revamp():
    if EImg.get() == '':
        tkinter.messagebox.showerror('错误', '请输入文件路径')
    else:
        state_color = int(var.get())
        if state_color == 0:
            tkinter.messagebox.showerror('错误', '请选择背景颜色')
        else:
            if os.path.exists(EImg.get()):
                if Eb.get() == '' or Eg.get() == '' or Er.get() == '' 
                        or int(Eb.get()) > 255 or int(Eg.get()) > 255 or int(Eb.get()) > 255 
                        or int(Eb.get()) < 0 or int(Eg.get()) < 0 or int(Eb.get()) < 0:
                    tkinter.messagebox.showerror('错误', '请输入正确图片BGR值')
                else:

第二步,根据你输入的图片路径进行图片的获取,把其值赋给img。通过img.shape读取img的参数,rows为行,cols为列,channels为通道数,使用cv2.imshow方法把原图展现。把获取到的图片通过cv2.COLOR_BGR2HSV转换为HSV格式图片(色调(H)、饱和度(S)和明度(V))以便于进行图片灰度处理。

 img = cv2.imread(EImg.get())
                    rows, cols, channels = img.shape
                    cv2.imshow('img', img)
                    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
                    # cv2.imshow('hsv',hsv)

第三步,根据你的背景颜色进行一个二值化参数的设置,lower是范围下限,upper是范围上限,在范围内的颜色会被修改成为白色,不在范围内的颜色会被修改成黑色,将二值化后的图片进行膨胀以去除毛刺和意外的亮点。iterations为腐蚀膨胀的次数。

  if state_color == 1:
                        lower_red = np.array([0, 135, 135])
                        upper_red = np.array([180, 245, 230])
                        mask = cv2.inRange(hsv, lower_red, upper_red)
                    if state_color == 2:
                        lower_blue = np.array([90, 70, 70])
                        upper_blue = np.array([110, 255, 255])
                        mask = cv2.inRange(hsv, lower_blue, upper_blue)
                    if state_color == 3:
                        lower_white = np.array([230, 230, 230])
                        upper_white = np.array([256, 256, 256])
                        mask = cv2.inRange(img, lower_white, upper_white)
                    erode = cv2.erode(mask, None, iterations=1)
                    # cv2.imshow('erode',erode)

第四步替换,循环图片的行和列遍历每个像素点,把腐蚀膨胀后的图片白色的值替换成所输入的BGR,黑色的进行跳过,输出图片为res。同时弹出提示修改成功。

                    for i in range(rows):
                        for j in range(cols):
                            if erode[i, j] == 255:
                                img[i, j] = (Eb.get(), Eg.get(), Er.get())
                    cv2.imshow('res', img)
                    tkinter.messagebox.showinfo(title='提示', message='修改成功')

有问题欢迎私信,学识有限,目前在摸索根据取色笔去实现支持所有背景色图片的变换,但图像二值化至今未理解透彻。

 

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>