感觉自己陷入了代码细节误区,本着时间紧任务重的理念,加上本人能力有限,暂时无法完成细节代码图解,但是可以简单写一下自己两周以来的学习感悟,和整体架构!

首先总体架构参考如下博客:https://zhuanlan.zhihu.com/p/38520597

代码部分总的执行流程如下:

代码结构截图:

代码实现模型的初始化,首先是构建mtcnn的tensorflow计算图,然后载入训练好的模型参数,细节是分别调用pnet,rnet,onet组装成mtcnn。里面涉及python装饰器的内容,首先写了一个基本的层,然后用装饰器分别实现神经网络各种层,感觉有点类似caffe的工厂模式。

代码实现最终的检测道德人脸框的四个点坐标和5个点的包括双眼,鼻尖,两个嘴角的坐标。

这是官方训练好的模型文件。

这里会对检测到的人脸框和五点位置进一步处理,最终得到我们想要的结果。

这里是代码的核心了,首先得到图像金字塔,参考博文。https://blog.csdn.net/poem_qianmo/article/details/26157633

然后输入pnet,返回值输入框的初始化,然后nms,然后rect实现正方形框输出,然后因为预测的框会超过原图边界,所以会涉及像素填充调用pad函数,然后输入到rnet,图像缩放、像素值归一化,归一化就是等比例缩放数值,如下图所示:

后面的也会有nms,等函数的调用就不一一细说了,先理解整体框架,具体代码实现讲解后面补充。

下面列出pro:net的网络结构图。

pnet 人脸得分 conv4-1, 人脸框对应 conv4-2,

rnet 人脸得分 conv5-1, 人脸框对应 conv5-2,

onet 人脸得分 conv6-1, 人脸框对应 conv6-2, 和 五点conv6-3 对应

代码解释:detect_face.py

1、def imresample(img, sz):函数主要功能对图片进行缩小放大。

im_data = cv2.resize(img, (sz[1], sz[0]), interpolation=cv2.INTER_AREA)

img 输入图片

sz[1], sz[0] resiz的尺寸

利用python opencv中的 cv.Resize(源,目标,变换方法)就可以实现变换为想要的尺寸了

源文件:就不用说了

目标:你可以对图像进行倍数的放大和缩小也可以直接的输入尺寸大小

变换的方法:

CV_INTER_NN

CV_INTER_LINEAR

CV_INTER_AREA

CV_INTER_CUBIC

2、def rerec(bboxA):函数主要功能是将检测到的矩形框以原的中心点为中心转换为正方形。

# convert bboxA to square

h = bboxA[:,3]-bboxA[:,1]

w = bboxA[:,2]-bboxA[:,0]

l = np.maximum(w, h)

bboxA[:,0] = bboxA[:,0]+w*0.5-l*0.5

bboxA[:,1] = bboxA[:,1]+h*0.5-l*0.5

bboxA[:,2:4] = bboxA[:,0:2] + np.transpose(np.tile(l,(2,1)))

下面是测试程序和效果图片

import numpy as np

import cv2

bboxA = np.array([[30, 20, 60, 60]])

img = np.ones((80, 80), dtype=np.uint8)

img[:, :] = 100

cv2.rectangle(img, (30, 20), (60, 60), (0, 255, 0), 1)

cv2.imwrite("pure.jpg", img)

h = bboxA[:, 3] - bboxA[:, 1]

w = bboxA[:, 2] - bboxA[:, 0]

l = np.maximum(w, h)

bboxA[:, 0] = bboxA[:, 0] + w * 0.5 - l * 0.5

bboxA[:, 1] = bboxA[:, 1] + h * 0.5 - l * 0.5

bboxA[:, 2:4] = bboxA[:, 0:2] + np.transpose(np.tile(l, (2, 1)))

img = cv2.imread("pure.jpg")

cv2.rectangle(img, (bboxA[0, 0:1], bboxA[0, 1:2]), (bboxA[0, 2:3], bboxA[0, 3]), (0, 255, 0), 1)

cv2.imwrite("pure.jpg", img)

4、def pad(total_boxes, w, h):

tmpw = (total_boxes[:,2]-total_boxes[:,0]+1).astype(np.int32)

tmph = (total_boxes[:,3]-total_boxes[:,1]+1).astype(np.int32)

numbox = total_boxes.shape[0]

dx = np.ones((numbox), dtype=np.int32)

例程:

numbox = 5

dx = np.ones((numbox), dtype=np.int32)

print(dx)

[1 1 1 1 1]

dy = np.ones((numbox), dtype=np.int32)

edx = tmpw.copy().astype(np.int32)

例程:

total_boxes = np.array([[30, 20, 60, 60]])

tmpw = (total_boxes[:, 2] - total_boxes[:, 0] + 1).astype(np.int32)

print(tmpw)

