├── .gitignore ├── images ├── 1.jpg ├── 2.jpg ├── 3.jpg └── image.png ├── __pycache__ ├── api.cpython-39.pyc ├── api.cpython-310.pyc ├── main.cpython-310.pyc ├── main.cpython-39.pyc ├── detection.cpython-310.pyc └── detection.cpython-39.pyc ├── init.sh ├── .idea ├── .gitignore ├── misc.xml ├── inspectionProfiles │ ├── profiles_settings.xml │ └── Project_Default.xml ├── vcs.xml ├── modules.xml └── nsfw_detection.iml ├── detection.py ├── api_test.py ├── api.py ├── main.py └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | nsfw_image_detection -------------------------------------------------------------------------------- /images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-zhui/nsfw_detection/HEAD/images/1.jpg -------------------------------------------------------------------------------- /images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-zhui/nsfw_detection/HEAD/images/2.jpg -------------------------------------------------------------------------------- /images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-zhui/nsfw_detection/HEAD/images/3.jpg -------------------------------------------------------------------------------- /images/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-zhui/nsfw_detection/HEAD/images/image.png -------------------------------------------------------------------------------- /__pycache__/api.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-zhui/nsfw_detection/HEAD/__pycache__/api.cpython-39.pyc -------------------------------------------------------------------------------- /__pycache__/api.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-zhui/nsfw_detection/HEAD/__pycache__/api.cpython-310.pyc -------------------------------------------------------------------------------- /__pycache__/main.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-zhui/nsfw_detection/HEAD/__pycache__/main.cpython-310.pyc -------------------------------------------------------------------------------- /__pycache__/main.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-zhui/nsfw_detection/HEAD/__pycache__/main.cpython-39.pyc -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source /root/miniconda3/bin/activate nsfw_detection 3 | uvicorn --host 0.0.0.0 --port 7860 main:app -------------------------------------------------------------------------------- /__pycache__/detection.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-zhui/nsfw_detection/HEAD/__pycache__/detection.cpython-310.pyc -------------------------------------------------------------------------------- /__pycache__/detection.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/a-zhui/nsfw_detection/HEAD/__pycache__/detection.cpython-39.pyc -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # 默认忽略的文件 2 | /shelf/ 3 | /workspace.xml 4 | # 基于编辑器的 HTTP 客户端请求 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/nsfw_detection.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /detection.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import time 3 | 4 | from transformers import pipeline 5 | 6 | classifier = pipeline("image-classification", model="nsfw_image_detection") 7 | 8 | 9 | def execute(image): # image 为pillow格式 10 | start_time = time.time() 11 | detection_result = classifier(image) 12 | logging.info(f'耗时约{round(time.time() - start_time, 2)}s,检测结果{detection_result}') 13 | result_dic = {} 14 | for i in detection_result: 15 | result_dic[i.get('label')] = i.get('score') 16 | return result_dic 17 | -------------------------------------------------------------------------------- /api_test.py: -------------------------------------------------------------------------------- 1 | import base64 2 | 3 | import requests 4 | 5 | 6 | def backend_requests_post(url, json): 7 | headers = {'Connection': 'close', 'token': 'pass'} 8 | response = requests.post(url=url, json=json, headers=headers) 9 | json_data = response.json() 10 | return json_data 11 | 12 | 13 | with open('images/1.jpg', 'rb') as f: 14 | content = f.read() 15 | 16 | content = base64.b64encode(content) 17 | content = content.decode() 18 | 19 | ret = backend_requests_post(url='http://127.0.0.1:7860/api/nsfw_detection', json={ 20 | 'image': content 21 | }) 22 | print(ret) 23 | -------------------------------------------------------------------------------- /api.py: -------------------------------------------------------------------------------- 1 | import base64 2 | from io import BytesIO 3 | 4 | from PIL import Image 5 | from fastapi import FastAPI 6 | from pydantic import BaseModel 7 | 8 | from detection import execute 9 | 10 | app_api = FastAPI() 11 | 12 | 13 | class RequestData(BaseModel): 14 | image: str 15 | 16 | 17 | class ResponseData(BaseModel): 18 | pass 19 | 20 | 21 | @app_api.post('/api/nsfw_detection') 22 | async def nsfw_detection(data: RequestData): 23 | 24 | byte_data = base64.b64decode(data.image) # base64转bytes 25 | image = Image.open(BytesIO(byte_data)) # 将二进制转为PIL格式图片 26 | 27 | result_dic = execute(image) 28 | return result_dic 29 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from detection import execute 3 | import gradio as gr 4 | from api import app_api 5 | 6 | logging.basicConfig(format='[%(filename)s:%(lineno)d] %(asctime)s - %(levelname)s : %(message)s', 7 | datefmt='%Y-%m-%d %H:%M:%S %p', 8 | level=20) 9 | 10 | 11 | def ex(image): 12 | result_dic = execute(image) 13 | 14 | return image, result_dic, result_dic 15 | 16 | 17 | ui = gr.Interface(fn=ex, 18 | title='NSFW 图片检测(色情检测)', 19 | inputs=[gr.Image(label='图片', type='pil')], 20 | outputs=[gr.Image(label='输入', width=300, container=False), gr.Label(label='结果', container=False), gr.JSON(label='json output', container=False)], 21 | allow_flagging='never', 22 | examples=[['images/1.jpg'], ['images/2.jpg'], ['images/3.jpg']] 23 | ) 24 | 25 | ui.queue() 26 | ui.show_api = False 27 | # ui.launch(inbrowser=True, server_name='0.0.0.0', server_port=7860) 28 | 29 | # 将api与ui界面挂载,path为ui界面的访问路径 30 | app = gr.mount_gradio_app(app_api, ui, path='/') 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NSFW DETECTION (色情检测) 2 | > 使用huggingface上的nsfw模型,对 NSFW(工作不安全)图像进行分类。使其过滤各种应用程序中的露骨或不当内容。 3 | > 4 | > ![image.png](images/image.png) 5 | > 6 | > [huggingface地址](https://huggingface.co/Falconsai/nsfw_image_detection) 7 | > 8 | > 在Falconsai/nsfw_image_detection的基础上将其封装成api,并用gradio编写了一个简单的测试界面 9 | > 10 | > api 测试详见项目api_test.py文件 11 | > 12 | > 速度检测快,不用GPU还是很香的 13 | 14 | 15 | ## 使用方式一:python虚拟环境(use with python env) 16 | > 安装 miniconda/anaconda 17 | 18 | ```bash 19 | #clone项目 20 | git clone https://github.com/a-zhui/nsfw_detection 21 | #下载模型文件 模型文件较大(2.6G) 22 | cd nsfw_detection #进入项目根目录 23 | apt-get install git-lfs #模型太大,以至于git仓库容纳不了。所以用git-lfs下载大文件 24 | git lfs install 25 | git clone https://huggingface.co/Falconsai/nsfw_image_detection 26 | ``` 27 | 28 | ```bash 29 | #构建虚拟环境 30 | conda create -n nsfw_detection python=3.10 31 | conda activate nsfw_detection 32 | 33 | pip install torch 34 | pip install transformers 35 | pip install uvicorn 36 | pip install gradio 37 | 38 | ``` 39 | 40 | ```bash 41 | #启动服务 42 | uvicorn --host 0.0.0.0 --port 7860 main:app 43 | ``` 44 | 45 | 46 | 47 | 48 | ## 使用方式二:docker (use with docker container) 49 | ```bash 50 | # 镜像较大12G 51 | docker run -it -d -p 8080:7860 --restart always --workdir /root/nsfw_detection --name nsfw_detection bocai123/nsfw_detection:V1.0 bash -c "bash init.sh" 52 | #docker run -it -d -p 8080:7860 --restart always --workdir /root/nsfw_detection --name nsfw_detection registry.cn-hangzhou.aliyuncs.com/bocai123/nsfw_detection:V1.0 bash -c "bash init.sh" #阿里云镜像 53 | ``` 54 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 121 | --------------------------------------------------------------------------------