计算机系统应用教程网站

网站首页 > 技术文章 正文

保护女神林志玲,给脸打马赛克python+opencv实现

btikc 2024-09-05 12:29:31 技术文章 8 ℃ 0 评论


1 说明:

=====

1.1 python+opencv实现人脸定位、马赛克采用2种方法:dlib法和cv2自带xml法。

1.2 cv2自带xml法:加载人脸模型

haarcascade_frontalface_default.xml

1.3 图片来源:来自今日头条正版免费图库,向女神致敬,仅供学习。

2 加载opencv的xml模型法:有bug,此处省略。

https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_default.xml #下载

3 dlib法:

======

3.1 安装dlib:

pip install dlib

3.2 效果图:


4 代码:

python的代码简洁,清晰,规范化的步骤

===============================

4.1 第1步:模块导入

# 导入模块
import dlib
import cv2

4.2 第2步:函数定义

# 获得人脸矩形的坐标信息
def rect_to_fb(face):
    x = face.left()
    y = face.top()
    w = face.right() - x
    h = face.bottom() - y
    return (x, y, w, h)

# 将待检测的image进行resize,调整大小
def resize(image, width=1200):  
    r = width * 1.0 / image.shape[1]
    dim = (width, int(image.shape[0] * r))
    resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
    return resized

# 定义人脸马赛克=face_mosaic函数:
def face_mosaic(image, x, y, w, h, m1w=9):

  """
  :param img: opencv img
  :param int x : 马赛克左顶点
  :param int y: 马赛克右顶点
  :param int w: 马赛克宽
  :param int h: 马赛克高
  :param int m1w: 马赛克每一块的宽:mosaic 1 w
  """
  # 获取读取图片的高和宽
  img_h, img_w = image.shape[0], image.shape[1]
  # 当判断超过边界,返回
  if (y + h > img_h) or (x + w > img_w):
    return

  # h==高:关键点0 减去m1w防止溢出
  for i in range(0, h - m1w, m1w): 
    # w==宽:关键点0 减去m1w防止溢出
    for j in range(0, w - m1w, m1w):
      # 获得人脸矩形的坐标信息
      rect = [j + x, i + y, m1w, m1w]
      # numpy中ndarray文件转为list
      color = image[i + y][j + x].tolist() # 关键点1 tolist
      # 获取对角线
      left_up = (rect[0], rect[1])
      # 关键点2 减去一个像素
      right_down = (rect[0] + m1w - 1, rect[1] + m1w - 1) 
      # 确定对角线 来画矩形的
      # 比如:
      # cv2.rectangle(img, (bbox.left, bbox.top), (bbox.right, bbox.bottom), (0,0,255), 2)
      # 注意上面是2=小绿色框,1=部分小绿色宽,-1=无色马赛克,不显示绿色框
      cv2.rectangle(image, left_up, right_down, color, -1)

4.3 第3步:main主函数

# 人脸侦测,定位,打马赛克
def main():
    # 读取原始图片
    image_file = "/home/xgj/Desktop/masaike/pic2.jpeg"
    image = cv2.imread(image_file)
    # 调用函数,调整图片大小
    image = resize(image, width=1200)
    
    # 调用dlib的函数获取人脸模型
    detector = dlib.get_frontal_face_detector()
    # 获取人脸数据
    faces = detector(image, 1)

    for (i, face) in enumerate(faces):
        (x, y, w, h) = rect_to_fb(face)
        # 人脸定位并加绿色矩形框
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
        # cv2.putText(I,'there 0 error(s):',(50,150),cv2.FONT_HERSHEY_COMPLEX,6,(0,0,255),25)
        # 各参数依次是:照片/添加的文字/左上角坐标/字体/字体大小/颜色/字体粗细
        cv2.putText(image, "Face:{}".format(i+1), (x - 10, y - 10),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
        # 调用马赛克函数,打马赛克
        face_mosaic(image, x, y, w, h)
    
    # 显示效果图片
    cv2.imshow("Output", image)
    cv2.waitKey(0) #永不自动关闭

4.4 第4步:结尾

if __name__ == "__main__":
    main()

5 小结:

=====

5.1 dlib法基本无bug,显示了dlib库在人脸识别和定位上的强大。

5.2 同时在使用OpenCV的自带人脸识别模型xml时出现上述2张照片bug,所以放弃使用,希望OpenCV这个强大的库能改进。 当然OpenCV还是一个很强大,很热门的计算机视觉库。

5.3 python代码规范的问题:要不要结尾if __name__ == "__main__":问题,好像python3中也不重要了,自己可以感受一下。

5.4 以上是个人心得,分享出来。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表