第四周主要工作
- 基本完成人像抠图功能
- 实现自主选择待处理图片
- 基本完成人像抠图的UI界面
一、完成人像抠图功能
人像分割功能: 识别人体的轮廓范围,与背景进行分离,适用于拍照背景替换、照片合成、身体特效等场景;输入正常人像图片,返回分割后的二值结果图、灰度图、透明背景的人像图
import cv2
import base64
import numpy as np
from aip import AipBodyAnalysis
from part4 import m_init_part4_menubar
def segmentation_human_function(instance):
APP_ID = '-----------'
API_KEY = '-----------------'
SECRET_KEY = '--------------------------'
client = AipBodyAnalysis(APP_ID, API_KEY, SECRET_KEY)
imgfile = instance.root_path+'/part4/images_seg/test.jpg'
imgfile = instance.segmentation_original[0][0]
print(imgfile)
print(instance.segmentation_original[0][0])
ori_img = cv2.imread(imgfile)
height, width, _ = ori_img.shape
with open(imgfile, 'rb') as fp:
img_info = fp.read()
seg_res = client.bodySeg(img_info)
labelmap = base64.b64decode(seg_res['labelmap'])
nparr = np.fromstring(labelmap, np.uint8)
labelimg = cv2.imdecode(nparr, 1)
labelimg = cv2.resize(labelimg, (width, height), interpolation=cv2.INTER_NEAREST)
new_img = np.where(labelimg == 1, 255, labelimg)
maskfile = imgfile.replace('.jpg', '_mask.png')
cv2.imwrite(maskfile, new_img)
res_imgfile = imgfile.replace('.jpg', '_res.jpg')
result = cv2.bitwise_and(ori_img, new_img)
cv2.imwrite(res_imgfile, result)
cv2.imshow('result',result)
# m_init_part4_menubar.update_image(instance)
二、实现自主选择待处理图片
在m_ui.py文件中添加:
# 选择原图 当某张图像被打开时返回文件名集,取第一个文件的文件路径部分(即索引[0][0])显示到label上
def open_file_and_change_name_seg(self):
self.segmentation_original = QFileDialog.getOpenFileNames(self,"选择文件",self.root_path+"/part4","photo(*.jpg *.png)")
self.label_seg_original.setText(self.segmentation_original[0][0])
在m_init_part4_menubar.py中添加显示路径的label
# 原图图片路径——人像分割
instance.seg_img=""
instance_button_choose_original_image=QPushButton("选择原图",instance.widget_segmentation_human)
instance_button_choose_original_image.clicked.connect(instance.open_file_and_change_name_seg)
# 用于显示路径名的label
instance.label_seg_original = QLabel(instance.widget_segmentation_human)
instance.label_seg_original.setGeometry(30,80,500,50)
instance.label_seg_original.setText("文件路径")
在segmentation_human.py文件中使用instance.segmentation_original[0][0]作为待处理的图片
imgfile = instance.segmentation_original[0][0]
print(imgfile)
print(instance.segmentation_original[0][0])
三、完成UI界面
(一)显示操作窗口、执行按钮
这部分要实现的功能是当我们点击Qmenu时会显示一个操作窗口。
首先定义一个Action(在头文件中引用QAction模块),当这个Action被触发时执行show_part4_submenu_widget函数,show_part4_submenu_widget在m_ui文件中声明,如下:
""""""""""""" 抠图 """""""""""""
# 创建一个窗口,定义位置,标题等属性
instance.widget_segmentation_human=QWidget()
instance.widget_segmentation_human.setGeometry(300, 300, 500, 500)
instance.widget_segmentation_human.setWindowTitle('抠图(人像)')
# 创建一个按钮,该按钮的父对象为instance.widget_segmentation_human
# 当该按钮被点击时执行信号发射函数
instance.button_widget_segmentation_human=QPushButton("执行",instance.widget_segmentation_human)
instance.button_widget_segmentation_human.setGeometry(30, 30, 50, 50)
instance.button_widget_segmentation_human.clicked.connect(instance.signal_segmentation_human_emit)
# 创建一个action,当该action被触发时运行show_segmentation_human_widget
# show_segmentation_human_widget的作用为显示抠图操作窗口widget_segmentation_human
action_segmentation_human_widget_show = QAction('&抠图/人像', instance)
action_segmentation_human_widget_show.triggered.connect(instance.show_segmentation_human_widget)
(二)点选菜单项后 图像增强——抠图(人像)弹出窗口
# 新增一个菜单选项:Part4
# Part4选项新增一个Action:抠图(人像)
menubar = instance.menuBar()
tempMenu = menubar.addMenu('&图像增强')
tempMenu.addAction(action_segmentation_human_widget_show)
(三)设置信号发射和接收函数
m_init_part4_menubar.py
# 连接信号,当该信号被发射后执行括号内被连接函数
instance.signal_part4_segmentation_human.connect(segmentation_human.segmentation_human_function)
m_ui.py
signal_part4_segmentation_human = pyqtSignal('PyQt_PyObject')
# 人像抠图菜单
def show_segmentation_human_widget(self):
self.widget_segmentation_human.show()
# 信号发射,执行该信号关联的函数
def signal_segmentation_human_emit(self):
self.signal_part4_segmentation_human.emit(self)
(四)结果——后期所有功能会统一界面,待调整
(五)显示图片功能(有待改进)
# 最终结果图像显示
instance.image_seg_result = np.uint8(np.zeros((300,300,3)))
display_seg_image=QImage(instance.image_seg_result[:],instance.image_seg_result.shape[1],
instance.image_seg_result.shape[0],instance.image_seg_result.shape[1]*3,
QImage.Format_RGB888)
instance.image_seg_result_width = 200
instance.image_seg_result_height = instance.image_seg_result.shape[0]/instance.image_seg_result.shape[1] * instance.image_seg_result_width
instance.seg_result_image_pixmap = QPixmap(display_seg_image)
# 新建label用于存放图片
instance.seg_result_lbl = QLabel(instance.widget_segmentation_human)
instance.seg_result_lbl.setPixmap(instance.seg_result_image_pixmap)
instance.seg_result_lbl.resize(instance.image_seg_result_width,instance.image_seg_result_height)
instance.seg_result_lbl.setScaledContents(True)
instance.seg_result_lbl.setGeometry(200,200,instance.image_seg_result_width,instance.image_seg_result_height)
def update_image(instance):
# 最终结果图像显示
display_seg_image=QImage(instance.image_seg_result[:],instance.image_seg_result.shape[1],
instance.image_seg_result.shape[0],instance.image_seg_result[1]*3,
QImage.Format_RGB888)
instance.image_seg_result_width = 200
instance.image_result_image_height = instance.image_result_image.shape[0] / instance.image_result_image.shape[
1] * instance.image_result_image_width
instance.seg_result_image_pixmap = QPixmap(display_seg_image)
# 更新label图片显示
instance.seg_result_lbl.setPixmap(instance.seg_result_image_pixmap)
instance.seg_result_lbl.resize(instance.image_seg_result_width,instance.image_seg_result_height)
instance.seg_result_lbl.setScaledContents(True)
instance.seg_result_lbl.setGeometry(200,200,instance.image_seg_result_width,
instance.image_seg_result_height)