├── .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 |
4 |
5 |
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 | > 
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 |
4 |
5 |
6 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
--------------------------------------------------------------------------------