Mercurial > hg > nsaunier > traffic-intelligence
comparison scripts/compute-homography.py @ 334:1d90e9080cb2
moved python scripts to the scripts directory
| author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
|---|---|
| date | Fri, 14 Jun 2013 10:34:11 -0400 |
| parents | python/compute-homography.py@9d88a4d97473 |
| children | 5f75d6c23ed5 |
comparison
equal
deleted
inserted
replaced
| 333:c9201f6b143a | 334:1d90e9080cb2 |
|---|---|
| 1 #! /usr/bin/env python | |
| 2 | |
| 3 import sys,getopt | |
| 4 | |
| 5 import matplotlib.pyplot as plt | |
| 6 import numpy as np | |
| 7 import cv2 | |
| 8 | |
| 9 import cvutils | |
| 10 import utils | |
| 11 | |
| 12 options, args = getopt.getopt(sys.argv[1:], 'hp:i:w:n:u:',['help']) | |
| 13 options = dict(options) | |
| 14 | |
| 15 # TODO process camera intrinsic and extrinsic parameters to obtain image to world homography, taking example from Work/src/python/generate-homography.py script | |
| 16 # cameraMat = load(videoFilenamePrefix+'-camera.txt'); | |
| 17 # T1 = cameraMat[3:6,:].copy(); | |
| 18 # A = cameraMat[0:3,0:3].copy(); | |
| 19 | |
| 20 # # pay attention, rotation may be the transpose | |
| 21 # # R = T1[:,0:3].T; | |
| 22 # R = T1[:,0:3]; | |
| 23 # rT = dot(R, T1[:,3]/1000); | |
| 24 # T = zeros((3,4),'f'); | |
| 25 # T[:,0:3] = R[:]; | |
| 26 # T[:,3] = rT; | |
| 27 | |
| 28 # AT = dot(A,T); | |
| 29 | |
| 30 # nPoints = 4; | |
| 31 # worldPoints = cvCreateMat(nPoints, 3, CV_64FC1); | |
| 32 # imagePoints = cvCreateMat(nPoints, 3, CV_64FC1); | |
| 33 | |
| 34 # # extract homography from the camera calibration | |
| 35 # worldPoints = cvCreateMat(4, 3, CV_64FC1); | |
| 36 # imagePoints = cvCreateMat(4, 3, CV_64FC1); | |
| 37 | |
| 38 # worldPoints[0,:] = [[1, 1, 0]]; | |
| 39 # worldPoints[1,:] = [[1, 2, 0]]; | |
| 40 # worldPoints[2,:] = [[2, 1, 0]]; | |
| 41 # worldPoints[3,:] = [[2, 2, 0]]; | |
| 42 | |
| 43 # wPoints = [[1,1,2,2], | |
| 44 # [1,2,1,2], | |
| 45 # [0,0,0,0]]; | |
| 46 # iPoints = utils.worldToImage(AT, wPoints); | |
| 47 | |
| 48 # for i in range(nPoints): | |
| 49 # imagePoints[i,:] = [iPoints[:,i].tolist()]; | |
| 50 | |
| 51 # H = cvCreateMat(3, 3, CV_64FC1); | |
| 52 | |
| 53 # cvFindHomography(imagePoints, worldPoints, H); | |
| 54 | |
| 55 if '--help' in options.keys() or '-h' in options.keys() or len(options) == 0: | |
| 56 print('Usage: {0} --help|-h [-p point-correspondences.txt] [ -i video-frame] [ -w world-frame] [n number-points] [-u unit-per-pixel=1]'.format(sys.argv[0])) | |
| 57 print('''The input data can be provided either as point correspondences already saved | |
| 58 in a text file or inputed by clicking a certain number of points (>=4) | |
| 59 in a video frame and a world image. | |
| 60 | |
| 61 The point correspondence file contains at least 4 non-colinear point coordinates | |
| 62 with the following format: | |
| 63 - the first two lines are the x and y coordinates in the projected space (usually world space) | |
| 64 - the last two lines are the x and y coordinates in the origin space (usually image space) | |
| 65 | |
| 66 If providing video and world images, with a number of points to input | |
| 67 and a ration to convert pixels to world distance unit (eg meters per pixel), | |
| 68 the images will be shown in turn and the user should click | |
| 69 in the same order the corresponding points in world and image spaces. ''') | |
| 70 sys.exit() | |
| 71 | |
| 72 homography = np.array([]) | |
| 73 if '-p' in options.keys(): | |
| 74 worldPts, videoPts = cvutils.loadPointCorrespondences(options['-p']) | |
| 75 homography, mask = cv2.findHomography(videoPts, worldPts) # method=0, ransacReprojThreshold=3 | |
| 76 elif '-i' in options.keys() and '-w' in options.keys(): | |
| 77 nPoints = 4 | |
| 78 if '-n' in options.keys(): | |
| 79 nPoints = int(options['-n']) | |
| 80 unitsPerPixel = 1 | |
| 81 if '-u' in options.keys(): | |
| 82 unitsPerPixel = float(options['-u']) | |
| 83 worldImg = plt.imread(options['-w']) | |
| 84 videoImg = plt.imread(options['-i']) | |
| 85 print('Click on {0} points in the video frame'.format(nPoints)) | |
| 86 plt.figure() | |
| 87 plt.imshow(videoImg) | |
| 88 videoPts = np.array(plt.ginput(nPoints)) | |
| 89 print('Click on {0} points in the world image'.format(nPoints)) | |
| 90 plt.figure() | |
| 91 plt.imshow(worldImg) | |
| 92 worldPts = unitsPerPixel*np.array(plt.ginput(nPoints)) | |
| 93 plt.close('all') | |
| 94 homography, mask = cv2.findHomography(videoPts, worldPts) | |
| 95 # save the points in file | |
| 96 f = open('point-correspondences.txt', 'a') | |
| 97 np.savetxt(f, worldPts.T) | |
| 98 np.savetxt(f, videoPts.T) | |
| 99 f.close() | |
| 100 | |
| 101 if homography.size>0: | |
| 102 np.savetxt('homography.txt',homography) | |
| 103 | |
| 104 if '-i' in options.keys() and homography.size>0: | |
| 105 videoImg = cv2.imread(options['-i']) | |
| 106 worldImg = cv2.imread(options['-w']) | |
| 107 invHomography = np.linalg.inv(homography) | |
| 108 projectedWorldPts = cvutils.projectArray(invHomography, worldPts.T).T | |
| 109 if '-u' in options.keys(): | |
| 110 unitsPerPixel = float(options['-u']) | |
| 111 projectedVideoPts = cvutils.projectArray(invHomography, videoPts.T).T | |
| 112 for i in range(worldPts.shape[0]): | |
| 113 cv2.circle(videoImg,tuple(np.int32(np.round(videoPts[i]))),2,cvutils.cvRed) | |
| 114 cv2.circle(videoImg,tuple(np.int32(np.round(projectedWorldPts[i]))),2,cvutils.cvBlue) | |
| 115 if '-u' in options.keys(): | |
| 116 cv2.circle(worldImg,tuple(np.int32(np.round(worldPts[i]/unitsPerPixel))),2,cvutils.cvRed) | |
| 117 cv2.circle(worldImg,tuple(np.int32(np.round(projectedVideoPts[i]/unitsPerPixel))),2,cvutils.cvRed) | |
| 118 #print('img: {0} / projected: {1}'.format(videoPts[i], p)) | |
| 119 cv2.imshow('video frame',videoImg) | |
| 120 if '-u' in options.keys(): | |
| 121 cv2.imshow('world image',worldImg) | |
| 122 cv2.waitKey() |
