创作不易,转载请注明出处 ,代码解释在后面。
源码:
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()
第一章 功能介绍
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='修改成功')
有问题欢迎私信,学识有限,目前在摸索根据取色笔去实现支持所有背景色图片的变换,但图像二值化至今未理解透彻。