学了那么久的Python 和opencv闲来无事做了一个自动修改证件照片底色的程序,方法和注释如下
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QTextEdit, QAction, QFileDialog, QInputDialog, QLineEdit, QLabel
from PyQt5.QtGui import QIcon, QImage, QPixmap
import hashlib
import time
import numpy as np
import sys
import cv2
from qtpy import QtCore
#处理证件照图像思路
#中间人像+底色,意思是我只需沿着人像把人沟壑出来,再将底色替换即可,是人都能想出来的思路
#但是虽然底色是属于一种颜色,但是内部的RGB其实是不同的,需要设置一个颜色区域值,或者说近似值
#因为颜色和人物轮廓差值非常大,所以这我使用颜色差值来把人物图像区分出来
class Example(QMainWindow):
def init(self):
super(Example, self).init()
self.initUI()
def initUI(self):
self.textEdit2 = QTextEdit(self)
self.textEdit2.resize(280,200)
self.textEdit2.move(1, 28)
self.label1 = QLabel(self)
self.label1.resize(128, 128)
self.label1.setStyleSheet(
“font:20pt ‘楷体’;border-width: 2px;border-style: solid;border-color: rgb(255, 0, 0);”)
self.label1.move(0, 250)
self.label2 = QLabel(self)
self.label2.resize(128, 128)
self.label2.setStyleSheet(
“font:20pt ‘楷体’;border-width: 2px;border-style: solid;border-color: rgb(0, 255, 0);”)
self.label2.move(150, 250)
self.label3 = QLabel(self)
self.label3.setText(‘原始图:’)
self.label3.move(0, 220)
self.label4 = QLabel(self)
self.label4.setText(‘修改图:’)
self.label4.move(150, 220)
#中心窗口模式
#self.setCentralWidget(self.textEdit2)
设置文本框不可编辑
self.textEdit2.setFocusPolicy(QtCore.Qt.NoFocus)
#self.statusBar()
openfile = QAction(‘选择图片’, self)
openfile.setStatusTip(‘选择图片’)
openfile.triggered.connect(self.showDialog)
menubar = self.menuBar()
filemune = menubar.addMenu(‘选择图片’)
filemune.addAction(openfile)
self.setGeometry(300, 300, 300, 400)
self.setWindowTitle(‘照片底色替换’)
self.show()
def showDialog(self):
fname = QFileDialog.getOpenFileName(self, ‘选择替换图片’, ‘/’)
print(fname[0])
dir = QFileDialog.getExistingDirectory(self,
“选取保存位置”,
“C:/”) # 起始路径
try:
时间函数,用来给新文件命名
timess = time.strftime(’%Y%m%d%H%M%S’)
path = ‘Work-’ + timess + ‘end’
pathsave = dir + ‘/’ + path + ‘.jpg’
print(dir)#保存位置
print(fname[0])#选择的文件名
print(pathsave)#保存路径
print(“it work”)
img = cv2.imread(fname[0])
开始形态学操作 --改变物体形状 1.二值化 简单的说就是使图片非黑即白
np.vstack(): 在竖直方向上堆叠
np.hstack(): 在水平方向上平铺
#kernel = np.ones((5, 5), np.uint8) # 得到一个五行五列的数组,后面是numpy的数据类型
#将选择的图片显示到框1内
Tolook = cv2.resize(img, (128, 128), interpolation=cv2.INTER_CUBIC)
rows1, cols1, channels1 = Tolook.shape
bytesPerline1 = 3 * cols1
self.qImg1 = QImage(Tolook.data, cols1, rows1, bytesPerline1, QImage.Format_RGB888).rgbSwapped()
将QImage显示出来
self.label1.setPixmap(QPixmap.fromImage(self.qImg1))
腐蚀和膨胀 --图像变瘦或变胖
rows, cols, channels = img.shape # 图像长,宽,通道(颜色模式)
print(rows, cols, channels)
#图像缩放
#img = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC)
#img = cv2.resize(img, None, fx=0.5, fy=0.5)
#换底(为了框人需要在灰度图像下进行变换),这里转化颜色空间HSV
hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
#下面是hsv的效果图
cv2.imshow(‘hsv’, hsv)
#这里是蓝色的RGB颜色间距,这里BGR和RGB反过来,
lower_blue=np.array([90,70,70])
upper_blue=np.array([110,255,255])
#关于颜色区域可以自己测试颜色范围或者自己百度或者谷歌
#变为二值化图
mask = cv2.inRange(hsv,lower_blue,upper_blue)
#至此,图像轮廓已经识别出来了
erosion = cv2.erode(mask, kernel) # 对图像进行腐蚀
dilation = cv2.dilate(mask, kernel) # 对图像进行膨胀
erosion = cv2.erode(mask, None,iterations=1)#iterations迭代次数
#dilation = cv2.dilate(mask, None,iterations=1)
#循环像素点,因为已经对图像进行了腐蚀操作,对比图已经有了,接下来就是对比相对位置的颜色像素点
#就好像二值化黑白图已经是黑白图了,将区域内的白色位置对应到原始图像中的蓝色位置,替换即可
#达到替换颜色的目的
for i in range(rows):
for j in range(cols):
if erosion[i,j] == 255:#如果像素点为白色
img[i,j]=(0,0,255)#替换为红色
将选择的图片显示到框2内
Tolook2 = cv2.resize(img, (128, 128), interpolation=cv2.INTER_CUBIC)
rows2, cols2, channels2 = Tolook2.shape
bytesPerline2 = 3 * cols2
#将opencv图转化为qimage对象
self.qImg2 = QImage(Tolook2.data, cols2, rows2, bytesPerline2, QImage.Format_RGB888).rgbSwapped()
将QImage显示出来
self.label2.setPixmap(QPixmap.fromImage(self.qImg2))
#height, width = img.shape[:2]
#suofanghou = cv2.resize(img, (0.5 * width, 0.5 * height), interpolation=cv2.INTER_CUBIC) # 定尺寸的缩放
测试图像代码,查看图像是否正常
#disposeimg = cv2.resize(img, (128, 128), interpolation=cv2.INTER_CUBIC)
#print(disposeimg)
cv2.imwrite(pathsave,img)#图像的保存
self.textEdit2.append(‘图片已经保存在’+pathsave)
cv2.imshow(‘list/test’, np.hstack((img,erosion,dilation)))
#下面是原图,腐蚀,膨胀的效果图
cv2.imshow(‘mask’,mask)
cv2.waitKey(0)
except Exception as msg:
print(msg)
self.textEdit2.append(“打开文件失败,可能是文件内型错误”)
if name == “main”:
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
图片
小声BB…未来有空看看能不能加个批量,而且文件打包后200M,爷蒙蔽了