Skip to content

Commit f0ac6c6

Browse files
Added comments explaining all variables and functions
1 parent cbd8f15 commit f0ac6c6

File tree

1 file changed

+31
-5
lines changed

1 file changed

+31
-5
lines changed

code/chapter-2/visualization.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,16 @@
1818
import glob
1919
import os
2020

21+
#Select a model to use, in this case VGG16
2122
model = VGG16(weights='imagenet', include_top=True, input_tensor=None, input_shape=None, pooling=None, classes=1000)
2223
#Check with 'print(model.summary())', in this case it is "block5_conv3"
2324
last_conv_layer_name = "block5_conv3"
24-
#Include layers between last convolutional layer and prediction layer
25+
#Must include layers between last convolutional layer and prediction layer
26+
#Layer names can be found through 'print(model.summary())'
2527
classifier_layer_names = ["block5_pool", "flatten", "fc1", "fc2", "predictions"]
2628

29+
#This function is called from 'make_gradcam_heatmap'
30+
#Takes iaage_path from 'get_command_line_arguments', turns into it an array
2731
def get_img_array(img_path, size):
2832
img = tensorflow.keras.preprocessing.image.load_img(img_path, target_size=(224, 224))
2933
# `array` is a float32 Numpy array
@@ -33,12 +37,17 @@ def get_img_array(img_path, size):
3337
array = np.expand_dims(array, axis=0)
3438
return array
3539

36-
#This replaces several functions from visualization.py
40+
#'make_gradcam_heatmap' is main function and ultimately returns heatmap superimposed onto the input image(s)
41+
42+
#inputs are the image path specified in the command line, the last convolutional layer and
43+
#the classifier layer names of which both are defined above and depend on your model, and the output path
44+
#for our heatmap superimposed onto original image which are specified in the script's final if statement
3745
def make_gradcam_heatmap(
3846
img_path, model, last_conv_layer_name, classifier_layer_names, output_path
3947
):
40-
48+
#pre_processes the array returned from 'get_img_array'
4149
img_array = preprocess_input(get_img_array(img_path, size= (224, 224)))
50+
4251
# First, we create a model that maps the input image to the activations
4352
# of the last conv layer
4453
last_conv_layer = model.get_layer(last_conv_layer_name)
@@ -55,9 +64,11 @@ def make_gradcam_heatmap(
5564
# Then, we compute the gradient of the top predicted class for our input image
5665
# with respect to the activations of the last conv layer
5766
with tensorflow.GradientTape() as tape:
67+
5868
# Compute activations of the last conv layer and make the tape watch it
5969
last_conv_layer_output = last_conv_layer_model(img_array)
6070
tape.watch(last_conv_layer_output)
71+
6172
# Compute class predictions
6273
preds = classifier_model(last_conv_layer_output)
6374
top_pred_index = tensorflow.argmax(preds[0])
@@ -111,20 +122,27 @@ def make_gradcam_heatmap(
111122
#Save the the superimposed image to the output path
112123
superimposed_img.save(output_path)
113124

114-
125+
#Runs body of code for entirety of videoframs_path (folder specified in command line)
115126
def process_video(videoframes_path, output_prefix):
116127
counter = 0
128+
#define output directory
117129
output_dir = output_prefix + "_output"
130+
131+
#Creates directory output directoy if it doesn't already exist
118132
if not os.path.exists(output_dir):
119133
os.makedirs(output_dir)
120134
for input_path in sorted(glob.glob(videoframes_path + "/*.jpg")):
121-
counter += 1
135+
counter +=
136+
122137
output_path = output_dir + "/result-" + str(counter).zfill(4) + '.jpg'
123138

139+
#Runs main function with specified image_path, output_prefix, and layers defined near top of script
124140
make_gradcam_heatmap(input_path, model, last_conv_layer_name, classifier_layer_names, output_path)
125141

142+
#Function for taking inputs through the command line
126143
def get_command_line_arguments():
127144
parser = ArgumentParser()
145+
#We specify either image or video to
128146
parser.add_argument("--process", choices=["image", "video"], required=True,
129147
dest="process_type", help="Process a single image or video")
130148
parser.add_argument("--path", required=True, dest="path",
@@ -134,17 +152,25 @@ def get_command_line_arguments():
134152

135153
args = get_command_line_arguments()
136154

155+
#If process is specified as 'image', defines image_path and output_prefix according to command line argument
137156
if args.process_type == "image":
157+
#image path is location of image that we want to generate a heatmap for
138158
image_path = args.path
139159
output_prefix = os.path.splitext(os.path.basename(image_path))[0]
160+
#Runs main function with specified image_path and output_prefix from command line
161+
#layers defined near top of script
140162
make_gradcam_heatmap(image_path, model, last_conv_layer_name, classifier_layer_names, output_prefix + "_output.jpg")
141163

142164
#Plot the superimposed image
143165
img = mpimg.imread(output_prefix + "_output.jpg")
144166
plt.imshow(img)
145167
plt.show()
146168

169+
#If process is specified as 'image', defines videoframes_path and output_prefix according to command line argument
147170
elif args.process_type == "video":
171+
#videoframes_path is directory with the video frames split by ffmpeg
148172
videoframes_path = args.path
173+
#will be used to specify or create output folder
149174
output_prefix = os.path.dirname(videoframes_path)
175+
#Runs 'process_video' function with inputs taken from command line
150176
heatmaps = process_video(videoframes_path, output_prefix)

0 commit comments

Comments
 (0)