124 lines
4.5 KiB
Python
124 lines
4.5 KiB
Python
|
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
|
|||
|
|