我们一般接触到的图像识别技术多是各大搜索引擎的图片搜索,在这方面做的最好的非Google莫属。我曾经几次想找到手上的图片源图,分别用了Google、Bing、360、baidu等,Google对于有版权的图片,不只是推荐相似图片,第一条结果就是摄影师的官网,第二条结果是其Faceboook地址。而度娘对图片的判断是星空倒是没错,但推荐的图片简直就是侮辱人类的智商。(星空图见底部)
下面这个Demo仅是测试用例,源于项目中用的直播和图片鉴黄辅助监控。从最简单的方法入手,就是用 YCbCr 色彩空间来提取Cb和Cr色度分量,判断其肤色范围比重,方法简单误差自然也就大,作为人工辅助工具使用还是可以的。再优化一下,可以先定位身体位置,然后再进行色量判断。再复杂的方案可以做特征“指纹”分析,或对已有类型标记的图片库做AI学习,根据学习的结果数据库对图片进行鉴定分析,这只能交给专业领域的人去做了。
这里使用YCbCr方法做一个简单测试:
from PIL import Image import os, glob def get_skin_ratio(im): im = im.crop((int(im.size[0]*0.2), int(im.size[1]*0.2), im.size[0]-int(im.size[0]*0.2), im.size[1]-int(im.size[1]*0.2))) skin = sum([count for count, rgb in im.getcolors(im.size[0]*im.size[1]) if rgb[0]>60 and rgb[1]<(rgb[0]*0.85) and rgb[2]<(rgb[0]*0.7) and rgb[1]>(rgb[0]*0.4) and rgb[2]>(rgb[0]*0.2)]) return float(skin)/float(im.size[0]*im.size[1]) def ck_img_ratio(image_file): skin_percent = get_skin_ratio(Image.open(image_file)) * 100 return '{0:.0f}'.format(skin_percent) def image_ifo(image): try: img = Image.open(image) except Exception as e: print("Can not open the image!") return img def preprocessed_image(image): img = image_ifo(image) if not img.mode == 'YCbCr': img = img.convert('YCbCr') return img def detector(image): img = preprocessed_image(image) ycbcr_data = img.getdata() W,H = img.size count = 0 for i,ycbcr in enumerate(ycbcr_data): y,cb,cr = ycbcr if 86 <= cb <= 117 and 140 <= cr <= 168: count += 1 return format(count/(W*H), '.0%') def each_dir_file(): for image_dir in ('d1','d2','d3'): print("-" * 30, "Dir : ", image_dir) fun1 = fun2 = '' for image_file in glob.glob(os.path.join(image_dir,"*.jpg")): fun1 += '{0:3}-'.format(detector(image_file)) fun2 += '{0:3}-'.format(ck_img_ratio(image_file)) print('M1:', fun1) print('M2:', fun2) if __name__ == '__main__': each_dir_file()
结果分析:Demo中使用了两种计算方法(M1、M2)。在包含风景和人物的目录d1中,结果超出30%的图片有4张,其中91%那张其实是沙地,因为和肤色接近,所以值也比较较高;比基尼居多的d2目录,命中结果还是比较高的;但d3目录只所以结果值都比较低,主要是受肤色影响。
------------------------------ Dir : d1 M1: 0% -8% -17%-1% -5% -56%-11%-15%-2% -2% -7% -1% -91%-18%-4% -39%-11%-4% -0% -12%-28%-37%-3% -10%- M2: 0 -18 -20 -1 -12 -34 -31 -27 -5 -5 -17 -2 -84 -36 -8 -25 -10 -11 -0 -15 -12 -28 -6 -13 - ------------------------------ Dir : d2 M1: 74%-42%-34%-40%-77%-45%-31%-42%-67%-58%-44%-40%-48%-69%-35%-21%-58%-28%-30%-57%-6% -9% - M2: 78 -58 -63 -31 -95 -63 -57 -58 -63 -61 -66 -55 -49 -71 -54 -43 -48 -59 -43 -65 -4 -10 - ------------------------------ Dir : d3 M1: 7% -25%-20%-0% -56%- M2: 17 -32 -25 -0 -36 -
上述Demo是对全图的分析,在此基础上我们可以先识别身体特征,比如图片中是否有面部,上半身,下半身。如果监测到这些部位,再对此部位进行局部色量分析,如果有面部特征,可以提取面部的色量值,然后根据此值来分析身体色量值,做到适应肤色判断。对身体的分析OpenCV默认提供的特征库效果一般般,成功率很低,这里也就没在继续测试。
另外也可以使用一些第三方的分析方案,如:阿里、腾讯云、Clarifai(擅长图片视频深度学习,很NB的样子,目前提供多种API服务)...