圣诞节,用Python给自己加顶“圣诞帽”

栏目: Python · 发布时间: 6年前

内容简介:每年到这个时候,微信好友的头像都会开始换上「圣诞」皮肤。最常见的就是加个圣诞小帽子了。当然这种事情用很多 P 图软件都可以做到,微信搜索「圣诞帽」也会有各种小程序出现,但是使用之前的验证,总会要求绑定微信等各种信息,接受各种弹幕广告,甚至还有的需要分享才可以保存图片。

每年到这个时候,微信好友的头像都会开始换上「圣诞」皮肤。最常见的就是加个圣诞小帽子了。

圣诞节,用 <a href='https://www.codercto.com/topics/20097.html'>Python</a> 给自己加顶“圣诞帽”

当然这种事情用很多 P 图软件都可以做到,微信搜索「圣诞帽」也会有各种小程序出现,但是使用之前的验证,总会要求绑定微信等各种信息,接受各种弹幕广告,甚至还有的需要分享才可以保存图片。

那么作为程序员,有没有其他添加的办法呢?当然有!

圣诞节,用Python给自己加顶“圣诞帽”

用到的工具:

  • OpenCV(毕竟我们主要的内容就是 OpenCV...)
  • dlib(dlib 的人脸检测比 OpenCV 更好用,而且 dlib 有 OpenCV 没有的关键点检测。)

用到的语言:

  • Python,但是完全可以改成 C++ 版本。

素材准备

首先我们需要准备一个圣诞帽的素材,格式最好为 PNG,因为 PNG 的话我们可以直接用 Alpha 通道作为掩膜使用。

我们用到的圣诞帽如下图:

圣诞节,用Python给自己加顶“圣诞帽”

我们通过通道分离可以得到圣诞帽图像的 Alpha 通道。代码如下:

r,g,b,= cv2.split(hat_img)  
rgb_hat = cv2.merge((r,g,b)) 
 
cv2.imwrite("hat_alpha.jpg",a) 

为了能够与 rgb 通道的头像图片进行运算,我们把 rgb 三通道合成一张 rgb 的彩色帽子图。

Alpha 通道的图像如下图所示:

圣诞节,用Python给自己加顶“圣诞帽”

人脸检测与人脸关键点检测

我们用下面这张图作为我们的测试图片:

圣诞节,用Python给自己加顶“圣诞帽”

下面我们用 dlib 的正脸检测器进行人脸检测,用 dlib 提供的模型提取人脸的五个关键点。

代码如下:

# dlib人脸关键点检测器 
      predictor_path = "shape_predictor_5_face_landmarks.dat" 
      predictor = dlib.shape_predictor(predictor_path)   
 
      # dlib正脸检测器 
      detector = dlib.get_frontal_face_detector() 
 
      # 正脸检测 
      dets = detector(img, 1) 
 
      # 如果检测到人脸 
      if len(dets)>0:   
          for d in dets: 
              x,y,w,= d.left(),d.top(), d.right()-d.left(), d.bottom()-d.top() 
              # x,y,w,h = faceRect   
              cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2,8,0) 
 
              # 关键点检测,5个关键点 
              shape = predictor(img, d) 
              for point in shape.parts(): 
                  cv2.circle(img,(point.x,point.y),3,color=(0,255,0)) 
 
              cv2.imshow("image",img) 
              cv2.waitKey()   

这部分效果如下图:

圣诞节,用Python给自己加顶“圣诞帽”

调整帽子大小

我们选取两个眼角的点,求中心作为放置帽子的 x 方向的参考坐标,y 方向的坐标用人脸框上线的 y 坐标表示。

然后我们根据人脸检测得到的人脸的大小调整帽子的大小,使得帽子大小合适。

