目录(?)[-]
- Python 3 ****识别
- 一实验简介
- 11 知识点
- 12 效果展示
- 二实验步骤
- 21 安装包
- 22 程序原理
- 23 实现脚本
- 24 测试效果
- 三实验总结
- 四完整代码
本实验将使用 Python3 去识别图片是否为****,我们会使用到 PIL 这个图像处理库,会编写算法来划分图像的皮肤区域
1.1. 知识点
- Python 3 的模块的安装
- Python 3 基础知识
- 肤色像素检测与皮肤区域划分算法
- Pillow 模块的使用
- argparse 模块的使用
1.2. 效果展示
2.1. 安装包
PIL 2009年之后就没有更新了,也不支持 Python3 ,于是有了 Alex Clark 领导的公益项目 Pillow,Pillow 是一个对 PIL 友好的分支,支持 Python3,所以我们这里安装的是 Pillow,其官方文档
安装前更新源
首先我们需要处理一个问题:当前实验楼的环境中 python3 命令使用的 Python 版本为 3.5,但源中却没有 python3.5-dev,这会导致安装 Pillow 出错。所以我们必须将 python3 命令使用的 python 版本切换为 3.4,然后再安装 python3-dev 和 python3-setuptools。
然后安装 Pillow 依赖包
安装 , 是 Python2 的软件包管理系统,使用它来安装 Python2 的模块非常简便,而
最后安装 Pillow:
2.2. 程序原理
本程序根据颜色(肤色)找出图片中皮肤的区域,然后通过一些条件判断是否为****
程序的关键步骤如下
- 遍历每个像素,检测像素颜色是否为肤色
- 将相邻的肤色像素归为一个皮肤区域,得到若干个皮肤区域
- 剔除像素数量极少的皮肤区域
我们定义非****的判定规则如下(满足任意一个判定为真):
- 皮肤区域的个数小于 3 个
- 皮肤区域的像素与图像所有像素的比值小于 15%
- 最大皮肤区域小于总皮肤面积的 45%
- 皮肤区域数量超过60个
这些规则你可以尝试更改,直到程序效果让你满意为止
关于像素肤色判定这方面,公式可以在网上找到很多,但世界上不可能有正确率 100% 的公式
你可以用自己找到的公式,在程序完成后慢慢调试
- RGB 颜色模式
第一种:
- 第二种:
- ,
- HSV 颜色模式
- YCbCr 颜色模式
一幅图像有零个到多个的皮肤区域,程序按发现顺序给它们编号,第一个发现的区域编号为 0,第 n 个发现的区域编号为 n-1
我们用一种类型来表示像素,我们给这个类型取名为 ,包含了像素的一些信息:唯一的 编号(),是/否肤色(),皮肤区域号(),横坐标(),纵坐标()遍历所有像素时,我们为每个像素创建一个与之对应的 其中 属性即为像素所在的皮肤区域编号,创建对象时初始化为无意义的
关于每个像素的 id 值,左上角为原点,像素的 id 值按像素坐标排布,那么看起来如下图
其实 id 的顺序也即遍历的顺序
遍历所有像素时,创建
相邻像素的定义:通常都能想到是当前像素周围的 8 个像素,然而实际上只需要定义 4
接下来实现细节部分
2.3. 实现脚本
导入所需要的模块
我们将设计一个
这个类里面我们首先使用 定义一个
函数实际上是一个返回Python中标准元组类型子类的一个工厂方法。 你需要传递一个类型名和你需要的字段给它,然后它就会返回一个类,你可以初始化这个类,为你定义的字段传递值等。 详情参见官方文档。然后定义
本实验代码中使用到的模块中的函数均可以在其模块的文档中找到,一定要培养查阅文档的习惯
isinstane(object, classinfo)
- 如果参数
object
- 是参数
classinfo
- 的实例,返回真,否则假;参数
classinfo
- 可以是一个包含若干
type
- 对象的元祖,如果参数
object
涉及到效率问题,越大的图片所需要消耗的资源与时间越大,因此有时候可能需要对图片进行缩小
所以需要有图片缩小方法
Image.resize(size, resample=0)
- size – 包含宽高像素数的元祖 (width, height) resample – 可选的重采样滤波器
返回 Image
然后便是最关键之一的解析方法了
接着,遍历每个像素,为每个像素创建对应的 其中
若当前像素并不是肤色,那么跳过本次循环,继续遍历
若当前像素是肤色像素,那么就需要处理了,先遍历其相邻像素
一定要注意相邻像素的索引值,因为像素的 值是从 1 开始编起的,而索引是从 0 编起的。变量 是存有当前像素的 值, 所以当前像素在 中的索引值为 ,以此类推,那么其左方的相邻像素在 中的索引值为 ,左上方为 ,上方为 ,右上方为
说起来复杂,其实看上面代码并不复杂,说这么多是怕同学搞混,你要是觉得有点绕的话,你也可以把
这个方法接收两个区域号,它将会把两个区域号添加到 中的元素中,检测的图像里,有些前几行的像素的相邻像素并没有 4 个,所以需要用
然后相邻像素的若是肤色像素,如果两个像素的皮肤区域号都为有效值且不同,因为两个区域中的像素相邻,那么其实这两个区域是连通的,说明需要合并这两个区域。记录下此相邻肤色像素的区域号,之后便可以将当前像素归到这个皮肤区域里了。
遍历完所有相邻像素后,分两种情况处理
- 所有相邻像素都不是肤色像素:发现了新的皮肤区域
- 存在区域号为有效值的相邻肤色像素:region 的中存储的值有用了,把当前像素归到这个相邻像素所在的区域
somenamedtuple._replace(kwargs)
- 返回一个替换指定字段的值为参数的
namedtuple
遍历完所有像素之后,图片的皮肤区域划分初步完成了,只是在变量
方法 方法 ,运用之前在程序原理一节定义的非色情图像判定规则,从而得到判定结果现在编写我们还没写过的调用过的 首先是
颜色模式的转换并不是本实验的重点,转换公式可以在网上找到,这里我们直接拿来用就行
方法主要是对 方法接收两个区域号,将之添加到
这两个区域号以怎样的形式添加,要分3种情况处理,
- 传入的两个区域号都存在于
- 传入的两个区域号有一个区域号存在于
- 传入的两个区域号都不存在于
具体的处理方法,见代码
在序列中循环时,索引位置和对应值可以使用 enumerate() 函数同时得到,在上面的代码中,索引位置即为 ,对应值即为 方法则是将
方法只将像素数大于指定数量的皮肤区域保留到
然后可以组织下分析得出的信息
前面的代码中我们有获得图像的像素的 RGB 值的操作,设置像素的 RGB 值也就是其逆操作,还是很简单的,不过注意设置像素的 RGB 值时不能在原图上操作
变量 最后支持一下命令行参数就大功告成啦!我们使用
具体使用方法请查看argparse的 官方文档,这里就不多说了
2.4. 测试效果
使用 把这两个测试用图片下载下来
假设你的脚本名为 nude.py,运行下面的命令执行脚本,注意是 而不是
现在你可以等待程序结果,结果出来后,你还可以查看
本次实验熟悉了下 PIL 的使用,了解了****检测的原理,整个实验难点是在皮肤区域的检测与整合这一方面,这方面不是很清楚的同学多多阅读思考,如果有什么疑问或者建议的话可以留言,实验楼会尽力解答你的问题,建议写下实验报告,将自己的思考过程记录下来是很有好处的
本实验还有许多可以改进的地方,比如肤色检测的公式,色情判定条件,还有性能问题,同学可以自己尝试改进,比如性能问题可以尝试多线程或多进程
代码也可以下载下来
代码:
本实验将使用 Python3 去识别图片是否为****,我们会使用到 PIL 这个图像处理库,会编写算法来划分图像的皮肤区域
1.1. 知识点
- Python 3 的模块的安装
- Python 3 基础知识
- 肤色像素检测与皮肤区域划分算法
- Pillow 模块的使用
- argparse 模块的使用
1.2. 效果展示
2.1. 安装包
PIL 2009年之后就没有更新了,也不支持 Python3 ,于是有了 Alex Clark 领导的公益项目 Pillow,Pillow 是一个对 PIL 友好的分支,支持 Python3,所以我们这里安装的是 Pillow,其官方文档
安装前更新源
首先我们需要处理一个问题:当前实验楼的环境中 python3 命令使用的 Python 版本为 3.5,但源中却没有 python3.5-dev,这会导致安装 Pillow 出错。所以我们必须将 python3 命令使用的 python 版本切换为 3.4,然后再安装 python3-dev 和 python3-setuptools。
然后安装 Pillow 依赖包
安装 , 是 Python2 的软件包管理系统,使用它来安装 Python2 的模块非常简便,而
最后安装 Pillow:
2.2. 程序原理
本程序根据颜色(肤色)找出图片中皮肤的区域,然后通过一些条件判断是否为****
程序的关键步骤如下
- 遍历每个像素,检测像素颜色是否为肤色
- 将相邻的肤色像素归为一个皮肤区域,得到若干个皮肤区域
- 剔除像素数量极少的皮肤区域
我们定义非****的判定规则如下(满足任意一个判定为真):
- 皮肤区域的个数小于 3 个
- 皮肤区域的像素与图像所有像素的比值小于 15%
- 最大皮肤区域小于总皮肤面积的 45%
- 皮肤区域数量超过60个
这些规则你可以尝试更改,直到程序效果让你满意为止
关于像素肤色判定这方面,公式可以在网上找到很多,但世界上不可能有正确率 100% 的公式
你可以用自己找到的公式,在程序完成后慢慢调试
- RGB 颜色模式
第一种:
- 第二种:
- ,
- HSV 颜色模式
- YCbCr 颜色模式
一幅图像有零个到多个的皮肤区域,程序按发现顺序给它们编号,第一个发现的区域编号为 0,第 n 个发现的区域编号为 n-1
我们用一种类型来表示像素,我们给这个类型取名为 ,包含了像素的一些信息:唯一的 编号(),是/否肤色(),皮肤区域号(),横坐标(),纵坐标()遍历所有像素时,我们为每个像素创建一个与之对应的 其中 属性即为像素所在的皮肤区域编号,创建对象时初始化为无意义的
关于每个像素的 id 值,左上角为原点,像素的 id 值按像素坐标排布,那么看起来如下图
其实 id 的顺序也即遍历的顺序

