简介
使用雅虎开源的 TensorFlow 2 Open-NSFW 模型,NSFW:not safe for work,工作场所不宜
实践
1.环境准备,
Python 3.7 及以上,安装 opennsfw2 库。图片素材请参考 小结中地址进行下载。
pip install opennsfw2
2.代码实践
图片识别 代码如下:
import opennsfw2 as n2# 将自动下载预训练模型 open_nsfw_weights.h5 到 C:\Users\Administrator\.opennsfw2\weights# pip install opennsfw2# 单张预测image_path = '1.jpg'nsfw_probability = n2.predict_image(image_path)print(nsfw_probability)# 0.16282974183559418# 批量预测image_paths = ['1.jpg', '2.jpg']nsfw_probabilities = n2.predict_images(image_paths)print(nsfw_probabilities)# [0.16282965242862701, 0.8638442158699036]
视频识别 代码如下:
import opennsfw2 as n2 video_path = '1.mp4'elapsed_seconds, nsfw_probabilities = n2.predict_video_frames(video_path)for second, probability in zip(elapsed_seconds, nsfw_probabilities): print(f'{second:.2f}s: {probability * 100:.0f} %')# 0.03s: 1%# ...# 10.01s: 87.00%# ...# 10.64s: 69.00%
高级用法
1. 加载的方式
import numpy as npfrom PIL import Imagefrom opennsfw2._model import make_open_nsfw_modelfrom opennsfw2._image import preprocess_image, Preprocessing image_path = '1.jpg'image = preprocess_image(Image.open(image_path), Preprocessing.YAHOO)model = make_open_nsfw_model()nsfw_probability = float(model.predict(np.expand_dims(image, 0), batch_size=1)[0][1])print(nsfw_probability)# 0.16282974183559418
2.车速检测
import timeimport numpy as npimport tkinter as tkfrom pathlib import Pathfrom tkinter import filedialogfrom tkinter import messageboxfrom PIL import ImageTk, Imagefrom opennsfw2._model import make_open_nsfw_modelfrom opennsfw2._image import preprocess_image, Preprocessing begin = time.time()model = make_open_nsfw_model() # 加载模型elapsed = time.time() - begin # 加载模型耗时initialdir = Path.cwd() # 初始化目录,可切换为图片Path.home() / 'Pictures'img = None # 当前打开的图片def scale(size, width=None, height=None): """获取按比例缩放后的宽高""" if not width and not height: width, height = size if not width or not height: _width, _height = size height = width * _height / _width if width else height width = height * _width / _height if height else width return int(width), int(height)def img_resize(event=None): """显示图片""" global img if img: _img = img.resize(scale(img.size, height=win.winfo_height())) _img = ImageTk.PhotoImage(_img) label.config(image=_img) label.image = _imgdef on_closing(): """关闭事件""" if messagebox.askokcancel('关闭', '是否退出程序?'): win.destroy()def open_file(event=None): """打开图片""" global initialdir global img file_path = filedialog.askopenfilename(title='选择图片', initialdir=initialdir, filetypes=[('image files', ('.png', '.jpg', '.jpeg', '.gif'))]) if file_path: statusbar.config(text='正在加载...') statusbar.update_idletasks() begin = time.time() path = Path(file_path) initialdir = path.parent img = Image.open(file_path) img_resize() _img = preprocess_image(Image.open(file_path), Preprocessing.YAHOO) probability = float(model.predict(np.expand_dims(_img, 0), batch_size=1)[0][1]) print(probability) end = time.time() statusbar.config(text=f'{path.name} 耗时: {end - begin:.2f}s 概率: {probability * 100:.2f} %')win = tk.Tk()win.title('黄图检测') # 标题menu = tk.Menu(win)menu.add_command(label='打开', command=open_file)win.config(menu=menu)win.bind('<Configure>', img_resize)win.geometry('600x300+300+300')win.minsize(200, 200)win.protocol('WM_DELETE_WINDOW', on_closing)statusbar = tk.Label(win, text=f'加载模型耗时: {elapsed:.2f}s', bd=1, relief=tk.SUNKEN, anchor=tk.W, name='statusbar')statusbar.pack(side=tk.BOTTOM, fill=tk.X)label = tk.Label(win, text='双击打开图片')label.bind('<Double-Button-1>', open_file)label.pack(fill=tk.BOTH, expand=True)win.mainloop()
3. 视频车速检测(无声)
import timeimport threadingimport tkinter as tkfrom pathlib import Pathfrom tkinter import filedialogfrom tkinter import messageboxfrom timeit import default_timer as timerimport imageioimport numpy as npfrom PIL import ImageTk, Imagefrom opennsfw2._model import make_open_nsfw_modelfrom opennsfw2._image import preprocess_image, Preprocessing# pip install imageio-ffmpegbegin = time.time()model = make_open_nsfw_model() # 加载模型elapsed = time.time() - begin # 加载模型耗时initialdir = Path.cwd() # 初始化目录,可切换为图片Path.home() / 'Pictures'reader = None # 视频读取器accum_time = 0curr_fps = 0last_fps = 0prev_time = timer()def on_closing(): """关闭事件""" if messagebox.askokcancel('关闭', '是否退出程序?'): win.destroy()def play(): global reader global prev_time, accum_time, curr_fps for image in reader: image = Image.fromarray(image) frame_image = ImageTk.PhotoImage(image) label.config(image=frame_image) label.image = frame_image _img = preprocess_image(image, Preprocessing.YAHOO) probability = float(model.predict(np.expand_dims(_img, 0), batch_size=1)[0][1]) # FPS curr_time = timer() exec_time = curr_time - prev_time prev_time = curr_time accum_time = accum_time + exec_time curr_fps = curr_fps + 1 if accum_time > 1: accum_time = accum_time - 1 last_fps = curr_fps curr_fps = 0 statusbar.config(text=f'概率: {probability * 100:.2f} % FPS: {last_fps}')def open_file(event=None): """打开视频""" global initialdir global reader file_path = filedialog.askopenfilename(title='选择视频', initialdir=initialdir, filetypes=[('Select files', ('.mp4', '.mkv', '.avi', '.wmv'))]) if file_path: statusbar.config(text='正在加载...') statusbar.update_idletasks() path = Path(file_path) initialdir = path.parent reader = imageio.get_reader(path) thread = threading.Thread(target=play, daemon=True) thread.start()win = tk.Tk()win.title('黄图检测') # 标题menu = tk.Menu(win)menu.add_command(label='打开', command=open_file)win.config(menu=menu)win.geometry('1280x720+300+300')win.minsize(200, 200)win.protocol('WM_DELETE_WINDOW', on_closing)statusbar = tk.Label(win, text=f'加载模型耗时: {elapsed:.2f}s', bd=1, relief=tk.SUNKEN, anchor=tk.W, name='statusbar')statusbar.pack(side=tk.BOTTOM, fill=tk.X)label = tk.Label(win, text='双击打开视频')label.bind('<Double-Button-1>', open_file)label.pack(fill=tk.BOTH, expand=True)win.mainloop()
4. 视频车速检测(有声)
import ioimport pygletimport numpy as npfrom PIL import Imagefrom opennsfw2._model import make_open_nsfw_modelfrom opennsfw2._image import preprocess_image, Preprocessing# pip install pygletmodel = make_open_nsfw_model()filename = '1.mp4'source = pyglet.media.load(filename)video_format = source.video_format width, height = video_format.width, video_format.height title = 'Video Player'window = pyglet.window.Window(width, height, title)player = pyglet.media.Player()player.queue(source)player.play()@window.eventdef on_draw(): window.clear() if player.source and player.source.video_format: player.get_texture().blit(0, 0, width=width, height=height) image_data = player.get_texture().get_image_data() pitch = -(image_data.width * len('RGB')) data = image_data.get_data('RGB', pitch) _img = preprocess_image(Image.frombytes('RGB', (width, height), data, 'raw'), Preprocessing.YAHOO) probability = float(model.predict(np.expand_dims(_img, 0), batch_size=1)[0][1]) print(probability)pyglet.app.run()
运行结果:文章来源:https://www.toymoban.com/news/detail-541949.html
效率分析: get_data() 0.941 s frombytes() 0.001 s preprocess_image() 0.006 s predict() 0.052 s
小结
参考: https://blog.csdn.net/lly1122334/article/details/121247781
https://github.com/bhky/opennsfw2文章来源地址https://www.toymoban.com/news/detail-541949.html
到了这里,关于Python:使用opennsfw2对图片/视频进行鉴黄识别的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!