效果展示
先看下效果:
这里通过网页上传图片,服务器接收到图片后保存到本地,再将图片路径传给Tensorflow服务,Tensorflow服务进行图片打分,再将分值返回到网页。
上传图片
在电脑本地选择您的图片,目前不支持网页链接。如图(1),选择了一个本地文件,点击“submit”按钮即可。
图片(1)
给图片打分
Tensorflow服务将评分返回给网页,网页进行显示。
图片(2)
目前Tensorflow模型里只有4个分类,分别是sexy(性感)、porn(真人淫秽)、hentai(卡通淫秽)、neutral(中性事物)、drawing(手绘漫画)
这个图片sexy打分达到了82.74%很明显属于性感类的图片了。其他的图片大家可以在服务搭建起来后自行测试。
开发情景
这个模型通过 https://github.com/alexkimxyz/nsfw_data_scraper 这个开源项目里的图片训练而成,训练后的模型放到了inception_model目录中,大家可以直接拿来使用。训练过程略过吧,要是讲的话就太多了。
项目使用说明
项目里的三个重要文件
TornadoServer.py
这个是python的Tornado服务器,用于搭建服务器。
TFServer.py
这个是Tensorflow服务,用于对图片打分。
UploadFile.html
这个就是网站首页了。如图(1)所示。
运行方式
第一步,需要将Tensorflow服务运行起来,执行TFServer.py这个文件。
第二步,启动Web服务器,执行TornadoServer.py这个文件。
第三步,在浏览器中打开http://127.0.0.1:8888/file这个地址,就是图片(1)显示的内容了。
上传图片的存储
当用户上传图片后,TornadoServer会将图片存在本地,不同的IP地址放在不同的文件夹中,文件以上传的时间点重新命名。
如图可见,192.168.10.19这个IP上传了多张图片,图片的名称按照时间点重新进行了命名。
代码讲解
TornadoServer
def post(self): # 文件的暂存路径 upload_path = os.path.join(os.path.dirname(__file__) + '/static', str(self.request.remote_ip)) if(os.path.exists(upload_path) == False): os.makedirs(upload_path)
file_metas = self.request.files['file'] #提取表单中‘name’为‘file’的文件元数据 fileData = file_metas[0] fileName = fileData['filename'] arr = os.path.splitext(fileName) extFileName = arr[len(arr) - 1] fileType = fileData['content_type'] print(fileName) print(fileType) #这里判断图片是否为jpeg格式的文件,将其他格式的图片进行了过滤。 if (operator.eq(fileType, 'image/jpeg') == False): self.write('请上传JPEG格式的图片!') return else: fileNameTime = self.getFileName() fileName = fileNameTime + extFileName fileFullName = os.path.join(upload_path, fileName) #将用户上传的图片进行本地化存储。 with open(fileFullName, 'wb') as up: up.write(fileData['body']) #self.write('finished!') #通过socket管道将图片路径传给Tensorflow服务器 client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) client.connect("/tmp/tfserver.sock") client.send(bytes(fileFullName, 'utf-8')) #接收Tensorflow服务的打分数据 resultbyte = client.recv(1024) resultStr = str(resultbyte, encoding="utf-8") n = fileFullName.find(staticFilePath) imagePath = fileFullName[n:] #将图片源文件和打分数据同时进行显示。 htmlSource = '<!DOCTYPE html> ' \ + '<head> <meta charset="UTF-8"> </head> ' \ + '<body> ' \ + '<p> ' + resultStr + '</p>' \ + '<img src="' + imagePath + '"/>' \ + '</body>' \ + '</html>' print(htmlSource) self.write(htmlSource) return
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
TFServer
with tf.Session() as sess: softmax_tensor = sess.graph.get_tensor_by_name('final_result:0') while True: #这里等待接收用户的图片信息。 connection, address = TFServer.accept() rec = connection.recv(1024) picPath = str(rec, encoding="utf-8") print (picPath) image_data = tf.gfile.GFile(picPath, 'rb').read() predictions = sess.run(softmax_tensor, {'DecodeJpeg/contents:0': image_data}) predictions = np.squeeze(predictions)
top_k = predictions.argsort()[::-1] result = '' for node_id in top_k: human_string = id_to_string(node_id) score = predictions[node_id] buf = ('%s (score = %.2f%%) \n' % (human_string, score*100)) result = result + buf print(result) #将打分结果返回给提交打分申请的客户端 connection.send(bytes(result, 'utf-8')) connection.close()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
这里是部分的代码讲解。如果有那些问题,欢迎给我留言。