edx = tmpw.copy().astype(np.int32)

print(edx)

[31]

[31]

x = total_boxes[:,0].copy().astype(np.int32)

total_boxes = np.array([[30, 20, 60, 60], [3, 2, 6, 6]])

x = total_boxes[:, 0].copy().astype(np.int32)

print(x)

y = total_boxes[:, 1].copy().astype(np.int32)

print(y)

ex = total_boxes[:, 2].copy().astype(np.int32)

print(ex)

ey = total_boxes[:, 3].copy().astype(np.int32)

print(ey)

[30 3]

[20 2]

[60 6]

[60 6]

tmp = np.where(ex>w)

w = 6

total_boxes = np.array([[30, 20, 60, 60], [3, 2, 6, 6]])

x = total_boxes[:, 0].copy().astype(np.int32)

y = total_boxes[:, 1].copy().astype(np.int32)

ex = total_boxes[:, 2].copy().astype(np.int32)

print(ex)

ey = total_boxes[:, 3].copy().astype(np.int32)

tmp = np.where(ex > w)

print(tmp)

[60 6]

(array([0]),)

edx.flat[tmp] = np.expand_dims(-ex[tmp] + w + tmpw[tmp], 1)

-ex[tmp]

tmpw[tmp]

np.expand_dims

edx

.flat

np.array([[[[[1, 2, 3, 4, 5]]]]]).flat

>[1, 2, 3, 4, 5]

total_boxes = np.array([[30, 20, 60, 60], [3, 2, 6, 6]])

w = 6

tmpw = (total_boxes[:, 2] - total_boxes[:, 0] + 1).astype(np.int32)

tmph = (total_boxes[:, 3] - total_boxes[:, 1] + 1).astype(np.int32)

numbox = total_boxes.shape[0]

dx = np.ones((numbox), dtype=np.int32)

dy = np.ones((numbox), dtype=np.int32)

edx = tmpw.copy().astype(np.int32)

edy = tmph.copy().astype(np.int32)

x = total_boxes[:, 0].copy().astype(np.int32)

y = total_boxes[:, 1].copy().astype(np.int32)

ex = total_boxes[:, 2].copy().astype(np.int32)

ey = total_boxes[:, 3].copy().astype(np.int32)

tmp = np.where(ex > w)

print(tmp)

print(-ex[tmp])

print(tmpw[tmp])

print(-ex[tmp] + w + tmpw[tmp],)

print(np.expand_dims(-ex[tmp] + w + tmpw[tmp], 0))

print(np.expand_dims(-ex[tmp] + w + tmpw[tmp], 1))

edx.flat[tmp] = np.expand_dims(-ex[tmp] + w + tmpw[tmp], 1)

print(edx.flat[tmp])

ex[tmp] = w

print(ex[tmp])

(array([0]),)

[-60]

[31]

(array([-23], dtype=int32),)

[[-23]]

[[-23]]

[-23]

[6]

I = np.argsort(s)

升序排列 排在最后的是值最大的下标

例程

a = np.array([6, 0, 5,])

b = np.argsort(a)

print(b)

[1 2 0]

pick = np.zeros_like(s, dtype=np.int16)

其维度与矩阵W一致,并为其初始化为全0

xx1 = np.maximum(x1[i], x1[idx])

接收两个参数 分别和另一个比较 输出大的值

例程

x1 = np.array([6, 0, 5,])

b = np.argsort(x1)

# print(b)

i = b[-1]

idx = b[0:-1]

# print(idx)

xx1 = np.maximum(x1[i], x1[idx])

print(x1[i])

print(x1[idx])

print(xx1)

np.maximum([-2, -1, 0, 1, 2], 0)

print(np.maximum([-2, -1, 0, 1, 2], 0))

print(np.maximum([5, 9, 5, 1], 3))

xx1 = np.maximum(x1[i], x1[idx])最大的xmin

yy1 = np.maximum(y1[i], y1[idx])最大的ymin

xx2 = np.minimum(x2[i], x2[idx])最小的xmax

yy2 = np.minimum(y2[i], y2[idx])最小的ymax

w = np.maximum(0.0, xx2-xx1+1)最小的宽

h = np.maximum(0.0, yy2-yy1+1)最小的高

获取最小的面积

o = inter / np.minimum(area[i], area[idx])

返回的o是面积比值的数组

I = I[np.where(o<=threshold)]

返回满足条件o<=threshold的数组I 然后I进入下一个循环 一直到I里面一个元素都没有,返回pick数组 pick数组里面记录了比较过程中满足o > threshold 值的索引。

