visrecall/WebInterface/Front-end/generate-experiment-files/generate_spotlight.py

124 lines
4.5 KiB
Python
Raw Normal View History

2022-07-29 14:22:57 +02:00
from cv2 import cv2
import numpy as np
import re,os
from glob import glob
from PIL import Image
import matplotlib.pyplot as plt
from shutil import rmtree
import pandas as pd
from natsort import natsorted
import imageio
import moviepy.editor as mp
bp = "E:/1Study/Hiwi/Massvis dataset" # change base path to the directory where you have downloaded the salicon data
curdir = 'E:/1Study/Hiwi/massvis/eyetracking/csv_files/fixationsByVis'
eledir = 'E:/1Study/Hiwi/massvis/dataset/csv_files/targets393_elementLabels/elementLabels/'
origimdir = os.path.join(bp, 'targets')
def highlight_function(x,y,r,imagePath,outPath,imgName):
# load input image
img= cv2.imread(imagePath, cv2.IMREAD_UNCHANGED)
# blur the image_origin to imgBlur
imgBlur=cv2.blur(img,(15,15))
# reduce brightness of imgBlur by 40%
w=imgBlur.shape[1]
h=imgBlur.shape[0]
imgBrightness=0.6
for xi in range(0,w):
for xj in range(0,h):
imgBlur[xj,xi,0]=int(imgBlur[xj,xi,0]*imgBrightness)
imgBlur[xj,xi,1]=int(imgBlur[xj,xi,1]*imgBrightness)
imgBlur[xj,xi,2]=int(imgBlur[xj,xi,2]*imgBrightness)
# get size of image
height, width = img.shape[:2]
height = int(height)
width = int(width)
# generate in-circle-display template
circleIn = np.zeros((height, width, 1), np.uint8)
circleIn = cv2.circle(circleIn, (x, y), r, (1), -1)
# generate out-circle-display template
circleOut = circleIn.copy()
circleOut[circleOut == 0] = 2
circleOut[circleOut == 1] = 0
circleOut[circleOut == 2] = 1
# generate imgIn in which only the content in the spotlight circle remains
# generate a blank img with the same size of input image
imgIn = np.zeros((height, width, 4), np.uint8)
# copy first 3 channel
imgIn[:, :, 0] = np.multiply(img[:, :, 0], circleIn[:, :, 0])
imgIn[:, :, 1] = np.multiply(img[:, :, 1], circleIn[:, :, 0])
imgIn[:, :, 2] = np.multiply(img[:, :, 2], circleIn[:, :, 0])
# set non-transparent part of α channel
circleIn[circleIn == 1] = 255
imgIn[:, :, 3] = circleIn[:, :, 0]
# generate imgOut in which only the content outside the spotlight circle remains and be blurred
imgOut = np.zeros((height, width, 4), np.uint8)
imgOut[:, :, 0] = np.multiply(imgBlur[:, :, 0], circleOut[:, :, 0])
imgOut[:, :, 1] = np.multiply(imgBlur[:, :, 1], circleOut[:, :, 0])
imgOut[:, :, 2] = np.multiply(imgBlur[:, :, 2], circleOut[:, :, 0])
circleOut[circleOut == 1] = 255
imgOut[:, :, 3] = circleOut[:, :, 0]
# generate output image by adding imgIn and imgOut
imgHighlight = cv2.add(imgIn,imgOut)
cv2.imwrite(os.path.join(outPath , imgName+'.png'),imgHighlight)
if(cv2.waitKey(0)==27):
cv2.destroyAllWindows()
return imgHighlight
for curfile in os.listdir(curdir):
os.makedirs(os.path.join(bp, 'highlight'), exist_ok=True)
outpath = os.path.join(bp, 'highlight', curfile)
os.makedirs(outpath, exist_ok=True)
basepath = os.path.basename(curfile)
imname, ext = os.path.splitext(basepath)
print('imname',imname)
allfiles = natsorted(glob(os.path.join(curdir, curfile, 'enc' ,'*.csv')))
# get the experiment data (csv format)
for subcsv in allfiles:
fixations = pd.read_csv(subcsv, header=None)
x=[]
y=[]
duration=[]
for row in fixations.iterrows():
x.append(row[1][1])
y.append(row[1][2])
duration.append(row[1][3])
gif_image=[]
# generate spotlight gif image
for i in range(len(x)):
#adjust the duration parameter so that the spotlight circle won't be too large or too small to display
dur = duration[i]/3 if duration[i]/3>100 else 100
dur = dur if dur>100 else 100
# Make the display time of each spotlight correspond to the observation time of the experimenter
dur_int=int(duration[i]/50)
for j in range(dur_int):
gif_image.append(highlight_function(int(x[i]),int(y[i]),int(dur),os.path.join(origimdir, curfile+'.png'),outpath,imname+'('+str(i+1)+')') )
print(i)
# save spotlight gif image
imageio.mimsave(os.path.join(outpath,imname+'.gif'), gif_image, fps=100)
# problem!!! : The generated spotlight gif image is too large
# possible solution: convert gif format to webm format. Converting to webm format can significantly reduce the file size