# 选取左右眼眼角的点 
              point1 = shape.part(0) 
              point2 = shape.part(2) 
 
              # 求两点中心 
              eyes_center = ((point1.x+point2.x)//2,(point1.y+point2.y)//2) 
 
              # cv2.circle(img,eyes_center,3,color=(0,255,0))   
              # cv2.imshow("image",img) 
              # cv2.waitKey() 
 
              #  根据人脸大小调整帽子大小 
              factor = 1.5 
              resized_hat_h = int(round(rgb_hat.shape[0]*w/rgb_hat.shape[1]*factor)) 
              resized_hat_w = int(round(rgb_hat.shape[1]*w/rgb_hat.shape[1]*factor)) 
 
              if resized_hat_h > y: 
                  resized_hat_h = y-1 
 
              # 根据人脸大小调整帽子大小 
              resized_hat = cv2.resize(rgb_hat,(resized_hat_w,resized_hat_h)) 

提取帽子和需要添加帽子的区域

按照之前所述,去 Alpha 通道作为 mask,并求反。这两个 mask 一个用于把帽子图中的帽子区域取出来,一个用于把人物图中需要填帽子的区域空出来。

后面你将会看到:

# 用alpha通道作为mask 
              mask = cv2.resize(a,(resized_hat_w,resized_hat_h)) 
              mask_inv =  cv2.bitwise_not(mask) 

从原图中取出需要添加帽子的区域,这里我们用的是位运算操作。

# 帽子相对与人脸框上线的偏移量 
              dh = 0 
              dw = 0 
              # 原图ROI 
              # bg_roi = img[y+dh-resized_hat_h:y+dh, x+dw:x+dw+resized_hat_w] 
              bg_roi = img[y+dh-resized_hat_h:y+dh,(eyes_center[0]-resized_hat_w//3):(eyes_center[0]+resized_hat_w//3*2)] 
 
              # 原图ROI中提取放帽子的区域 
              bg_roi = bg_roi.astype(float) 
              mask_inv = cv2.merge((mask_inv,mask_inv,mask_inv)) 
              alpha = mask_inv.astype(float)/255 
 
              # 相乘之前保证两者大小一致(可能会由于四舍五入原因不一致) 
              alpha = cv2.resize(alpha,(bg_roi.shape[1],bg_roi.shape[0])) 
              # print("alpha size: ",alpha.shape) 
              # print("bg_roi size: ",bg_roi.shape) 
              bg = cv2.multiply(alpha, bg_roi) 
              bg = bg.astype('uint8') 

这是的背景区域(bg)如下图所示。可以看到,刚好是需要填充帽子的区域缺失了。

圣诞节,用Python给自己加顶“圣诞帽”

然后我们提取帽子区域,代码如下:

# 提取帽子区域 
   hat = cv2.bitwise_and(resized_hat,resized_hat,mask = mask) 

提取得到的帽子区域如下图。帽子区域正好与上一个背景区域互补。

圣诞节,用Python给自己加顶“圣诞帽”

添加圣诞帽

最后我们把两个区域相加。再放回到原图中去,就可以得到我们想要的圣诞帽图了。

这里需要注意的就是,相加之前 resize 一下保证两者大小一致,因为可能会由于四舍五入原因不一致。

# 相加之前保证两者大小一致(可能会由于四舍五入原因不一致) 
              hat = cv2.resize(hat,(bg_roi.shape[1],bg_roi.shape[0])) 
              # 两个ROI区域相加 
              add_hat = cv2.add(bg,hat) 
              # cv2.imshow("add_hat",add_hat)  
 
              # 把添加好帽子的区域放回原图 
              img[y+dh-resized_hat_h:y+dh,(eyes_center[0]-resized_hat_w//3):(eyes_center[0]+resized_hat_w//3*2)] = add_hat 

我们得到的效果图如下图所示:

圣诞节,用Python给自己加顶“圣诞帽”

最后祝大家圣诞节快乐!

圣诞节,用Python给自己加顶“圣诞帽”

圣诞节,用Python给自己加顶“圣诞帽”


以上所述就是小编给大家介绍的《圣诞节,用Python给自己加顶“圣诞帽”》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Agile Web Development with Rails 4

Agile Web Development with Rails 4

Sam Ruby、Dave Thomas、David Heinemeier Hansson / Pragmatic Bookshelf / 2013-10-11 / USD 43.95

Ruby on Rails helps you produce high-quality, beautiful-looking web applications quickly. You concentrate on creating the application, and Rails takes care of the details. Tens of thousands of deve......一起来看看 《Agile Web Development with Rails 4》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具