utils.py 18 KB

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