rainit2006 / Artificial-Intelligence

1 stars 0 forks source link

OpenCV-sample #22

Open rainit2006 opened 5 years ago

rainit2006 commented 5 years ago

rainit2006 commented 5 years ago

打开国庆的正确方式,教你用OpenCV-Python轻松生成微信国庆版头像

实现思路

完整的程序实现分为三个部分完成:

  1. 首先需要准备一个国旗图案的模板图像
  2. 根据这个 模板图像,生成遮罩图层mask图像。 这里主要是通过inRange来实现mask生成,通过imagewatch我观察到模板图中的空白区域的像素值为(216、216、216)所以上下浮点5。 然后对输入的模板图像与头像图像,进行融合,生成一张国庆版头像。 这个时候直接的像素相加效果会比较生硬。所以先通过高斯模糊生成边缘的融合权重,这样边缘看上去比较自然。
  3. 最后对选择的任意图像,都可以先通过人脸检测,自动定位到人脸区域,然后截取ROI,自动生成。 如果无法自动检测到人脸,则会利用输入图像自动生成。人脸检测我这里采用OpenCV DNN的人脸检测方法。

代码地址

https://github.com/gloomyfish1998/opencv_tutorial/tree/master/python

知识点:

  1. mask处理

    mask = cv.inRange(icon, (210, 210, 210), (225, 225, 225))
    se = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
    mask = cv.morphologyEx(mask, cv.MORPH_CLOSE, se)
    # mask with gaussian
    mask = cv.GaussianBlur(mask, (5, 5), 0)
  2. InRange(): 範囲指定による2値化処理が行える。

dst = cv2.inRange(src, lowerb, upperb[, dst])

src: 入力画像
lowerb: 下限
upperb: 上限
dst: 出力画像 (引数経由で受け取る場合)
  1. getStructuringElement関数 モルフォロジー演算のために,指定されたサイズと形状の構造要素を返します. 形态学变换用的函数。膨胀(Dilation)与腐蚀(Erosion)是最基本的两种形态学变换方法。

  2. 画像融合(alpha融合)

 h, w = mask.shape[:2]
    avatar = cv.resize(avatar, (w, h), interpolation=cv.INTER_CUBIC)
    cv.imshow("profile", avatar)
    result = np.array(np.zeros_like(avatar))
    for row in range(h):
        for col in range(w):
            pv = mask[row, col]
            w1 = pv / 255.0
            w2 = 1.0 - w1
            b1, g1, r1 = avatar[row, col]
            b2, g2, r2 = icon[row, col]
            b1 = b1 * w1 + b2 * w2
            g1 = g1 * w1 + g2 * w2
            r1 = r1 * w1 + r2 * w2
            result[row, col] = [np.int32(b1), np.int32(g1), np.int32(r1)]
    return result
  1. numpy.zeros関数: 全ての要素が0の配列を生成する numpy.zeros_like関数:ある配列とまったく同様の性質(shape, dtype等)をもった配列を新しく生成し、要素をゼロで初期化する。