Template Matching Changes and Small Style Fixes
* Added reference and comparison index variables to ImageData * Re-worked how template and search window is calculated and specified * Small code style changes with comments * Separated plotting from calculation of displacement and strain into separate functions * Made new function to compare matching methods * Expanded x and y ranges of grid points * Saved matching method comparison plots to file, deleted old incorrect plots
Before Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 105 KiB |
Before Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 110 KiB |
After Width: | Height: | Size: 656 KiB |
After Width: | Height: | Size: 396 KiB |
Before Width: | Height: | Size: 115 KiB |
Before Width: | Height: | Size: 115 KiB |
170
src/__main__.py
@@ -20,24 +20,18 @@ def read_images():
|
|||||||
return images
|
return images
|
||||||
|
|
||||||
|
|
||||||
def find_displacement(match_method):
|
def find_displacement(images, ref_index, comp_index, match_method):
|
||||||
images = read_images()
|
reference = images[ref_index]
|
||||||
|
compare_img = images[comp_index]
|
||||||
|
|
||||||
specimen, load_disp_data = file_data.read_file("../Section001_Data.txt")
|
ref_template_size = (5, 5)
|
||||||
|
search_window_size = (5, 3)
|
||||||
|
grid_spacing = 10
|
||||||
|
|
||||||
reference = images[8]
|
x_range = range(200, 2200, grid_spacing)
|
||||||
compare_img = images[9]
|
y_range = range(100, 500, grid_spacing)
|
||||||
|
|
||||||
subset_size = 5
|
im_data = image_data.ImageData(len(y_range), len(x_range), ref_index, comp_index)
|
||||||
subset_spacing = 10
|
|
||||||
search_size = 5
|
|
||||||
|
|
||||||
x_range = range(650, 2080, subset_spacing)
|
|
||||||
y_range = range(120, 500, subset_spacing)
|
|
||||||
|
|
||||||
im_data = image_data.ImageData(len(y_range), len(x_range))
|
|
||||||
|
|
||||||
disp_mag = np.zeros((len(y_range), len(x_range)))
|
|
||||||
|
|
||||||
for i in range(len(y_range)):
|
for i in range(len(y_range)):
|
||||||
for j in range(len(x_range)):
|
for j in range(len(x_range)):
|
||||||
@@ -46,90 +40,156 @@ def find_displacement(match_method):
|
|||||||
|
|
||||||
im_data.location[i, j, :] = np.array([x, y])
|
im_data.location[i, j, :] = np.array([x, y])
|
||||||
|
|
||||||
up_bound = (subset_size + 1) // 2
|
template_x = [x - (ref_template_size[0] // 2), x + ((ref_template_size[0] + 1) // 2)]
|
||||||
low_bound = subset_size // 2
|
template_y = [y - (ref_template_size[1] // 2), y + ((ref_template_size[1] + 1) // 2)]
|
||||||
|
search_x = [template_x[0] - search_window_size[0], template_x[1] + search_window_size[0]]
|
||||||
|
search_y = [template_y[0] - search_window_size[1], template_y[1] + search_window_size[1]]
|
||||||
|
|
||||||
subset = reference[y-low_bound:y+up_bound, x-low_bound:x+up_bound]
|
ref_template = reference[template_y[0]:template_y[1], template_x[0]:template_x[1]]
|
||||||
search = compare_img[y-search_size:y+search_size+1, x-search_size:x+search_size+1]
|
search_window = compare_img[search_y[0]:search_y[1], search_x[0]:search_x[1]]
|
||||||
|
|
||||||
res = cv2.matchTemplate(image=search, templ=subset, method=match_method)
|
res = cv2.matchTemplate(
|
||||||
|
image=search_window, # Search window in compare image
|
||||||
|
templ=ref_template, # Template from reference image
|
||||||
|
method=match_method # Matching Method
|
||||||
|
)
|
||||||
|
|
||||||
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(src=res)
|
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(src=res)
|
||||||
|
|
||||||
dx = None
|
dx = None
|
||||||
dy = None
|
dy = None
|
||||||
|
|
||||||
if match_method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
|
if match_method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
|
||||||
dx = (minLoc[0] + (subset_size // 2)) - search_size
|
dx = min_loc[0] - search_window_size[0]
|
||||||
dy = (minLoc[1] + (subset_size // 2)) - search_size
|
dy = min_loc[1] - search_window_size[1]
|
||||||
elif match_method in [cv2.TM_CCORR, cv2.TM_CCORR_NORMED,
|
elif match_method in [cv2.TM_CCORR, cv2.TM_CCORR_NORMED,
|
||||||
cv2.TM_CCOEFF, cv2.TM_CCOEFF_NORMED]:
|
cv2.TM_CCOEFF, cv2.TM_CCOEFF_NORMED]:
|
||||||
dx = (maxLoc[0] + (subset_size // 2)) - search_size
|
dx = max_loc[0] - search_window_size[0]
|
||||||
dy = (maxLoc[1] + (subset_size // 2)) - search_size
|
dy = max_loc[1] - search_window_size[1]
|
||||||
|
|
||||||
im_data.displacement[i, j, :] = np.array([dx, dy])
|
im_data.displacement[i, j, :] = np.array([dx, dy])
|
||||||
disp_mag[i, j] = np.sqrt((dx ** 2) + (dy ** 2))
|
|
||||||
|
|
||||||
# Strain in x direction
|
# Strain in x direction
|
||||||
im_data.strain[:, :, 0] = np.gradient(
|
im_data.strain[:, :, 0] = np.gradient(
|
||||||
im_data.displacement[:, :, 0], # x displacements
|
im_data.displacement[:, :, 0], # x displacements
|
||||||
im_data.location[:, 0, 1], # y (row) positions
|
im_data.location[:, 0, 1], # y (row) positions
|
||||||
im_data.location[0, :, 0])[1] # x (col) positions
|
im_data.location[0, :, 0] # x (col) positions
|
||||||
|
)[1] # Gradient in cols direction
|
||||||
|
|
||||||
# Strain in y direction
|
# Strain in y direction
|
||||||
im_data.strain[:, :, 1] = np.gradient(
|
im_data.strain[:, :, 1] = np.gradient(
|
||||||
im_data.displacement[:, :, 1], # y displacements
|
im_data.displacement[:, :, 1], # y displacements
|
||||||
im_data.location[:, 0, 1], # y (row) positions
|
im_data.location[:, 0, 1], # y (row) positions
|
||||||
im_data.location[0, :, 0])[0] # x (col) positions
|
im_data.location[0, :, 0] # x (col) positions
|
||||||
|
)[0] # Gradient in rows direction
|
||||||
|
|
||||||
##########################
|
return reference, im_data
|
||||||
# Figure 1: Displacement #
|
|
||||||
##########################
|
|
||||||
plt.figure(1)
|
|
||||||
plt.subplot(2, 1, 1)
|
|
||||||
|
|
||||||
plt.imshow(reference, # Show reference image
|
|
||||||
|
def plot_disp_and_strain(ref_img, img_data):
|
||||||
|
plt.figure()
|
||||||
|
|
||||||
|
# Subplot 1: Displacement
|
||||||
|
ax = plt.subplot(2, 1, 1)
|
||||||
|
ax.title.set_text("Displacements between image " + str(img_data.reference_index)
|
||||||
|
+ " and image " + str(img_data.comparison_index))
|
||||||
|
|
||||||
|
plt.imshow(ref_img, # Show reference image
|
||||||
cmap="gray", # Grayscale
|
cmap="gray", # Grayscale
|
||||||
vmin=0, # Minimum pixel value
|
vmin=0, # Minimum pixel value
|
||||||
vmax=255, # Maximum pixel value
|
vmax=255, # Maximum pixel value
|
||||||
origin="lower") # Flip image so increasing row corresponds to increasing y
|
origin="lower") # Flip image so increasing row corresponds to increasing y
|
||||||
|
|
||||||
plt.quiver(im_data.location[:, :, 0], # x coordinates of arrow locations
|
disp_mag = np.sqrt(img_data.displacement[:, :, 0] ** 2 + img_data.displacement[:, :, 1] ** 2)
|
||||||
im_data.location[:, :, 1], # y coordinates of arrow locations
|
|
||||||
im_data.displacement[:, :, 0], # x components of arrow vectors
|
plt.quiver(img_data.location[:, :, 0], # x coordinates of arrow locations
|
||||||
im_data.displacement[:, :, 1], # y components of arrow vectors
|
img_data.location[:, :, 1], # y coordinates of arrow locations
|
||||||
|
img_data.displacement[:, :, 0], # x components of arrow vectors
|
||||||
|
img_data.displacement[:, :, 1], # y components of arrow vectors
|
||||||
disp_mag, # arrow color (vector magnitude)
|
disp_mag, # arrow color (vector magnitude)
|
||||||
cmap=plt.cm.jet, # color map (jet)
|
cmap=plt.cm.jet, # color map (jet)
|
||||||
units="dots") # units of arrow dimensions
|
units="dots", # units of arrow dimensions
|
||||||
|
angles="xy") # arrows point from (x, y) to (x + u, y + v)
|
||||||
|
|
||||||
####################
|
# Subplot 2: Strain
|
||||||
# Figure 1: Strain #
|
ax = plt.subplot(2, 1, 2)
|
||||||
####################
|
ax.title.set_text("Strain between image " + str(img_data.reference_index)
|
||||||
plt.subplot(2, 1, 2)
|
+ " and image " + str(img_data.comparison_index))
|
||||||
|
|
||||||
plt.imshow(reference, # Show reference image
|
plt.imshow(ref_img, # Show reference image
|
||||||
cmap="gray", # Grayscale
|
cmap="gray", # Grayscale
|
||||||
vmin=0, # Minimum pixel value
|
vmin=0, # Minimum pixel value
|
||||||
vmax=255, # Maximum pixel value
|
vmax=255, # Maximum pixel value
|
||||||
origin="lower") # Flip image so increasing row corresponds to increasing y
|
origin="lower") # Flip image so increasing row corresponds to increasing y
|
||||||
|
|
||||||
strain_mag = np.sqrt(im_data.strain[:, :, 0] ** 2 + im_data.strain[:, :, 1] ** 2)
|
strain_mag = np.sqrt(img_data.strain[:, :, 0] ** 2 + img_data.strain[:, :, 1] ** 2)
|
||||||
|
|
||||||
plt.quiver(im_data.location[0, :, 0],
|
plt.quiver(img_data.location[0, :, 0],
|
||||||
im_data.location[:, 0, 1],
|
img_data.location[:, 0, 1],
|
||||||
im_data.strain[:, :, 0],
|
img_data.strain[:, :, 0],
|
||||||
im_data.strain[:, :, 1],
|
img_data.strain[:, :, 1],
|
||||||
strain_mag,
|
strain_mag,
|
||||||
cmap=plt.cm.jet,
|
cmap=plt.cm.jet,
|
||||||
units="dots")
|
units="dots",
|
||||||
|
angles="xy")
|
||||||
|
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
def compare_matching_methods(images, ref_idx, comp_idx):
|
||||||
|
plt.figure()
|
||||||
|
plt.suptitle("Displacements between image " + str(ref_idx) + " and image " + str(comp_idx))
|
||||||
|
|
||||||
|
i = 1
|
||||||
|
for match_method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED,
|
||||||
|
cv2.TM_CCORR, cv2.TM_CCORR_NORMED,
|
||||||
|
cv2.TM_CCOEFF, cv2.TM_CCOEFF_NORMED]:
|
||||||
|
reference_img, img_data = find_displacement(images, ref_idx, comp_idx, match_method)
|
||||||
|
|
||||||
|
ax = plt.subplot(3, 2, i)
|
||||||
|
|
||||||
|
title = None
|
||||||
|
|
||||||
|
if match_method == cv2.TM_SQDIFF:
|
||||||
|
title = "SQDIFF"
|
||||||
|
elif match_method == cv2.TM_SQDIFF_NORMED:
|
||||||
|
title = "SQDIFF_NORMED"
|
||||||
|
elif match_method == cv2.TM_CCORR:
|
||||||
|
title = "CCORR"
|
||||||
|
elif match_method == cv2.TM_CCORR_NORMED:
|
||||||
|
title = "CCORR_NORMED"
|
||||||
|
elif match_method == cv2.TM_CCOEFF:
|
||||||
|
title = "CCOEFF"
|
||||||
|
elif match_method == cv2.TM_CCOEFF_NORMED:
|
||||||
|
title = "CCOEFF_NORMED"
|
||||||
|
|
||||||
|
ax.title.set_text(title)
|
||||||
|
|
||||||
|
plt.imshow(reference_img, cmap="gray", vmin=0, vmax=255, origin="lower")
|
||||||
|
|
||||||
|
disp_mag = np.sqrt(img_data.displacement[:, :, 0] ** 2 + img_data.displacement[:, :, 1] ** 2)
|
||||||
|
|
||||||
|
plt.quiver(img_data.location[:, :, 0], img_data.location[:, :, 1], img_data.displacement[:, :, 0],
|
||||||
|
img_data.displacement[:, :, 1], disp_mag, cmap=plt.cm.jet, units="dots", angles="xy")
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
find_displacement(cv2.TM_SQDIFF_NORMED)
|
images = read_images()
|
||||||
|
|
||||||
# for match_method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED,
|
specimen, load_disp_data = file_data.read_file("../Section001_Data.txt")
|
||||||
# cv2.TM_CCORR, cv2.TM_CCORR_NORMED,
|
|
||||||
# cv2.TM_CCOEFF, cv2.TM_CCOEFF_NORMED]:
|
compare_matching_methods(images, 560, 561)
|
||||||
# find_displacement(match_method)
|
|
||||||
|
# Matching Methods
|
||||||
|
# cv2.TM_SQDIFF
|
||||||
|
# cv2.TM_SQDIFF_NORMED
|
||||||
|
# cv2.TM_CCORR
|
||||||
|
# cv2.TM_CCORR_NORMED
|
||||||
|
# cv2.TM_CCOEFF
|
||||||
|
# cv2.TM_CCOEFF_NORMED
|
||||||
|
reference_img, img_data = find_displacement(images, 560, 561, cv2.TM_CCORR_NORMED)
|
||||||
|
plot_disp_and_strain(reference_img, img_data)
|
||||||
|
@@ -11,11 +11,16 @@ import numpy as np
|
|||||||
|
|
||||||
|
|
||||||
class ImageData:
|
class ImageData:
|
||||||
|
reference_index = None
|
||||||
|
comparison_index = None
|
||||||
location = None
|
location = None
|
||||||
displacement = None
|
displacement = None
|
||||||
strain = None
|
strain = None
|
||||||
|
|
||||||
def __init__(self, num_rows, num_cols):
|
def __init__(self, num_rows, num_cols, ref_index, comp_index):
|
||||||
|
self.reference_index = ref_index
|
||||||
|
self.comparison_index = comp_index
|
||||||
|
|
||||||
matrix_shape = (num_rows, num_cols, 2)
|
matrix_shape = (num_rows, num_cols, 2)
|
||||||
|
|
||||||
self.location = np.zeros(matrix_shape)
|
self.location = np.zeros(matrix_shape)
|
||||||
|