遍历所有像素时,创建
相邻像素的定义:通常都能想到是当前像素周围的 8 个像素,然而实际上只需要定义 4
接下来实现细节部分
2.3. 实现脚本
导入所需要的模块
我们将设计一个
这个类里面我们首先使用 定义一个
函数实际上是一个返回Python中标准元组类型子类的一个工厂方法。 你需要传递一个类型名和你需要的字段给它,然后它就会返回一个类,你可以初始化这个类,为你定义的字段传递值等。 详情参见官方文档。然后定义
本实验代码中使用到的模块中的函数均可以在其模块的文档中找到,一定要培养查阅文档的习惯
isinstane(object, classinfo)
- 如果参数
object
- 是参数
classinfo
- 的实例,返回真,否则假;参数
classinfo
- 可以是一个包含若干
type
- 对象的元祖,如果参数
object
涉及到效率问题,越大的图片所需要消耗的资源与时间越大,因此有时候可能需要对图片进行缩小
所以需要有图片缩小方法
Image.resize(size, resample=0)
- size – 包含宽高像素数的元祖 (width, height) resample – 可选的重采样滤波器
返回 Image
然后便是最关键之一的解析方法了
接着,遍历每个像素,为每个像素创建对应的 其中
若当前像素并不是肤色,那么跳过本次循环,继续遍历
若当前像素是肤色像素,那么就需要处理了,先遍历其相邻像素
一定要注意相邻像素的索引值,因为像素的 值是从 1 开始编起的,而索引是从 0 编起的。变量 是存有当前像素的 值, 所以当前像素在 中的索引值为 ,以此类推,那么其左方的相邻像素在 中的索引值为 ,左上方为 ,上方为 ,右上方为
说起来复杂,其实看上面代码并不复杂,说这么多是怕同学搞混,你要是觉得有点绕的话,你也可以把
这个方法接收两个区域号,它将会把两个区域号添加到 中的元素中,检测的图像里,有些前几行的像素的相邻像素并没有 4 个,所以需要用
然后相邻像素的若是肤色像素,如果两个像素的皮肤区域号都为有效值且不同,因为两个区域中的像素相邻,那么其实这两个区域是连通的,说明需要合并这两个区域。记录下此相邻肤色像素的区域号,之后便可以将当前像素归到这个皮肤区域里了。
遍历完所有相邻像素后,分两种情况处理
- 所有相邻像素都不是肤色像素:发现了新的皮肤区域
- 存在区域号为有效值的相邻肤色像素:region 的中存储的值有用了,把当前像素归到这个相邻像素所在的区域
somenamedtuple._replace(kwargs)
- 返回一个替换指定字段的值为参数的
namedtuple
遍历完所有像素之后,图片的皮肤区域划分初步完成了,只是在变量
方法 方法 ,运用之前在程序原理一节定义的非色情图像判定规则,从而得到判定结果现在编写我们还没写过的调用过的 首先是
颜色模式的转换并不是本实验的重点,转换公式可以在网上找到,这里我们直接拿来用就行
方法主要是对 方法接收两个区域号,将之添加到
这两个区域号以怎样的形式添加,要分3种情况处理,
- 传入的两个区域号都存在于
- 传入的两个区域号有一个区域号存在于
- 传入的两个区域号都不存在于
具体的处理方法,见代码
在序列中循环时,索引位置和对应值可以使用 enumerate() 函数同时得到,在上面的代码中,索引位置即为 ,对应值即为 方法则是将
方法只将像素数大于指定数量的皮肤区域保留到
然后可以组织下分析得出的信息
前面的代码中我们有获得图像的像素的 RGB 值的操作,设置像素的 RGB 值也就是其逆操作,还是很简单的,不过注意设置像素的 RGB 值时不能在原图上操作
变量 最后支持一下命令行参数就大功告成啦!我们使用
具体使用方法请查看argparse的 官方文档,这里就不多说了
2.4. 测试效果
使用 把这两个测试用图片下载下来
假设你的脚本名为 nude.py,运行下面的命令执行脚本,注意是 而不是
现在你可以等待程序结果,结果出来后,你还可以查看
本次实验熟悉了下 PIL 的使用,了解了****检测的原理,整个实验难点是在皮肤区域的检测与整合这一方面,这方面不是很清楚的同学多多阅读思考,如果有什么疑问或者建议的话可以留言,实验楼会尽力解答你的问题,建议写下实验报告,将自己的思考过程记录下来是很有好处的
本实验还有许多可以改进的地方,比如肤色检测的公式,色情判定条件,还有性能问题,同学可以自己尝试改进,比如性能问题可以尝试多线程或多进程
代码也可以下载下来
代码:

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/195651.html