import math import cv2 import logging import numpy as np import random as rd NO_MOD = 0 FACE_GLITCH = 1 FACE_DRAG = 2 EYE_CENSOR = 3 EYE_DRAG = 4 EYES = 100 FACE = 101 logger = logging.getLogger("mods") # The following function is used to determine the placement of # text, at the moment it is incomplete # function takes corners and text # and resturns top left corner that # centers text and the angle needed def pos_and_angle(pts): # find left top most coordinate dist = np.inf # left = pts[0] for cr in pts: if (cr[0] ** 2 + cr[1] ** 2) ** 0.5 < dist: dist = (cr[0] ** 2 + cr[1] ** 2) ** 0.5 # left = cr # first find angle return 1 def determine_face_mod(eyes_present): function_list = [ (lambda x, y: x, FACE), (face_glitch, FACE), (face_drag, FACE), (eye_censor, EYES), (eye_drag, EYES) ] function_index = rd.randint(0, 4) if eyes_present else rd.randint(0, 2) return function_list[function_index] def eye_drag(img, eyes): # make sure there are only two eyes per face if len(eyes) > 2: eye1 = eyes[0] eye2 = eyes[0] size = 0 for itr in range(0, len(eyes)): if eyes[itr][2] * eyes[itr][3] > size: size = eyes[itr][2] * eyes[itr][3] eye1 = eyes[itr] size = 0 for itr in range(0, len(eyes)): if eyes[itr][2] * eyes[itr][3] > size and not np.array_equal(eyes[itr], eye1): size = eyes[itr][2] * eyes[itr][3] eye2 = eyes[itr] eyes = [eye1, eye2] # there should only be two eyes now for eye in eyes: # find width of eye iwid = eye[2] strp = int(round(iwid / 20.)) num_glitches = int(eye[2] / strp) line = rd.randint(1, eye[3]) line += eye[1] line = int(eye[1] + eye[3] / 2) for itr in range(0, num_glitches): # edit the second parameter to change eye drop chance drop = rd.randint(10, 200) # if the line drop is too low, shorten it if line + drop > img.shape[0]: drop = img.shape[0] - line img[line:line + drop, eye[0] + itr * strp:eye[0] + itr * strp + strp] = \ img[line, eye[0] + itr * strp:eye[0] + itr * strp + strp] def eye_censor(img, eyes): if len(eyes) < 2: logger.warning("Failed to generate censor, less than two eyes present") return # cenH = 40 # get centroids of eyes c1 = np.array([eyes[0][0] + eyes[0][2] / 2.0, eyes[0][1] + eyes[0][3] / 2.0]) c2 = np.array([eyes[1][0] + eyes[1][2] / 2.0, eyes[1][1] + eyes[1][3] / 2.0]) # find the corners of the bar # find vector of the two centroids vec = c1 - c2 # unitize vector vec = vec / (vec[0] ** 2.0 + vec[1] ** 2.0) ** 0.5 # perpendicular vector per_vec = np.array([vec[1], vec[0] * (-1)]) # change these value to adjust height and width of # censor bar w_ex = 40 mag = 75 cr1 = per_vec * w_ex + c1 cr2 = c1 - per_vec * w_ex cr3 = per_vec * w_ex + c2 cr4 = c2 - per_vec * w_ex cr1 += vec * mag cr2 += vec * mag cr3 -= vec * mag cr4 -= vec * mag # round all values pts = np.array([cr1, cr2, cr4, cr3]) cv2.fillPoly(img, np.array([pts], dtype=np.int32), (0, 0, 0)) ######################################################### # The following code is incomplete. It's purpose is to randomly # add text to the censor bar # roll to see if to add text # textc = rd.randint(0,2) # textc = 1 # if textc == 1: # text = open("elements/censor.txt","r") # allText = text.read() # possText = allText.split(";") # dec = rd.randint(0,len(possText)) # use = possText[dec] # #calculate text position and angle # # info = posAndAngle(pts,use) # font = cv2.FONT_HERSHEY_SIMPLEX # cv2.putText(img,use,(int(cr1[0]),int(cr1[1])), font, 1,(255,255,255),2,cv2.LINE_AA) ############################################################ def face_drag(img, face): h, w, d = img.shape # 0 is horizontal 1 is veritical ornt = rd.randint(0, 2) if ornt == 0: line = rd.randint(face[1] + 25, face[1] + face[3] - 25) # 0 is up 1 is down direction = rd.randint(0, 2) if direction == 0: img[0:line, face[0]:face[0] + face[2]] = img[line, face[0]:face[0] + face[2]] else: img[line:h, face[0]:face[0] + face[2]] = img[line, face[0]:face[0] + face[2]] else: line = rd.randint(face[0] + 25, face[0] + face[2] - 25) # 0 is left 1 is right direction = rd.randint(0, 2) if direction == 0: img[face[1]:face[1] + face[3], 0:line] = img[face[1]:face[1] + face[3], line:line + 1] else: img[face[1]:face[1] + face[3], line:w] = img[face[1]:face[1] + face[3], line:line + 1] def face_glitch(img, face): height, width, d = img.shape # pixels segments of 40 div = rd.randint(10, 100) strp = int(round(face[3] / (div * 1.0))) num_glitches = face[3] / strp if type(num_glitches) == np.float64: num_glitches = math.floor(num_glitches) for itr in range(0, num_glitches): # play with the second parameter to increase "glitchiness" rng = rd.randint(15, 100) right_ext = face[0] + face[2] + rng left_ext = face[0] + face[2] - rng # make sure extremes don't go out of bounds if left_ext < 0: left_ext = 0 if right_ext >= width: right_ext = width # randomize static direction # 1 moves left, 2 moves right dec = rd.randint(1, 2) back_bound = face[0] + rng if dec % 2 == 0: diff = 0 # make corrections if glitch falls outside of image if face[0] + face[2] + rng >= width: diff = face[0] + face[2] + rng - width img[face[1] + (itr * strp):face[1] + (itr * strp + strp), (face[0] + rng):right_ext] = \ img[face[1] + (itr * strp):face[1] + (itr * strp + strp), face[0]:face[0] + face[2] - diff] else: diff = 0 # make corrections if glitch falls outside of image if back_bound < 0: diff = abs(back_bound) back_bound = 0 old = img[face[1] + (itr * strp):face[1] + (itr * strp + strp), back_bound:left_ext] new = img[face[1] + (itr * strp):face[1] + (itr * strp + strp), face[0]:face[0] + face[2] - diff] if old.shape != new.shape: logger.warning("Shape mismatch: %s vs %s" % (old.shape, new.shape, )) return img[face[1] + (itr * strp):face[1] + (itr * strp + strp), back_bound:left_ext] = \ img[face[1] + (itr * strp):face[1] + (itr * strp + strp), face[0]:face[0] + face[2] - diff]