Biden的帽子忘记带了,你能用Python给它快速PS一个么?

222 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第31天,点击查看活动详情

项目需求

  今天不写游戏辅助了,今天做一个有意思的东西,实现给图像进行P图,不过我们今天不使用PS进行P图,我们使用Python对图像进行P图。

  功能描述:

  1. 读取图像a(人物图)
  2. 读取图像b(P图)
  3. 将图b使用代码PS到图像a上面去
  4. 需满足看起来较为和谐舒适

需求分析

  读取图像这个我们可以使用OpenCv很好能够解决这个问题,难点在后续的"PS"上面, 我们以PS一顶帽子为例子,对某登进行PS一顶绿油油的帽子,实现思路:

  1. 使用OpenCV检测出头部位置;
  2. 在头部位置上面放置待P的图像;
  3. 对帽子图像进行选择设置;
  4. 将画面变的协调起来。

选择人物图像以及帽子图像:

image.png lvmao.jpg

  大家注意一下,我们选择帽子图像的时候,需要选择或者制作一个背景为纯黑色的图像,帽子款式任意选,我选了个比较适合某登的帽子,我想它应该会喜欢的.

代码实践

搭建戴帽子函数:

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

  这里我准备了两套戴帽子的方案:

  1. 对两张图像进行处理,最后输出带着一顶绿油油的帽子;
  2. 对一段某登的演讲视频做处理,视频中某登一直带着这顶绿油油的帽子

  本文中由于某登的视频不好找(主要是不好给某登的脸进行马赛克处理),暂时只发图像版的代码:

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()

image.png