You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
4.4 KiB
117 lines
4.4 KiB
import sys, Image
|
|
from numpy import *
|
|
import scipy.ndimage
|
|
|
|
def score_from_autocorr(img0, img1, corres):
|
|
# Code by Philippe Weinzaepfel
|
|
# Compute autocorrelation
|
|
# parameters
|
|
sigma_image = 0.8 # for the gaussian filter applied to images before computing derivatives
|
|
sigma_matrix = 3.0 # for the integration gaussian filter
|
|
derivfilter = array([-0.5,0,0.5]) # function to compute the derivatives
|
|
# smooth_images
|
|
tmp = scipy.ndimage.filters.gaussian_filter1d(img0.astype(float32), sigma_image, axis=0, order=0, mode='nearest')
|
|
img0_smooth = scipy.ndimage.filters.gaussian_filter1d(tmp, sigma_image, axis=1, order=0, mode='nearest')
|
|
# compute the derivatives
|
|
img0_dx = scipy.ndimage.filters.convolve1d(img0_smooth, derivfilter, axis=0, mode='nearest')
|
|
img0_dy = scipy.ndimage.filters.convolve1d(img0_smooth, derivfilter, axis=1, mode='nearest')
|
|
# compute the auto correlation matrix
|
|
dx2 = sum(img0_dx*img0_dx,axis=2)
|
|
dxy = sum(img0_dx*img0_dy,axis=2)
|
|
dy2 = sum(img0_dy*img0_dy,axis=2)
|
|
# integrate it
|
|
tmp = scipy.ndimage.filters.gaussian_filter1d(dx2, sigma_matrix, axis=0, order=0, mode='nearest')
|
|
dx2_smooth = scipy.ndimage.filters.gaussian_filter1d(tmp, sigma_matrix, axis=1, order=0, mode='nearest')
|
|
tmp = scipy.ndimage.filters.gaussian_filter1d(dxy, sigma_matrix, axis=0, order=0, mode='nearest')
|
|
dxy_smooth = scipy.ndimage.filters.gaussian_filter1d(tmp, sigma_matrix, axis=1, order=0, mode='nearest')
|
|
tmp = scipy.ndimage.filters.gaussian_filter1d(dy2, sigma_matrix, axis=0, order=0, mode='nearest')
|
|
dy2_smooth = scipy.ndimage.filters.gaussian_filter1d(tmp, sigma_matrix, axis=1, order=0, mode='nearest')
|
|
# compute minimal eigenvalues: it is done by computing (dx2+dy2)/2 - sqrt( ((dx2+dy2)/2)^2 + (dxy)^2 - dx^2*dy^2)
|
|
tmp = 0.5*(dx2_smooth+dy2_smooth)
|
|
small_eigen = tmp - sqrt( maximum(0,tmp*tmp + dxy_smooth*dxy_smooth - dx2_smooth*dy2_smooth)) # the numbers can be negative in practice due to rounding errors
|
|
large_eigen = tmp + sqrt( maximum(0,tmp*tmp + dxy_smooth*dxy_smooth - dx2_smooth*dy2_smooth))
|
|
# Compute weight as flow score: preparing variable
|
|
#parameters
|
|
sigma_image = 0.8 # gaussian applied to images
|
|
derivfilter = array([1.0,-8.0,0.0,8.0,-1.0])/12.0 # filter to compute the derivatives
|
|
sigma_score = 50.0 # gaussian to convert dist to score
|
|
mul_coef = 10.0 # multiplicative coefficients
|
|
# smooth images
|
|
tmp = scipy.ndimage.filters.gaussian_filter1d(img0.astype(float32), sigma_image, axis=0, order=0, mode='nearest')
|
|
img0_smooth = scipy.ndimage.filters.gaussian_filter1d(tmp, sigma_image, axis=1, order=0, mode='nearest')
|
|
tmp = scipy.ndimage.filters.gaussian_filter1d(img1.astype(float32), sigma_image, axis=0, order=0, mode='nearest')
|
|
img1_smooth = scipy.ndimage.filters.gaussian_filter1d(tmp, sigma_image, axis=1, order=0, mode='nearest')
|
|
# compute derivatives
|
|
img0_dx = scipy.ndimage.filters.convolve1d(img0_smooth, derivfilter, axis=0, mode='nearest')
|
|
img0_dy = scipy.ndimage.filters.convolve1d(img0_smooth, derivfilter, axis=1, mode='nearest')
|
|
img1_dx = scipy.ndimage.filters.convolve1d(img1_smooth, derivfilter, axis=0, mode='nearest')
|
|
img1_dy = scipy.ndimage.filters.convolve1d(img1_smooth, derivfilter, axis=1, mode='nearest')
|
|
# compute it
|
|
res = []
|
|
for pos0, pos1, score in corres:
|
|
p0, p1 = tuple(pos0)[::-1], tuple(pos1)[::-1] # numpy coordinates
|
|
dist = sum( abs(img0_smooth[p0]-img1_smooth[p1]) + abs(img0_dx[p0]-img1_dx[p1]) + abs(img0_dy[p0]-img1_dy[p1]) )
|
|
score = mul_coef * sqrt( max(0,small_eigen[p0])) / (sigma_score*sqrt(2*pi))*exp(-0.5*square(dist/sigma_score));
|
|
res.append((pos0,pos1,score))
|
|
return res
|
|
|
|
|
|
if __name__=='__main__':
|
|
args = sys.argv[1:]
|
|
img0 = array(Image.open(args[0]).convert('RGB'))
|
|
img1 = array(Image.open(args[1]).convert('RGB'))
|
|
out = open(args[2]) if len(args)>=3 else sys.stdout
|
|
|
|
ty0, tx0 = img0.shape[:2]
|
|
ty1, tx1 = img1.shape[:2]
|
|
rint = lambda s: int(0.5+float(s))
|
|
|
|
retained_matches = []
|
|
for line in sys.stdin:
|
|
line = line.split()
|
|
if not line or len(line)!=6 or not line[0][0].isdigit(): continue
|
|
x0, y0, x1, y1, score, index = line
|
|
retained_matches.append(((min(tx0-1,rint(x0)),min(ty0-1,rint(y0))),
|
|
(min(tx1-1,rint(x1)),min(ty1-1,rint(y1))),0))
|
|
|
|
assert retained_matches, 'error: no matches piped to this program'
|
|
|
|
for p0, p1, score in score_from_autocorr(img0, img1, retained_matches):
|
|
print >>out, '%d %d %d %d %f' %(p0[0],p0[1],p1[0],p1[1],score)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|