Mercurial > hg > nsaunier > traffic-intelligence
comparison scripts/compute-homography.py @ 933:8ac7f61c6e4f
major rework of homography calibration, no in ideal points if correcting for distortion
| author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
|---|---|
| date | Fri, 14 Jul 2017 02:11:21 -0400 |
| parents | f5a49b603e8b |
| children | 39691b460fca |
comparison
equal
deleted
inserted
replaced
| 932:66f382852e61 | 933:8ac7f61c6e4f |
|---|---|
| 34 parser.add_argument('--undistort', dest = 'undistort', help = 'undistort the video (because features have been extracted that way', action = 'store_true') | 34 parser.add_argument('--undistort', dest = 'undistort', help = 'undistort the video (because features have been extracted that way', action = 'store_true') |
| 35 parser.add_argument('--save', dest = 'saveImages', help = 'save the undistorted video frame (display option must be chosen)', action = 'store_true') | 35 parser.add_argument('--save', dest = 'saveImages', help = 'save the undistorted video frame (display option must be chosen)', action = 'store_true') |
| 36 | 36 |
| 37 args = parser.parse_args() | 37 args = parser.parse_args() |
| 38 | 38 |
| 39 # TODO process camera intrinsic and extrinsic parameters to obtain image to world homography, taking example from Work/src/python/generate-homography.py script | |
| 40 # cameraMat = load(videoFilenamePrefix+'-camera.txt'); | |
| 41 # T1 = cameraMat[3:6,:].copy(); | |
| 42 # A = cameraMat[0:3,0:3].copy(); | |
| 43 | |
| 44 # # pay attention, rotation may be the transpose | |
| 45 # # R = T1[:,0:3].T; | |
| 46 # R = T1[:,0:3]; | |
| 47 # rT = dot(R, T1[:,3]/1000); | |
| 48 # T = zeros((3,4),'f'); | |
| 49 # T[:,0:3] = R[:]; | |
| 50 # T[:,3] = rT; | |
| 51 | |
| 52 # AT = dot(A,T); | |
| 53 | |
| 54 # nPoints = 4; | |
| 55 # worldPoints = cvCreateMat(nPoints, 3, CV_64FC1); | |
| 56 # imagePoints = cvCreateMat(nPoints, 3, CV_64FC1); | |
| 57 | |
| 58 # # extract homography from the camera calibration | |
| 59 # worldPoints = cvCreateMat(4, 3, CV_64FC1); | |
| 60 # imagePoints = cvCreateMat(4, 3, CV_64FC1); | |
| 61 | |
| 62 # worldPoints[0,:] = [[1, 1, 0]]; | |
| 63 # worldPoints[1,:] = [[1, 2, 0]]; | |
| 64 # worldPoints[2,:] = [[2, 1, 0]]; | |
| 65 # worldPoints[3,:] = [[2, 2, 0]]; | |
| 66 | |
| 67 # wPoints = [[1,1,2,2], | |
| 68 # [1,2,1,2], | |
| 69 # [0,0,0,0]]; | |
| 70 # iPoints = utils.worldToImage(AT, wPoints); | |
| 71 | |
| 72 # for i in range(nPoints): | |
| 73 # imagePoints[i,:] = [iPoints[:,i].tolist()]; | |
| 74 | |
| 75 # H = cvCreateMat(3, 3, CV_64FC1); | |
| 76 | |
| 77 # cvFindHomography(imagePoints, worldPoints, H); | |
| 78 | |
| 79 | |
| 80 homography = np.array([]) | 39 homography = np.array([]) |
| 81 if args.pointCorrespondencesFilename is not None: | 40 if args.pointCorrespondencesFilename is not None: |
| 82 worldPts, videoPts = cvutils.loadPointCorrespondences(args.pointCorrespondencesFilename) | 41 worldPts, videoPts = cvutils.loadPointCorrespondences(args.pointCorrespondencesFilename) |
| 83 homography, mask = cv2.findHomography(videoPts, worldPts) # method=0, ransacReprojThreshold=3 | 42 homography, mask = cv2.findHomography(videoPts, worldPts) # method=0, ransacReprojThreshold=3 |
| 84 elif args.tsaiCameraFilename is not None: # hack using PDTV | 43 elif args.tsaiCameraFilename is not None: # hack using PDTV |
| 88 homography = cvutils.computeHomographyFromPDTV(camera) | 47 homography = cvutils.computeHomographyFromPDTV(camera) |
| 89 elif args.videoFrameFilename is not None and args.worldFilename is not None: | 48 elif args.videoFrameFilename is not None and args.worldFilename is not None: |
| 90 worldImg = plt.imread(args.worldFilename) | 49 worldImg = plt.imread(args.worldFilename) |
| 91 videoImg = plt.imread(args.videoFrameFilename) | 50 videoImg = plt.imread(args.videoFrameFilename) |
| 92 if args.undistort: | 51 if args.undistort: |
| 93 [map1, map2] = cvutils.computeUndistortMaps(videoImg.shape[1], videoImg.shape[0], args.undistortedImageMultiplication, np.loadtxt(args.intrinsicCameraMatrixFilename), args.distortionCoefficients) | 52 [map1, map2], newCameraMatrix = cvutils.computeUndistortMaps(videoImg.shape[1], videoImg.shape[0], args.undistortedImageMultiplication, np.loadtxt(args.intrinsicCameraMatrixFilename), args.distortionCoefficients) |
| 94 videoImg = cv2.remap(videoImg, map1, map2, interpolation=cv2.INTER_LINEAR) | 53 videoImg = cv2.remap(videoImg, map1, map2, interpolation=cv2.INTER_LINEAR) |
| 95 print('Click on {} points in the video frame'.format(args.nPoints)) | 54 print('Click on {} points in the video frame'.format(args.nPoints)) |
| 96 plt.figure() | 55 plt.figure() |
| 97 plt.imshow(videoImg) | 56 plt.imshow(videoImg) |
| 98 plt.tight_layout() | 57 plt.tight_layout() |
| 99 videoPts = np.array(plt.ginput(args.nPoints, timeout=3000)) | 58 videoPts = np.array(plt.ginput(args.nPoints, timeout=3000)) |
| 59 if args.undistort: | |
| 60 videoPts = cvutils.newCameraProject(videoPts, np.linalg.inv(newCameraMatrix)) | |
| 100 print('Click on {} points in the world image'.format(args.nPoints)) | 61 print('Click on {} points in the world image'.format(args.nPoints)) |
| 101 plt.figure() | 62 plt.figure() |
| 102 plt.imshow(worldImg) | 63 plt.imshow(worldImg) |
| 103 plt.tight_layout() | 64 plt.tight_layout() |
| 104 worldPts = args.unitsPerPixel*np.array(plt.ginput(args.nPoints, timeout=3000)) | 65 worldPts = args.unitsPerPixel*np.array(plt.ginput(args.nPoints, timeout=3000)) |
| 115 | 76 |
| 116 if args.displayPoints and args.videoFrameFilename is not None and args.worldFilename is not None and homography.size>0 and args.tsaiCameraFilename is None: | 77 if args.displayPoints and args.videoFrameFilename is not None and args.worldFilename is not None and homography.size>0 and args.tsaiCameraFilename is None: |
| 117 worldImg = cv2.imread(args.worldFilename) | 78 worldImg = cv2.imread(args.worldFilename) |
| 118 videoImg = cv2.imread(args.videoFrameFilename) | 79 videoImg = cv2.imread(args.videoFrameFilename) |
| 119 if args.undistort: | 80 if args.undistort: |
| 120 [map1, map2] = cvutils.computeUndistortMaps(videoImg.shape[1], videoImg.shape[0], args.undistortedImageMultiplication, np.loadtxt(args.intrinsicCameraMatrixFilename), args.distortionCoefficients) | 81 [map1, map2], newCameraMatrix = cvutils.computeUndistortMaps(videoImg.shape[1], videoImg.shape[0], args.undistortedImageMultiplication, np.loadtxt(args.intrinsicCameraMatrixFilename), args.distortionCoefficients) |
| 121 videoImg = cv2.remap(videoImg, map1, map2, interpolation=cv2.INTER_LINEAR) | 82 videoImg = cv2.remap(videoImg, map1, map2, interpolation=cv2.INTER_LINEAR) |
| 122 if args.saveImages: | 83 if args.saveImages: |
| 123 cv2.imwrite(utils.removeExtension(args.videoFrameFilename)+'-undistorted.png', videoImg) | 84 cv2.imwrite(utils.removeExtension(args.videoFrameFilename)+'-undistorted.png', videoImg) |
| 124 invHomography = np.linalg.inv(homography) | 85 invHomography = np.linalg.inv(homography) |
| 125 projectedWorldPts = cvutils.projectArray(invHomography, worldPts.T).T | 86 projectedWorldPts = cvutils.homographyProject(worldPts.T, invHomography).T |
| 126 projectedVideoPts = cvutils.projectArray(homography, videoPts.T).T | 87 projectedVideoPts = cvutils.homographyProject(videoPts.T, homography).T |
| 88 if args.undistort: | |
| 89 projectedWorldPts = cvutils.newCameraProject(projectedWorldPts.T, newCameraMatrix).T | |
| 90 videoPts = cvutils.newCameraProject(videoPts.T, newCameraMatrix).T | |
| 127 for i in range(worldPts.shape[0]): | 91 for i in range(worldPts.shape[0]): |
| 128 # world image | 92 # world image |
| 129 cv2.circle(worldImg,tuple(np.int32(np.round(worldPts[i]/args.unitsPerPixel))),2,cvutils.cvBlue['default']) | 93 cv2.circle(worldImg,tuple(np.int32(np.round(worldPts[i]/args.unitsPerPixel))),2,cvutils.cvBlue['default']) |
| 130 cv2.circle(worldImg,tuple(np.int32(np.round(projectedVideoPts[i]/args.unitsPerPixel))),2,cvutils.cvRed['default']) | 94 cv2.circle(worldImg,tuple(np.int32(np.round(projectedVideoPts[i]/args.unitsPerPixel))),2,cvutils.cvRed['default']) |
| 131 cv2.putText(worldImg, str(i+1), tuple(np.int32(np.round(worldPts[i]/args.unitsPerPixel))+5), cv2.FONT_HERSHEY_PLAIN, 2., cvutils.cvBlue['default'], 2) | 95 cv2.putText(worldImg, str(i+1), tuple(np.int32(np.round(worldPts[i]/args.unitsPerPixel))+5), cv2.FONT_HERSHEY_PLAIN, 2., cvutils.cvBlue['default'], 2) |
