utils.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. import cv2
  2. import math
  3. import random
  4. import time
  5. import csv
  6. import numpy as np
  7. import pandas as pd
  8. import tensorflow as tf
  9. import skimage.transform as sktransform
  10. import matplotlib.image as mpimg
  11. from os import path
  12. from collections import defaultdict
  13. from tensorflow.keras import backend as K
  14. from tensorflow.keras.applications.imagenet_utils import preprocess_input
  15. from tensorflow.keras.models import Model
  16. from keras_preprocessing import image
  17. #test
  18. def get_start_point(orig_pixels,orig_shape,final_shape):
  19. final_pixels = [round(float(orig_pixels[0])*final_shape[0]/orig_shape[0]),round(float(orig_pixels[1])*final_shape[1]/orig_shape[1])]
  20. return final_pixels
  21. def get_occl_size(orig_start,orig_end,orig_shape,final_shape):
  22. occl_size = [max(1,round((float(orig_end[0])-float(orig_start[0]))*final_shape[0]/orig_shape[0])),max(1,round((float(orig_end[1])-float(orig_start[1]))*final_shape[1]/orig_shape[1]))]
  23. return occl_size
  24. def v3_preprocess(image, top_offset=.375, bottom_offset=.125,shape=(32,128)):
  25. """
  26. Applies preprocessing pipeline to an image: crops `top_offset` and `bottom_offset`
  27. portions of image, resizes to 32x128 px and scales pixel values to [0, 1].
  28. """
  29. top = int(top_offset * image.shape[0])
  30. bottom = int(bottom_offset * image.shape[0])
  31. if(bottom == 0):
  32. bottom = 1
  33. image = sktransform.resize(image[top:-bottom, :], shape)
  34. return image
  35. def draw_arrow2(img, angle1,thickness = 1):
  36. pt1 = (int(img.shape[1] / 2), img.shape[0])
  37. pt2_angle1 = (int(img.shape[1] / 2 - img.shape[0] / 3 * math.sin(angle1)),
  38. int(img.shape[0] - img.shape[0] / 3 * math.cos(angle1)))
  39. img = cv2.arrowedLine(img, pt1, pt2_angle1, (255, 0, 0), thickness)
  40. return img
  41. def draw_arrow3(img, angle1,angle2):
  42. pt1 = (int(img.shape[1] / 2), img.shape[0])
  43. pt2_angle1 = (int(img.shape[1] / 2 - img.shape[0] / 3 * math.sin(angle1)),
  44. int(img.shape[0] - img.shape[0] / 3 * math.cos(angle1)))
  45. pt2_angle2 = (int(img.shape[1] / 2 - img.shape[0] / 3 * math.sin(angle2)),
  46. int(img.shape[0] - img.shape[0] / 3 * math.cos(angle2)))
  47. img = cv2.arrowedLine(img, pt1, pt2_angle1, (0, 0, 255), 5)
  48. img = cv2.arrowedLine(img, pt1, pt2_angle2, (0, 255, 0), 5)
  49. return img
  50. def raw_draw_arrow3(img, angle1,angle2):
  51. pt1 = (int(img.shape[1] / 2), img.shape[0])
  52. pt2_angle1 = (int(img.shape[1] / 2 - img.shape[0] / 3 * math.sin(angle1)),
  53. int(img.shape[0] - img.shape[0] / 3 * math.cos(angle1)))
  54. pt2_angle2 = (int(img.shape[1] / 2 - img.shape[0] / 3 * math.sin(angle2)),
  55. int(img.shape[0] - img.shape[0] / 3 * math.cos(angle2)))
  56. img = cv2.arrowedLine(img, pt1, pt2_angle1, (1, 0, 0), 1)
  57. img = cv2.arrowedLine(img, pt1, pt2_angle2, (0, 1, 0), 1)
  58. return img
  59. def draw_arrow(img, angle1, angle2, angle3):
  60. pt1 = (int(img.shape[1] / 2), img.shape[0])
  61. pt2_angle1 = (int(img.shape[1] / 2 - img.shape[0] / 3 * math.sin(angle1)),
  62. int(img.shape[0] - img.shape[0] / 3 * math.cos(angle1)))
  63. pt2_angle2 = (int(img.shape[1] / 2 - img.shape[0] / 3 * math.sin(angle2)),
  64. int(img.shape[0] - img.shape[0] / 3 * math.cos(angle2)))
  65. pt2_angle3 = (int(img.shape[1] / 2 - img.shape[0] / 3 * math.sin(angle3)),
  66. int(img.shape[0] - img.shape[0] / 3 * math.cos(angle3)))
  67. img = cv2.arrowedLine(img, pt1, pt2_angle1, (0, 0, 255), 1)
  68. img = cv2.arrowedLine(img, pt1, pt2_angle2, (0, 255, 0), 1)
  69. img = cv2.arrowedLine(img, pt1, pt2_angle3, (255, 0, 0), 1)
  70. return img
  71. def angle_diverged(angle1, angle2, angle3):
  72. if (abs(angle1 - angle2) > 0.2 or abs(angle1 - angle3) > 0.2 or abs(angle2 - angle3) > 0.2) and not (
  73. (angle1 > 0 and angle2 > 0 and angle3 > 0) or (
  74. angle1 < 0 and angle2 < 0 and angle3 < 0)):
  75. return True
  76. return False
  77. def angle_diverged2(angle1, angle2):
  78. if (abs(angle1 - angle2) > 0.1) and not (
  79. (angle1 > 0 and angle2 > 0 ) or (angle1 < 0 and angle2 < 0 )):
  80. return True
  81. return False
  82. def angle_diverged3(angle1, angle2):
  83. if (abs(angle1 - angle2) > 0.1):
  84. return True
  85. return False
  86. def preprocess_image(img_path, target_size=(100, 100)):
  87. img = image.load_img(img_path, target_size=target_size)
  88. input_img_data = image.img_to_array(img)
  89. input_img_data = np.expand_dims(input_img_data, axis=0)
  90. input_img_data = preprocess_input(input_img_data)
  91. return input_img_data
  92. def preprocess_image_v3(img_path,top_offset,bottom_offset):
  93. orig_name = image.load_img(img_path)
  94. orig_name = image.img_to_array(orig_name)
  95. orig_name = orig_name.astype(np.uint8)
  96. gen_img = v3_preprocess(orig_name,top_offset = top_offset,bottom_offset = bottom_offset)
  97. gen_img = np.expand_dims(gen_img, axis=0)
  98. return gen_img
  99. def preprocess_image_v2(img_path,top_offset,bottom_offset):
  100. orig_name = image.load_img(img_path)
  101. orig_name = image.img_to_array(orig_name)
  102. orig_name = orig_name.astype(np.uint8)
  103. gen_img = v3_preprocess(orig_name,top_offset = top_offset,bottom_offset = bottom_offset,shape=(66,200))
  104. gen_img = np.expand_dims(gen_img, axis=0)
  105. return gen_img
  106. def deprocess_image(x,shape=(100,100,3)):
  107. tmp = x.copy()
  108. tmp = tmp.reshape(shape)
  109. # Remove zero-center by mean pixel
  110. tmp[:, :, 0] += 103.939
  111. tmp[:, :, 1] += 116.779
  112. tmp[:, :, 2] += 123.68
  113. # 'BGR'->'RGB'
  114. tmp = tmp[:, :, ::-1]
  115. tmp = np.clip(tmp, 0, 255).astype('uint8')
  116. return tmp
  117. def atan_layer(x):
  118. return tf.multiply(tf.atan(x), 2)
  119. def atan_layer_shape(input_shape):
  120. return input_shape
  121. def normal_init(shape, dtype=None):
  122. return K.truncated_normal(shape, stddev=0.1)
  123. def normalize(x):
  124. # utility function to normalize a tensor by its L2 norm
  125. return x / (K.sqrt(K.mean(K.square(x))) + 1e-5)
  126. def constraint_occl(gradients, start_point, rect_shape):
  127. new_grads = np.zeros_like(gradients)
  128. new_grads[:, start_point[0]:start_point[0] + rect_shape[0],
  129. start_point[1]:start_point[1] + rect_shape[1]] = gradients[:, start_point[0]:start_point[0] + rect_shape[0],
  130. start_point[1]:start_point[1] + rect_shape[1]]
  131. return new_grads
  132. def constraint_light(gradients):
  133. new_grads = np.ones_like(gradients)
  134. grad_mean = 500 * np.mean(gradients)
  135. return grad_mean * new_grads
  136. def constraint_black(gradients, rect_shape=(10, 10)):
  137. start_point = (
  138. random.randint(0, gradients.shape[1] - rect_shape[0]), random.randint(0, gradients.shape[2] - rect_shape[1]))
  139. new_grads = np.zeros_like(gradients)
  140. patch = gradients[:, start_point[0]:start_point[0] + rect_shape[0], start_point[1]:start_point[1] + rect_shape[1]]
  141. if np.mean(patch) < 0:
  142. new_grads[:, start_point[0]:start_point[0] + rect_shape[0],
  143. start_point[1]:start_point[1] + rect_shape[1]] = -np.ones_like(patch)
  144. return new_grads
  145. def init_coverage_tables(model1, model2, model3):
  146. model_layer_dict1 = defaultdict(bool)
  147. model_layer_dict2 = defaultdict(bool)
  148. model_layer_dict3 = defaultdict(bool)
  149. init_dict(model1, model_layer_dict1)
  150. init_dict(model2, model_layer_dict2)
  151. init_dict(model3, model_layer_dict3)
  152. return model_layer_dict1, model_layer_dict2, model_layer_dict3
  153. def init_coverage_tables2(model1):
  154. model_layer_dict1 = defaultdict(bool)
  155. init_dict(model1, model_layer_dict1)
  156. return model_layer_dict1
  157. def init_dict(model, model_layer_dict):
  158. for layer in model.layers:
  159. if 'flatten' in layer.name or 'input' in layer.name:
  160. continue
  161. for index in range(layer.output_shape[-1]):
  162. model_layer_dict[(layer.name, index)] = False
  163. def neuron_to_cover(model_layer_dict):
  164. not_covered = [(layer_name, index) for (layer_name, index), v in model_layer_dict.items() if not v]
  165. if not_covered:
  166. layer_name, index = random.choice(not_covered)
  167. else:
  168. layer_name, index = random.choice(model_layer_dict.keys())
  169. return layer_name, index
  170. def neuron_covered(model_layer_dict):
  171. covered_neurons = len([v for v in model_layer_dict.values() if v])
  172. total_neurons = len(model_layer_dict)
  173. return covered_neurons, total_neurons, covered_neurons / float(total_neurons)
  174. def scale(intermediate_layer_output, rmax=1, rmin=0):
  175. X_std = (intermediate_layer_output - intermediate_layer_output.min()) / (
  176. intermediate_layer_output.max() - intermediate_layer_output.min())
  177. X_scaled = X_std * (rmax - rmin) + rmin
  178. return X_scaled
  179. def update_coverage(input_data, model, model_layer_dict, threshold=0):
  180. layer_names = [layer.name for layer in model.layers if
  181. 'flatten' not in layer.name and 'input' not in layer.name]
  182. intermediate_layer_model = Model(inputs=model.input,
  183. outputs=[model.get_layer(layer_name).output for layer_name in layer_names])
  184. intermediate_layer_outputs = intermediate_layer_model.predict(input_data)
  185. for i, intermediate_layer_output in enumerate(intermediate_layer_outputs):
  186. scaled = scale(intermediate_layer_output[0])
  187. for num_neuron in range(scaled.shape[-1]):
  188. if np.mean(scaled[..., num_neuron]) > threshold and not model_layer_dict[(layer_names[i], num_neuron)]:
  189. model_layer_dict[(layer_names[i], num_neuron)] = True
  190. def full_coverage(model_layer_dict):
  191. if False in model_layer_dict.values():
  192. return False
  193. return True
  194. def fired(model, layer_name, index, input_data, threshold=0):
  195. intermediate_layer_model = Model(inputs=model.input, outputs=model.get_layer(layer_name).output)
  196. intermediate_layer_output = intermediate_layer_model.predict(input_data)[0]
  197. scaled = scale(intermediate_layer_output)
  198. if np.mean(scaled[..., index]) > threshold:
  199. return True
  200. return False
  201. def diverged(predictions1, predictions2, predictions3, target):
  202. # if predictions2 == predictions3 == target and predictions1 != target:
  203. if not predictions1 == predictions2 == predictions3:
  204. return True
  205. return False
  206. def transform_occl(gradients,start_point,rect_shape,logo_data,order):
  207. new_grads = np.zeros((np.shape(gradients)[0],rect_shape[0],rect_shape[1],np.shape(gradients)[3]))
  208. new_grads = gradients[:, start_point[0]:start_point[0] + rect_shape[0],start_point[1]:start_point[1] + rect_shape[1]]
  209. for i in range(rect_shape[0]):
  210. for j in range(rect_shape[1]):
  211. logo_shape = np.shape(logo_data)
  212. logo_data[order,round(logo_shape[1]*1.00*i/(rect_shape[0])),round(logo_shape[2]*1.00*j/(rect_shape[1])),:] = new_grads[0,i,j,:]
  213. return logo_data
  214. #for pixel transform: nearest interpolation
  215. def transform_occl2(gradients,start_point,rect_shape,logo_data,order):
  216. new_grads = np.zeros((np.shape(gradients)[0],rect_shape[0],rect_shape[1],np.shape(gradients)[3]))
  217. new_grads = gradients[:, start_point[0]:start_point[0] + rect_shape[0],start_point[1]:start_point[1] + rect_shape[1]]
  218. logo_shape = np.shape(logo_data)
  219. for i in range(logo_shape[1]):
  220. for j in range(logo_shape[2]):
  221. logo_data[order,i,j,:] = new_grads[0,round(rect_shape[0]*1.00*i/(logo_shape[1])-0.5),round(rect_shape[1]*1.00*j/(logo_shape[2])-0.5),:]
  222. return logo_data
  223. #for pixel transform: linear interpolation
  224. def transform_occl3(gradients,start_point,rect_shape,logo_data,order):
  225. new_grads = np.zeros((np.shape(gradients)[0],rect_shape[0],rect_shape[1],np.shape(gradients)[3]))
  226. new_grads = gradients[:, start_point[0]:start_point[0] + rect_shape[0],start_point[1]:start_point[1] + rect_shape[1],:]
  227. logo_shape = np.shape(logo_data)
  228. #In this version (29/07/2018), we do not use own rescale code but opencv resize instead
  229. #print(np.shape(new_grads))
  230. logo_data[order] = cv2.resize(new_grads[0], dsize=(logo_shape[2], logo_shape[1]))
  231. '''
  232. for i in range(logo_shape[1]):
  233. for j in range(logo_shape[2]):
  234. y_approximation = rect_shape[0]*1.00*i/(logo_shape[1])
  235. x_approximation = rect_shape[1]*1.00*j/(logo_shape[2])
  236. y_offset = y_approximation - int(y_approximation)
  237. x_offset = x_approximation -int(x_approximation)
  238. logo_data[order,i,j,:] = new_grads[0,int(y_approximation),int(x_approximation),:] * (1-x_offset)*(1-y_offset) + \
  239. new_grads[0,min(rect_shape[0]-1,int(y_approximation)+1),int(x_approximation),:] * (1-x_offset)*(y_offset) + \
  240. new_grads[0,int(y_approximation),min(rect_shape[1]-1,int(x_approximation)+1),:] * (x_offset)*(1-y_offset) + \
  241. new_grads[0,min(rect_shape[0]-1,int(y_approximation)+1),min(rect_shape[1]-1,int(x_approximation)+1),:] * (x_offset)*(y_offset)
  242. '''
  243. return logo_data
  244. def transfrom_accurate(gradients,des_pixel,logo_data,order):
  245. des = np.array([[0.1, 0], [np.shape(logo_data[0])[1]-1, 0], [0, np.shape(logo_data[0])[0]-1], [np.shape(logo_data[0])[1]-1, np.shape(logo_data[0])[0]-1]],np.float32)
  246. transform = cv2.getPerspectiveTransform(des_pixel,des)
  247. logo_data[order] = cv2.warpPerspective(gradients,transform,( np.shape(logo_data[0])[1], np.shape(logo_data[0])[0]))
  248. return logo_data
  249. def update_image(imgs,logo,start_point,occl_size):
  250. for i in range(len(imgs)):
  251. imgs[i][0,start_point[i][0]:start_point[i][0]+occl_size[i][0],start_point[i][1]:start_point[i][1]+occl_size[i][1],:] = cv2.resize(logo,(occl_size[i][1],occl_size[i][0]))[:min(occl_size[i][0],np.shape(imgs[i])[1]-start_point[i][0]),:min(occl_size[i][1],np.shape(imgs[i])[2]-start_point[i][1])]
  252. return imgs
  253. #def accurate_logo_grad(gradients,des_pixels):
  254. def accurate_update(imgs,logo,des_pixels):
  255. src = np.array([[0, 0], [np.shape(logo)[1]-1, 0], [0, np.shape(logo)[0]-1], [np.shape(logo)[1]-1, np.shape(logo)[0]-1]],np.float32)
  256. for i in range(len(imgs)):
  257. transform = cv2.getPerspectiveTransform(src,des_pixels[i])
  258. output = cv2.warpPerspective(logo,transform,( np.shape(imgs[i])[2], np.shape(imgs[i])[1]),flags=cv2.INTER_LINEAR )
  259. mask = output.astype(np.bool)
  260. mask = mask.astype(np.float32)
  261. back = cv2.multiply(1.0-mask,imgs[i][0])
  262. imgs[i][0] = np.array(cv2.add(back,np.array(output,dtype=np.float32)))
  263. return imgs
  264. def control_bound(logo):
  265. np.clip(logo[:,:,0], -103.939, 255-103.939, out=logo[:,:,0])
  266. np.clip(logo[:,:,1], -116.779, 255-116.779, out=logo[:,:,1])
  267. np.clip(logo[:,:,2], -123.68, 255-123.68, out=logo[:,:,2])
  268. return logo
  269. def raw_control_bound(logo):
  270. np.clip(logo, 0, 1, out=logo)
  271. return logo
  272. def preprocess_color(color):
  273. color[0] = color[0] -103.939
  274. color[1] = color[1] -116.779
  275. color[2] = color[2] - 123.68
  276. return color
  277. def total_diff(imgs,model1,angles_2):
  278. angles_diff = []
  279. count = 0
  280. for img in imgs:
  281. angles_diff.append(abs(model1.predict(img)[0]-angles_2[count]))
  282. count+=1
  283. return sum(angles_diff)
  284. def gen_optimal(imgs,model1,angle3,start_points,occl_sizes):
  285. logo = np.zeros((480,640,3))
  286. result = {"pixel_value":np.zeros([10,3]),"diff":np.zeros(10)}
  287. for blue in range(0,256,51):
  288. for green in range(0,256,51):
  289. #print("[",blue,green,":] claculated, current result is,",result)
  290. for red in range(0,256,51):
  291. logo[:,:] = preprocess_color([blue,green,red])
  292. #imgs = accurate_update(imgs,logo,des_pixels)
  293. imgs = update_image(imgs,logo,start_points,occl_sizes)
  294. this_diff = total_diff(imgs,model1,angle3)
  295. this_diff = this_diff/len(imgs) * 180 / math.pi
  296. if(this_diff > result["diff"][0]):
  297. result["pixel_value"][0] = np.array([blue,green,red])
  298. result["diff"][0] = this_diff
  299. index = np.argsort(result["diff"])
  300. result["diff"] = result["diff"][index]
  301. result["pixel_value"] = result["pixel_value"][index]
  302. print(result)
  303. return preprocess_color(result["pixel_value"][-1])
  304. def raw_gen_optimal(imgs,model1,angle3,start_points,occl_sizes):
  305. logo = np.zeros((480,640,3))
  306. result = {"pixel_value":np.zeros([10,3]),"diff":np.zeros(10)}
  307. for blue in range(0,256,51):
  308. for green in range(0,256,51):
  309. #print("[",blue,green,":] claculated, current result is,",result)
  310. for red in range(0,256,51):
  311. logo[:,:] = [blue/255.0,green/255.0,red/255.0]
  312. #imgs = accurate_update(imgs,logo,des_pixels)
  313. imgs = update_image(imgs,logo,start_points,occl_sizes)
  314. this_diff = total_diff(imgs,model1,angle3)
  315. this_diff = this_diff/len(imgs) * 180 / math.pi
  316. if(this_diff > result["diff"][0]):
  317. result["pixel_value"][0] = np.array([blue/255.0,green/255.0,red/255.0])
  318. result["diff"][0] = this_diff
  319. index = np.argsort(result["diff"])
  320. result["diff"] = result["diff"][index]
  321. result["pixel_value"] = result["pixel_value"][index]
  322. print(result)
  323. return result["pixel_value"][-1]
  324. def read_input(imgs,des_pixels,occl_sizes,start_points,filelist,coordination,is_crop = False,is_all = False):
  325. if(is_crop):
  326. img_size = [600,800]
  327. else:
  328. img_size = [1080,1920]
  329. for f in sorted(filelist):
  330. orig_name = f
  331. gen_img = preprocess_image(orig_name)
  332. imgs.append(gen_img)
  333. with open(coordination) as f:
  334. if(is_all):
  335. spamreader = csv.reader(f)
  336. else:
  337. spamreader = csv.reader(f, delimiter=',', quotechar='|')
  338. for row in spamreader:
  339. if(len(row) != 9):
  340. print(len(row))
  341. continue
  342. tmp = np.array([[float(row[2])*100.0/img_size[1],float(row[1])*100.0/img_size[0]],[float(row[6])*100.0/img_size[1],float(row[5])*100.0/img_size[0]],[float(row[4])*100.0/img_size[1],float(row[3])*100.0/img_size[0]],[float(row[8])*100.0/img_size[1],float(row[7])*100.0/img_size[0]]],np.float32)
  343. des_pixels.append(tmp)
  344. start_points.append([round(float(row[1])*100.0/img_size[0]),round(float(row[2])*100.0/img_size[1])])
  345. occl_sizes.append([round((float(row[7])-float(row[1]))*100.0/img_size[0]),round((float(row[8])-float(row[2]))*100.0/img_size[1])])
  346. print(coordination + " read complete")
  347. return imgs,des_pixels,occl_sizes,start_points
  348. def find_kth_max(array,k):
  349. tmp = array.flatten()
  350. tmp = abs(tmp)
  351. tmp.sort()
  352. return tmp[-k]