Python3 色情图片识别

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

Python 3 色情图片识别

一、实验简介

本实验将使用 Python3 去识别图片是否为色情图片,我们会使用到 PIL 这个图像处理库,会编写算法来划分图像的皮肤区域

1.1. 知识点

  • Python 3 的模块的安装
  • Python 3 基础知识
  • 肤色像素检测与皮肤区域划分算法
  • Pillow 模块的使用
  • argparse 模块的使用

1.2. 效果展示

二、实验步骤

2.1. 安装包

PIL 2009年之后就没有更新了,也不支持 Python3 ,于是有了 Alex Clark 领导的公益项目 Pillow,Pillow 是一个对 PIL 友好的分支,支持 Python3,所以我们这里安装的是 Pillow,其官方文档

安装前更新源

$ sudo apt-get update

首先我们需要处理一个问题:当前实验楼的环境中 python3 命令使用的 python 版本为 3.5,但源中却没有 python3.5-dev,这会导致安装 Pillow 出错。所以我们必须将 python3 命令使用的 python 版本切换为 3.4,然后再安装 python3-dev 和 python3-setuptools。

$ sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.4 70 --slave /usr/bin/python3m python3m /usr/bin/python3.4m$ sudo apt-get install python3-dev python3-setuptools

然后安装 Pillow 依赖包

$ sudo apt-get install libtiff5-dev libjpeg8-dev zlib1g-dev \    libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python-tk

安装 pip3pip 是 Python2 的软件包管理系统,使用它来安装 Python2 的模块非常简便,而 pip3 则是对应于 Python3 的版本

$ sudo apt-get install python3-pip

最后安装 Pillow:

$ sudo pip3 install Pillow

2.2. 程序原理

本程序根据颜色(肤色)找出图片中皮肤的区域,然后通过一些条件判断是否为色情图片

程序的关键步骤如下

  1. 遍历每个像素,检测像素颜色是否为肤色
  2. 将相邻的肤色像素归为一个皮肤区域,得到若干个皮肤区域
  3. 剔除像素数量极少的皮肤区域

我们定义非色情图片的判定规则如下(满足任意一个判定为真):

  1. 皮肤区域的个数小于 3 个
  2. 皮肤区域的像素与图像所有像素的比值小于 15%
  3. 最大皮肤区域小于总皮肤面积的 45%
  4. 皮肤区域数量超过60个

这些规则你可以尝试更改,直到程序效果让你满意为止

关于像素肤色判定这方面,公式可以在网上找到很多,但世界上不可能有正确率 100% 的公式

你可以用自己找到的公式,在程序完成后慢慢调试

  • RGB 颜色模式

    第一种:r > 95 and g > 40 and g < 100 and b > 20 and max([r, g, b]) - min([r, g, b]) > 15 and abs(r - g) > 15 and r > g and r > b

    第二种:nr = r / (r + g + b), ng = g / (r + g + b), nb = b / (r +g + b)nr / ng > 1.185 and r * b / (r + g + b) ** 2 > 0.107 and r * g / (r + g + b) ** 2 > 0.112

  • HSV 颜色模式

    h > 0 and h < 35 and s > 0.23 and s < 0.68

  • YCbCr 颜色模式

    97.5 <= cb <= 142.5 and 134 <= cr <= 176

一幅图像有零个到多个的皮肤区域,程序按发现顺序给它们编号,第一个发现的区域编号为 0,第 n 个发现的区域编号为 n-1

我们用一种类型来表示像素,我们给这个类型取名为 Skin,包含了像素的一些信息:唯一的 编号(id),是/否肤色(skin),皮肤区域号(region),横坐标(x),纵坐标(y

遍历所有像素时,我们为每个像素创建一个与之对应的 Skin 对象,并设置对象的所有属性

其中 region 属性即为像素所在的皮肤区域编号,创建对象时初始化为无意义的 None

关于每个像素的 id 值,左上角为原点,像素的 id 值按像素坐标排布,那么看起来如下图

其实 id 的顺序也即遍历的顺序

遍历所有像素时,创建 Skin 对象后,如果当前像素为肤色,且相邻的像素有肤色的,那么我们把这些肤色像素归到一个皮肤区域

相邻像素的定义:通常都能想到是当前像素周围的 8 个像素,然而实际上只需要定义 4 个就可以了,位置分别在当前像素的左方,左上方,正上方,右上方;因为另外四个像素都在当前像素后面,我们还未给这4个像素创建对应的 Skin 对象

接下来实现细节部分

2.3. 实现脚本

导入所需要的模块

import sysimport osimport _iofrom collections import namedtuplefrom PIL import Image

我们将设计一个 Nude 类:

class Nude(object):

这个类里面我们首先使用 collections.namedtuple() 定义一个 Skin 类型

Skin = namedtuple("Skin", "id skin region x y")

collections.namedtuple() 函数实际上是一个返回Python中标准元组类型子类的一个工厂方法。 你需要传递一个类型名和你需要的字段给它,然后它就会返回一个类,你可以初始化这个类,为你定义的字段传递值等。 详情参见官方文档

然后定义 Nude 类的初始化方法

def __init__(self, path_or_image):    # 若 path_or_image 为 Image.Image 类型的实例,直接赋值    if isinstance(path_or_image, Image.Image):        self.image = path_or_image    # 若 path_or_image 为 str 类型的实例,打开图片    elif isinstance(path_or_image, str):        self.image = Image.open(path_or_image)    # 获得图片所有颜色通道    bands = self.image.getbands()    # 判断是否为单通道图片(也即灰度图),是则将灰度图转换为 RGB 图    if len(bands) == 1:        # 新建相同大小的 RGB 图像        new_img = Image.new("RGB", self.image.size)        # 拷贝灰度图 self.image 到 RGB图 new_img.paste (PIL 自动进行颜色通道转换)        new_img.paste(self.image)        f = self.image.filename        # 替换 self.image        self.image = new_img        self.image.filename = f    # 存储对应图像所有像素的全部 Skin 对象    self.skin_map = []    # 检测到的皮肤区域,元素的索引即为皮肤区域号,元素都是包含一些 Skin 对象的列表    self.detected_regions = []    # 元素都是包含一些 int 对象(区域号)的列表    # 这些元素中的区域号代表的区域都是待合并的区域    self.merge_regions = []    
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值