|
| 1 | +import matplotlib.pyplot as plt |
| 2 | +import cv2 |
| 3 | +import numpy as np |
| 4 | + |
| 5 | + |
| 6 | +def plot_imgs(imgs, titles=None, cmap='brg', ylabel='', normalize=True, ax=None, |
| 7 | + r=(0, 1), dpi=100): |
| 8 | + n = len(imgs) |
| 9 | + if not isinstance(cmap, list): |
| 10 | + cmap = [cmap]*n |
| 11 | + if ax is None: |
| 12 | + _, ax = plt.subplots(1, n, figsize=(6*n, 6), dpi=dpi) |
| 13 | + if n == 1: |
| 14 | + ax = [ax] |
| 15 | + else: |
| 16 | + if not isinstance(ax, list): |
| 17 | + ax = [ax] |
| 18 | + assert len(ax) == len(imgs) |
| 19 | + for i in range(n): |
| 20 | + if len(imgs[i].shape) == 3: |
| 21 | + if imgs[i].shape[-1] == 3: |
| 22 | + imgs[i] = imgs[i][..., ::-1] # BGR to RGB |
| 23 | + elif imgs[i].shape[-1] == 1: |
| 24 | + imgs[i] = imgs[i][..., 0] |
| 25 | + if len(imgs[i].shape) == 2 and cmap[i] == 'brg': |
| 26 | + cmap[i] = 'gray' |
| 27 | + ax[i].imshow(imgs[i], cmap=plt.get_cmap(cmap[i]), |
| 28 | + vmin=None if normalize else r[0], |
| 29 | + vmax=None if normalize else r[1]) |
| 30 | + if titles: |
| 31 | + ax[i].set_title(titles[i]) |
| 32 | + ax[i].get_yaxis().set_ticks([]) |
| 33 | + ax[i].get_xaxis().set_ticks([]) |
| 34 | + for spine in ax[i].spines.values(): # remove frame |
| 35 | + spine.set_visible(False) |
| 36 | + ax[0].set_ylabel(ylabel) |
| 37 | + plt.tight_layout() |
| 38 | + |
| 39 | + |
| 40 | +def draw_datches(img1, kp1, img2, kp2, matches, color=None, kp_radius=5, |
| 41 | + thickness=2, margin=20): |
| 42 | + # Create frame |
| 43 | + if len(img1.shape) == 3: |
| 44 | + new_shape = (max(img1.shape[0], img2.shape[0]), |
| 45 | + img1.shape[1]+img2.shape[1]+margin, |
| 46 | + img1.shape[2]) |
| 47 | + elif len(img1.shape) == 2: |
| 48 | + new_shape = (max(img1.shape[0], |
| 49 | + img2.shape[0]), |
| 50 | + img1.shape[1]+img2.shape[1]+margin) |
| 51 | + new_img = np.ones(new_shape, type(img1.flat[0]))*255 |
| 52 | + |
| 53 | + # Place original images |
| 54 | + new_img[0:img1.shape[0], 0:img1.shape[1]] = img1 |
| 55 | + new_img[0:img2.shape[0], |
| 56 | + img1.shape[1]+margin:img1.shape[1]+img2.shape[1]+margin] = img2 |
| 57 | + |
| 58 | + # Draw lines between matches |
| 59 | + if color: |
| 60 | + c = color |
| 61 | + for m in matches: |
| 62 | + # Generate random color for RGB/BGR and grayscale images as needed. |
| 63 | + if not color: |
| 64 | + if len(img1.shape) == 3: |
| 65 | + c = np.random.randint(0, 256, 3) |
| 66 | + else: |
| 67 | + c = np.random.randint(0, 256) |
| 68 | + c = (int(c[0]), int(c[1]), int(c[2])) |
| 69 | + |
| 70 | + end1 = tuple(np.round(kp1[m.trainIdx].pt).astype(int)) |
| 71 | + end2 = tuple(np.round(kp2[m.queryIdx].pt).astype(int) |
| 72 | + + np.array([img1.shape[1]+margin, 0])) |
| 73 | + cv2.line(new_img, end1, end2, c, thickness, lineType=cv2.LINE_AA) |
| 74 | + cv2.circle(new_img, end1, kp_radius, c, thickness, lineType=cv2.LINE_AA) |
| 75 | + cv2.circle(new_img, end2, kp_radius, c, thickness, lineType=cv2.LINE_AA) |
| 76 | + return new_img |
0 commit comments