项目需求
今天不写游戏辅助了,今天做一个有意思的东西,实现给图像进行P图,不过我们今天不使用PS进行P图,我们使用Python对图像进行P图。
功能描述:
- 读取图像a(人物图)
- 读取图像b(P图)
- 将图b使用代码PS到图像a上面去
- 需满足看起来较为和谐舒适
需求分析
读取图像这个我们可以使用OpenCv很好能够解决这个问题,难点在后续的"PS"上面, 我们以PS一顶帽子为例子,对某登进行PS一顶绿油油的帽子,实现思路:
- 使用OpenCV检测出头部位置;
- 在头部位置上面放置待P的图像;
- 对帽子图像进行选择设置;
- 将画面变的协调起来。
选择人物图像以及帽子图像:
大家注意一下,我们选择帽子图像的时候,需要选择或者制作一个背景为纯黑色的图像,帽子款式任意选,我选了个比较适合某登的帽子,我想它应该会喜欢的.
代码实践
搭建戴帽子函数:
import cv2 class WearHat(): def __int__(self): self.FaceModelPath = "./haarcascade_frontalface_default.Xml" self.color = (0, 255, 0) # 定义绘制颜色 def Place(self, PeopleImg, HatImg): FaceModel = cv2.CascadeClassifier(self.FaceModelPath) PeopleImgGray = cv2.cvtColor(PeopleImg, cv2.COLOR_BGR2GRAY) # 转换灰色 FaceRects = FaceModel.detectMultiScale(PeopleImgGray, scaleFactor=1.2, minNeighbors=3, minSize=(32, 32)) if len(FaceRects): # 大于0则检测到人脸 for FaceRect in FaceRects: Xmin, Ymin, Wigth, Hight = FaceRect HatShape = HatImg.shape HatImgSizeH = int(HatShape[0] / HatShape[1] * Wigth) if HatImgSizeH > (Ymin - 20): HatImgSizeH = (Ymin - 20) HatImgSize = cv2.resize(HatImg, (Wigth, HatImgSizeH), interpolation=cv2.INTER_NEAREST) Top = (Ymin - HatImgSizeH - 20) if Top <= 0: Top = 0 HatImgRows, HatImgCols, _ = HatImgSize.shape PeopleImgROI = PeopleImg[Top:Top + HatImgRows, Xmin:Xmin + HatImgCols] HatImgSizeGray = cv2.cvtColor(HatImgSize, cv2.COLOR_RGB2GRAY) _, HatImgSizeBW = cv2.threshold(HatImgSizeGray, 10, 255, cv2.THRESH_BINARY) HatImgSizeBwInv = cv2.bitwise_not(HatImgSizeBW) PeopleImg_BG = cv2.bitwise_and(PeopleImgROI, PeopleImgROI, mask=HatImgSizeBwInv) HatImg_FG = cv2.bitwise_and(HatImgSize, HatImgSize, mask=HatImgSizeBW) dst = cv2.add(PeopleImg_BG, HatImg_FG) PeopleImg[Top:Top + HatImgRows, Xmin:Xmin + HatImgCols] = dst return PeopleImg 复制代码
这里我准备了两套戴帽子的方案:
- 对两张图像进行处理,最后输出带着一顶绿油油的帽子;
- 对一段某登的演讲视频做处理,视频中某登一直带着这顶绿油油的帽子
本文中由于某登的视频不好找(主要是不好给某登的脸进行马赛克处理),暂时只发图像版的代码:
if __name__ == "__main__": PeopleImg = cv2.imread("Biden.jpg") HatImg = cv2.imread("GrennHat.jpg") GrennPeople = WearHat.Place(PeopleImg, HatImg) cv2.imshow("image", GrennPeople) cv2.waitKey(0) cv2.destroyAllWindows() 复制代码