nsfw_model icon indicating copy to clipboard operation
nsfw_model copied to clipboard

Detect nsfw in video file

Open xcbtrader opened this issue 6 years ago • 12 comments

Hello. Thank you very much for this excellent work. I'm using it to detect nsfw in video frames. The problem I have is that I can only do it if I extract a frame, save it to disk and then open it and analyze it. I use opencv. Is there any way to directly analyze the frame that gives opencv ?

Let me give you an example

cam = cv2.VideoCapture('video.avi') while(True): ret,frame = cam.read() result = detector.predict(frame) ???????

xcbtrader avatar Apr 13 '19 14:04 xcbtrader

We have a ticket to do it in JavaScript that might be applied soon. But I'm actually not that great at Python. I imagine if you could grab all the keyframes down to a folder, then run all those images in the folder in a single batch, that would be pretty fast.

GantMan avatar Apr 14 '19 19:04 GantMan

@GantMan I think it'd be inaccurate by simply grabbing all keyframes, since keyframes can be defined by producer during transcoding. Therefore, it's possible that we get mislead by producer. On the other hand, given we have so many frames, in case of false positive, we will have a hard time to decide whether it's bad or not. I think we need a model dedicated for video handling

jiangyurong609 avatar Apr 15 '19 15:04 jiangyurong609

What I do is take an image every n frames, see if it is nsfw and if positive I keep it in a directory

xcbtrader avatar Apr 15 '19 18:04 xcbtrader

@xcbtrader what if there are false positives?

jiangyurong609 avatar Apr 15 '19 18:04 jiangyurong609

I keep them as well, and then I look at the directory to check what was analyzed. In the tests I have done, I have found quite a few false positives.

This is the code to decide if is or not nsfw: ` result = detector.predict('temp.jpg') datos = result['temp.jpg']

		nsfw = False
		
		if float(datos['porn']) > float(datos['drawings']) and float(datos['porn']) > float(datos['hentai']) and float(datos['porn']) > float(datos['neutral']) and float(datos['porn']) > float(datos['sexy']) and float(datos['porn']) > 0.93:
			nsfw = True
		else:
			if float(datos['sexy']) > float(datos['drawings']) and float(datos['sexy']) > float(datos['hentai']) and float(datos['sexy']) > float(datos['neutral']) and float(datos['sexy']) > float(datos['porn']) and float(datos['sexy']) > 0.93:
				nsfw = True
		
		if nsfw:

			name = './' 'nude_' + info_video[0] + '/' + info_video[0] + '_' + str(currentframe) + '.jpg'
			print ('Creating...' + name + ' --- ' + str(float(datos['porn'])) + ';' + str(float(datos['sexy']))+ ';' + str(float(datos['neutral']))) 
			cv2.imwrite(name, frame)
			frames_nude += 1

	currentframe += 1`

xcbtrader avatar Apr 15 '19 18:04 xcbtrader

@xcbtrader based on your condition, you will have false negatives. Moreover, you will treat hentai as good content for work.

jiangyurong609 avatar Apr 16 '19 03:04 jiangyurong609

Hentai doesn't worry me. What conditions do you recommend?

xcbtrader avatar Apr 16 '19 04:04 xcbtrader

@xcbtrader Yeah, saving frames to disk and then calling the predict function is very time taking. I will ad a function to process a video directly. I will also add a paramter in that function so that you can select how many frames you want to analyze. eg: n=1 will analyze all frames and n=0.5 will analyze only half of randomly selected frames each second. Would this work for you?

bedapudi6788 avatar Apr 16 '19 09:04 bedapudi6788

I do it differently. I put a variable called n_frames that indicates how many frames it analyzes. For example: If n_frames = 10, it reads frame by frame, and every 10 frames it analyzes. Analyze frame 10, 20, 30, 40 ....

xcbtrader avatar Apr 16 '19 21:04 xcbtrader

@xcbtrader I think you need to define a model to decide whether the video is nsfw based on discrete frame detection output. Moreover, your fixed frames can be cracked if someone intends.

jiangyurong609 avatar Apr 16 '19 22:04 jiangyurong609

@xcbtrader Yeah, saving frames to disk and then calling the predict function is very time taking. I will ad a function to process a video directly. I will also add a paramter in that function so that you can select how many frames you want to analyze. eg: n=1 will analyze all frames and n=0.5 will analyze only half of randomly selected frames each second. Would this work for you?

Has this been implemented yet? I haven't found any reference to this function.

Right now I'm extracting frames from a video with ffmpeg, and sending them in batch to the predict method. I've found that doing this with up to 5 videos at once really kills the CPU. I'm using a 4 core CPU with 8 gigs of RAM. Any recommendation on the hardware requirements part for such a task for analyzing multiple videos at once

remusnegrota avatar Feb 11 '20 13:02 remusnegrota

Nothing in place yet. I'd love to see your solution. This is something we might come back to as more advancements show up in TFJS

GantMan avatar Feb 14 '20 22:02 GantMan