Szükséges importálások.
import cv2
import numpy as np
from scipy import optimize
Fix eltolási értékek (az eredeti kontúrra alkalmazva).
TRANS_X = -22
TRANS_Y = 3
Eredeti kontúr kép betöltése és kontúrpontok kinyerése.
im1 = cv2.imread('04_ol.png', cv2.IMREAD_GRAYSCALE)
# Extract contour points from im1
cnts1_y, cnts1_x = np.nonzero(im1)
im2 kontúrkép előállítása.
# Generating im2 by applying a known displacement to im1 contours
im2 = np.zeros((im1.shape[0], im1.shape[1]), np.uint8)
im2[cnts1_y + TRANS_Y, cnts1_x + TRANS_X] = 255
Egymásra vetített kontúr képek előállítása és megjelenítése.
# Blending contours
h, w = im1.shape[:2]
image_orig_blend = cv2.merge((np.zeros((h, w), np.uint8), im1, im2))
cv2.imshow('Originals (blended)', image_orig_blend)
Kontúrok kinyerése az illesztendő képből.
# Extract contour points of im2
cnts2_y, cnts2_x = np.nonzero(im2)
Távolságtérkép számítása.
# Distance map from the inverse of im1 and write result to image
# im1_dist = cv2.distanceTransform(255 - im1, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
im1_dist = cv2.distanceTransform(~im1, 2, 5)
Az optimalizálandó függvény. A params tömböt az optimalizáló módszer adja át. Ennek értelmezése a függvény feladata. A függvénynek vissza kell adnia, a paramétrek szerinti transzformáció után milyen távolságra kerülnek a kontúrok?
# Function to optimize (contour distance based on global displacement parameters)
def func(params):
global im1_dist, cnts2_x, cnts2_y
# Get parameters from optimizer
dy = int(round(params[0]))
dx = int(round(params[1]))
# Compute distance
distance_sum = 0
for idx in range(0, len(cnts2_x)):
distance_sum = distance_sum + im1_dist[cnts2_y[idx] + dy, cnts2_x[idx] + dx]
print('params:', params, 'distance:', distance_sum)
display_result(dx, dy)
cv2.waitKey(100)
return distance_sum
Kontúrok egymásra vetített megjelenítését végző függvény.
def display_result(dx, dy):
im2[:, :] = 0
im2[cnts2_y + dy, cnts2_x + dx] = 255
image_reg_blend = cv2.merge((np.zeros((h, w), np.uint8), im1, im2))
cv2.imshow('Registered (blended)', image_reg_blend)
Optimalizáló paraméterezése és indítása.
# Initial parameters (identical transformation)
x0 = np.array([0, 0])
# Start Powell optimization (from SciPy)
result = optimize.fmin_powell(func, x0)
Eredmények megjelenítése.
# Print and display result
print(result)
dist_y = int(round(result[0]))
dist_x = int(round(result[1]))
print('Result:', dist_x, dist_y)
display_result(dist_x, dist_y)
Program befejezése.
cv2.waitKey(0)
cv2.destroyAllWindows()