python代码总体框架怎么写_mtcnn python 开源代码详细图解相关推荐

  1. 《代码规范》如何写出干净的代码(四)对象和类

    大家好,这段时间上海的疫情太严重了,我们这些周边城市也收到了一些波及,是不是的部分区域就被封锁-期望上海的疫情早日过去,加油,每一位打工人-最后,求关注,求收藏,求点赞,任何意见都可以留言,谢谢- 前 ...

  2. pycharm格式化代码快捷键_你写的 Python 代码总是不规范?用它!

    今天咱们来说说代码风格不同的编程语言有不同的代码风格 Python 的代码规范就是人们常说的 PEP8 在这个网站https://www.python.org/dev/peps/pep-0008/#i ...

  3. python实现统计你一共写了多少行代码

    程序员要保证一定的代码量就必须勤奋的敲代码,但怎么知道自己一共写了多少代码呢,笔者用python写了个简单的脚本,遍历所有的.java,.cpp,.c文件的行数,但是正如大家所知,java生成了许多代 ...

  4. python消息队列框架_awesome asyncio-精选python异步框架清单集合

    Python 3.4引入标准库的Python asyncio模块提供了使用协程编写单线程并发代码,通过套接字和其他资源对I / O进行多路访问,运行网络客户端和服务器以及其他相关原语的基础结构. As ...

  5. python监控某个程序_写一个python的服务监控程序

    写一个python的服务监控程序 前言: Redhat下安装Python2.7 rhel6.4自带的是2.6, 发现有的机器是python2.4. 到python网站下载源代码,解压到Redhat上, ...

  6. python绘制函数图像opengl3d_写给 python 程序员的 OpenGL 教程

    原标题:写给 python 程序员的 OpenGL 教程 作者:牧马人 (本文来自作者投稿) 1预备知识 OpenGL 是 Open Graphics Library 的简写,意为"开放式图 ...

  7. pythonic 代码_怎样才能写出Pythonic 的代码?

    近来,身边的一些Python 大牛们老是提到一个很时髦的词:Pythonic,但却很少人说得清楚它是个什么意思,搞得新童鞋一头雾水: 在我们周围有很多资深的工程师,用其他语言写过很多的代码,做过很多项 ...

  8. 排队模型java代码_mm1 用Java写的排队论MM1,详细,适合初学者阅读。 Develop 238万源代码下载- www.pudn.com...

    文件名称: mm1下载 收藏√  [ 5  4  3  2  1 ] 开发工具: Java 文件大小: 7118 KB 上传时间: 2014-11-11 下载次数: 2 提 供 者: mcf 详细说明 ...

  9. python画人脸编程怎么写_Python 40行代码实现人脸识别功能

    前言 很多人都认为人脸识别是一项非常难以实现的工作,看到名字就害怕,然后心怀忐忑到网上一搜,看到网上N页的教程立马就放弃了.这些人里包括曾经的我自己.其实如果如果你不是非要深究其中的原理,只是要实现这 ...

最新文章

  1. roast和roasting区别_《吐槽大会》的英文居然是roast!为什么?
  2. Java协作开发,Java开发学习笔记之八:servlet之间的协作
  3. httpf发送 json_Java用HttpClient3发送http/https协议get/post请求,发送map,json,xml,txt数据...
  4. 「实践出真知」如何打造一流的视觉AI技术
  5. iOS CoreData (一) 增删改查
  6. Oracle 日期时间函数大全
  7. Intellij mac快捷键
  8. cmpp java代码_CMPP2.0 java实现基于 协议。 多个厂家的版本都有体现。 Develop 238万源代码下载- www.pudn.com...
  9. wps页眉怎么设置不同页码_WPS论文排版教程二:如何设置不同页码
  10. 【20220412】文献翻译4:交互中的手势和语言概述
  11. 【MarkDown】基础语法
  12. MySQL--- 有哪些“饮鸩止渴”提高性能的方法?
  13. 支持3d android 模拟器,3D太空模拟器
  14. 上网本 linux中文版,veket|veket linux上网本操作系统 v5.30 简体中文正式版 - 天天游戏吧...
  15. 现货黄金投资的鳄鱼法则
  16. Web用户体验设计提升实践
  17. 从0开始学爬虫6比价工具开发2之图书信息汇总
  18. java 多线程和线程池
  19. 语音识别工具箱之HTK安装与使用
  20. Armv8架构虚拟化介绍

热门文章

  1. python爬视频选择清晰度_Python爬取新浪微博博主高清视频
  2. 实现三维向量之间的加法与减法
  3. Caffeine Cache
  4. 基于AR模型的功率谱matlab,基于AR模型法功率谱估计的Matlab实现
  5. 干掉GuavaCache:Caffeine才是本地缓存的王
  6. 华为DHCP SNOOPING配置
  7. 用Beep函数演绎天空之城
  8. Nodejs Request使用介绍
  9. Python一分钟带你探秘不为人知的网络昆虫!(文末获取爬虫福利!)
  10. crypto-了不起的盖茨比(CATCTF)