Skip to content

Commit cd700f1

Browse files
Deployed to GitHub Pages
1 parent a83f3e0 commit cd700f1

551 files changed

Lines changed: 3204 additions & 1530 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
0 Bytes
Binary file not shown.
Binary file not shown.
Binary file not shown.
0 Bytes
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
0 Bytes
Binary file not shown.

dev/_downloads/0e3607c7429e3d908cebaf5856d396a7/plot_matching.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
},
1616
"outputs": [],
1717
"source": [
18-
"import numpy as np\nfrom matplotlib import pyplot as plt\n\nfrom skimage import data\nfrom skimage.util import img_as_float\nfrom skimage.feature import (\n corner_harris,\n corner_subpix,\n corner_peaks,\n plot_matched_features,\n)\nfrom skimage.transform import warp, AffineTransform\nfrom skimage.exposure import rescale_intensity\nfrom skimage.color import rgb2gray\nfrom skimage.measure import ransac\n\n\n# generate synthetic checkerboard image and add gradient for the later matching\ncheckerboard = img_as_float(data.checkerboard())\nimg_orig = np.zeros(list(checkerboard.shape) + [3])\nimg_orig[..., 0] = checkerboard\ngradient_r, gradient_c = np.mgrid[0 : img_orig.shape[0], 0 : img_orig.shape[1]] / float(\n img_orig.shape[0]\n)\nimg_orig[..., 1] = gradient_r\nimg_orig[..., 2] = gradient_c\nimg_orig = rescale_intensity(img_orig)\nimg_orig_gray = rgb2gray(img_orig)\n\n# warp synthetic image\ntform = AffineTransform(scale=(0.9, 0.9), rotation=0.2, translation=(20, -10))\nimg_warped = warp(img_orig, tform.inverse, output_shape=(200, 200))\nimg_warped_gray = rgb2gray(img_warped)\n\n# extract corners using Harris' corner measure\ncoords_orig = corner_peaks(\n corner_harris(img_orig_gray), threshold_rel=0.001, min_distance=5\n)\ncoords_warped = corner_peaks(\n corner_harris(img_warped_gray), threshold_rel=0.001, min_distance=5\n)\n\n# determine sub-pixel corner position\ncoords_orig_subpix = corner_subpix(img_orig_gray, coords_orig, window_size=9)\ncoords_warped_subpix = corner_subpix(img_warped_gray, coords_warped, window_size=9)\n\n\ndef gaussian_weights(window_ext, sigma=1):\n y, x = np.mgrid[-window_ext : window_ext + 1, -window_ext : window_ext + 1]\n g = np.zeros(y.shape, dtype=np.double)\n g[:] = np.exp(-0.5 * (x**2 / sigma**2 + y**2 / sigma**2))\n g /= 2 * np.pi * sigma * sigma\n return g\n\n\ndef match_corner(coord, window_ext=5):\n r, c = np.round(coord).astype(np.intp)\n window_orig = img_orig[\n r - window_ext : r + window_ext + 1, c - window_ext : c + window_ext + 1, :\n ]\n\n # weight pixels depending on distance to center pixel\n weights = gaussian_weights(window_ext, 3)\n weights = np.dstack((weights, weights, weights))\n\n # compute sum of squared differences to all corners in warped image\n SSDs = []\n for cr, cc in coords_warped:\n window_warped = img_warped[\n cr - window_ext : cr + window_ext + 1,\n cc - window_ext : cc + window_ext + 1,\n :,\n ]\n SSD = np.sum(weights * (window_orig - window_warped) ** 2)\n SSDs.append(SSD)\n\n # use corner with minimum SSD as correspondence\n min_idx = np.argmin(SSDs)\n return coords_warped_subpix[min_idx]\n\n\n# find correspondences using simple weighted sum of squared differences\nsrc = []\ndst = []\nfor coord in coords_orig_subpix:\n src.append(coord)\n dst.append(match_corner(coord))\nsrc = np.array(src)\ndst = np.array(dst)\n\n\n# estimate affine transform model using all coordinates\nmodel = AffineTransform()\nmodel.estimate(src, dst)\n\n# robustly estimate affine transform model with RANSAC\nmodel_robust, inliers = ransac(\n (src, dst), AffineTransform, min_samples=3, residual_threshold=2, max_trials=100\n)\noutliers = inliers == False\n\n\n# compare \"true\" and estimated transform parameters\nprint(\"Ground truth:\")\nprint(\n f'Scale: ({tform.scale[1]:.4f}, {tform.scale[0]:.4f}), '\n f'Translation: ({tform.translation[1]:.4f}, '\n f'{tform.translation[0]:.4f}), '\n f'Rotation: {-tform.rotation:.4f}'\n)\nprint(\"Affine transform:\")\nprint(\n f'Scale: ({model.scale[0]:.4f}, {model.scale[1]:.4f}), '\n f'Translation: ({model.translation[0]:.4f}, '\n f'{model.translation[1]:.4f}), '\n f'Rotation: {model.rotation:.4f}'\n)\nprint(\"RANSAC:\")\nprint(\n f'Scale: ({model_robust.scale[0]:.4f}, {model_robust.scale[1]:.4f}), '\n f'Translation: ({model_robust.translation[0]:.4f}, '\n f'{model_robust.translation[1]:.4f}), '\n f'Rotation: {model_robust.rotation:.4f}'\n)\n\n# visualize correspondence\nfig, ax = plt.subplots(nrows=2, ncols=1)\n\nplt.gray()\n\ninlier_idxs = np.nonzero(inliers)[0]\nplot_matched_features(\n img_orig_gray,\n img_warped_gray,\n keypoints0=src,\n keypoints1=dst,\n matches=np.column_stack((inlier_idxs, inlier_idxs)),\n ax=ax[0],\n matches_color='b',\n)\nax[0].axis('off')\nax[0].set_title('Correct correspondences')\n\noutlier_idxs = np.nonzero(outliers)[0]\nplot_matched_features(\n img_orig_gray,\n img_warped_gray,\n keypoints0=src,\n keypoints1=dst,\n matches=np.column_stack((outlier_idxs, outlier_idxs)),\n ax=ax[1],\n matches_color='r',\n)\nax[1].axis('off')\nax[1].set_title('Faulty correspondences')\n\nplt.show()"
18+
"import numpy as np\nfrom matplotlib import pyplot as plt\n\nfrom skimage import data\nfrom skimage.util import img_as_float\nfrom skimage.feature import (\n corner_harris,\n corner_subpix,\n corner_peaks,\n plot_matched_features,\n)\nfrom skimage.transform import warp, AffineTransform\nfrom skimage.exposure import rescale_intensity\nfrom skimage.color import rgb2gray\nfrom skimage.measure import ransac\n\n\n# generate synthetic checkerboard image and add gradient for the later matching\ncheckerboard = img_as_float(data.checkerboard())\nimg_orig = np.zeros(list(checkerboard.shape) + [3])\nimg_orig[..., 0] = checkerboard\ngradient_r, gradient_c = np.mgrid[0 : img_orig.shape[0], 0 : img_orig.shape[1]] / float(\n img_orig.shape[0]\n)\nimg_orig[..., 1] = gradient_r\nimg_orig[..., 2] = gradient_c\nimg_orig = rescale_intensity(img_orig)\nimg_orig_gray = rgb2gray(img_orig)\n\n# warp synthetic image\ntform = AffineTransform(scale=(0.9, 0.9), rotation=0.2, translation=(20, -10))\nimg_warped = warp(img_orig, tform.inverse, output_shape=(200, 200))\nimg_warped_gray = rgb2gray(img_warped)\n\n# extract corners using Harris' corner measure\ncoords_orig = corner_peaks(\n corner_harris(img_orig_gray), threshold_rel=0.001, min_distance=5\n)\ncoords_warped = corner_peaks(\n corner_harris(img_warped_gray), threshold_rel=0.001, min_distance=5\n)\n\n# determine sub-pixel corner position\ncoords_orig_subpix = corner_subpix(img_orig_gray, coords_orig, window_size=9)\ncoords_warped_subpix = corner_subpix(img_warped_gray, coords_warped, window_size=9)\n\n\ndef gaussian_weights(window_ext, sigma=1):\n y, x = np.mgrid[-window_ext : window_ext + 1, -window_ext : window_ext + 1]\n g = np.zeros(y.shape, dtype=np.double)\n g[:] = np.exp(-0.5 * (x**2 / sigma**2 + y**2 / sigma**2))\n g /= 2 * np.pi * sigma * sigma\n return g\n\n\ndef match_corner(coord, window_ext=5):\n r, c = np.round(coord).astype(np.intp)\n window_orig = img_orig[\n r - window_ext : r + window_ext + 1, c - window_ext : c + window_ext + 1, :\n ]\n\n # weight pixels depending on distance to center pixel\n weights = gaussian_weights(window_ext, 3)\n weights = np.dstack((weights, weights, weights))\n\n # compute sum of squared differences to all corners in warped image\n SSDs = []\n for cr, cc in coords_warped:\n window_warped = img_warped[\n cr - window_ext : cr + window_ext + 1,\n cc - window_ext : cc + window_ext + 1,\n :,\n ]\n SSD = np.sum(weights * (window_orig - window_warped) ** 2)\n SSDs.append(SSD)\n\n # use corner with minimum SSD as correspondence\n min_idx = np.argmin(SSDs)\n return coords_warped_subpix[min_idx]\n\n\n# find correspondences using simple weighted sum of squared differences\nsrc = []\ndst = []\nfor coord in coords_orig_subpix:\n src.append(coord)\n dst.append(match_corner(coord))\nsrc = np.array(src)\ndst = np.array(dst)\n\n\n# estimate affine transform model using all coordinates\nmodel = AffineTransform.from_estimate(src, dst)\n\n# robustly estimate affine transform model with RANSAC\nmodel_robust, inliers = ransac(\n (src, dst), AffineTransform, min_samples=3, residual_threshold=2, max_trials=100\n)\noutliers = inliers == False\n\n\n# compare \"true\" and estimated transform parameters\nprint(\"Ground truth:\")\nprint(\n f'Scale: ({tform.scale[1]:.4f}, {tform.scale[0]:.4f}), '\n f'Translation: ({tform.translation[1]:.4f}, '\n f'{tform.translation[0]:.4f}), '\n f'Rotation: {-tform.rotation:.4f}'\n)\nprint(\"Affine transform:\")\nprint(\n f'Scale: ({model.scale[0]:.4f}, {model.scale[1]:.4f}), '\n f'Translation: ({model.translation[0]:.4f}, '\n f'{model.translation[1]:.4f}), '\n f'Rotation: {model.rotation:.4f}'\n)\nprint(\"RANSAC:\")\nprint(\n f'Scale: ({model_robust.scale[0]:.4f}, {model_robust.scale[1]:.4f}), '\n f'Translation: ({model_robust.translation[0]:.4f}, '\n f'{model_robust.translation[1]:.4f}), '\n f'Rotation: {model_robust.rotation:.4f}'\n)\n\n# visualize correspondence\nfig, ax = plt.subplots(nrows=2, ncols=1)\n\nplt.gray()\n\ninlier_idxs = np.nonzero(inliers)[0]\nplot_matched_features(\n img_orig_gray,\n img_warped_gray,\n keypoints0=src,\n keypoints1=dst,\n matches=np.column_stack((inlier_idxs, inlier_idxs)),\n ax=ax[0],\n matches_color='b',\n)\nax[0].axis('off')\nax[0].set_title('Correct correspondences')\n\noutlier_idxs = np.nonzero(outliers)[0]\nplot_matched_features(\n img_orig_gray,\n img_warped_gray,\n keypoints0=src,\n keypoints1=dst,\n matches=np.column_stack((outlier_idxs, outlier_idxs)),\n ax=ax[1],\n matches_color='r',\n)\nax[1].axis('off')\nax[1].set_title('Faulty correspondences')\n\nplt.show()"
1919
]
2020
}
2121
],
Binary file not shown.

0 commit comments

Comments
 (0)