#!/usr/bin/env python3 """Process YorkUrban dataset for L-CNN network Usage: dataset/york.py dataset/york.py (-h | --help ) Examples: python dataset/york.py /datadir/york data/york Arguments: Original data directory of YorkUrban Directory of the output Options: -h --help Show this screen. """ import os import sys import glob import json import os.path as osp from itertools import combinations import cv2 import numpy as np import skimage.draw import matplotlib.pyplot as plt from docopt import docopt from scipy.io import loadmat from scipy.ndimage import zoom try: sys.path.append(".") sys.path.append("..") from lcnn.utils import parmap except Exception: raise def inrange(v, shape): return 0 <= v[0] < shape[0] and 0 <= v[1] < shape[1] def to_int(x): return tuple(map(int, x)) def save_heatmap(prefix, image, lines): im_rescale = (512, 512) heatmap_scale = (128, 128) fy, fx = heatmap_scale[1] / image.shape[0], heatmap_scale[0] / image.shape[1] jmap = np.zeros((1,) + heatmap_scale, dtype=np.float32) joff = np.zeros((1, 2) + heatmap_scale, dtype=np.float32) lmap = np.zeros(heatmap_scale, dtype=np.float32) lines[:, :, 0] = np.clip(lines[:, :, 0] * fx, 0, heatmap_scale[0] - 1e-4) lines[:, :, 1] = np.clip(lines[:, :, 1] * fy, 0, heatmap_scale[1] - 1e-4) lines = lines[:, :, ::-1] junc = [] jids = {} def jid(jun): jun = tuple(jun[:2]) if jun in jids: return jids[jun] jids[jun] = len(junc) junc.append(np.array(jun + (0,))) return len(junc) - 1 lnid = [] lpos, lneg = [], [] for v0, v1 in lines: lnid.append((jid(v0), jid(v1))) lpos.append([junc[jid(v0)], junc[jid(v1)]]) vint0, vint1 = to_int(v0), to_int(v1) jmap[0][vint0] = 1 jmap[0][vint1] = 1 rr, cc, value = skimage.draw.line_aa(*to_int(v0), *to_int(v1)) lmap[rr, cc] = np.maximum(lmap[rr, cc], value) for v in junc: vint = to_int(v[:2]) joff[0, :, vint[0], vint[1]] = v[:2] - vint - 0.5 llmap = zoom(lmap, [0.5, 0.5]) lineset = set([frozenset(l) for l in lnid]) for i0, i1 in combinations(range(len(junc)), 2): if frozenset([i0, i1]) not in lineset: v0, v1 = junc[i0], junc[i1] vint0, vint1 = to_int(v0[:2] / 2), to_int(v1[:2] / 2) rr, cc, value = skimage.draw.line_aa(*vint0, *vint1) lneg.append([v0, v1, i0, i1, np.average(np.minimum(value, llmap[rr, cc]))]) # assert np.sum((v0 - v1) ** 2) > 0.01 assert len(lneg) != 0 lneg.sort(key=lambda l: -l[-1]) junc = np.array(junc, dtype=np.float32) Lpos = np.array(lnid, dtype=np.int) Lneg = np.array([l[2:4] for l in lneg][:4000], dtype=np.int) lpos = np.array(lpos, dtype=np.float32) lneg = np.array([l[:2] for l in lneg[:2000]], dtype=np.float32) image = cv2.resize(image, im_rescale) # plt.subplot(131), plt.imshow(lmap) # plt.subplot(132), plt.imshow(image) # for i0, i1 in Lpos: # plt.scatter(junc[i0][1] * 4, junc[i0][0] * 4) # plt.scatter(junc[i1][1] * 4, junc[i1][0] * 4) # plt.plot([junc[i0][1] * 4, junc[i1][1] * 4], [junc[i0][0] * 4, junc[i1][0] * 4]) # plt.subplot(133), plt.imshow(lmap) # for i0, i1 in Lneg[:150]: # plt.plot([junc[i0][1], junc[i1][1]], [junc[i0][0], junc[i1][0]]) # plt.show() np.savez_compressed( f"{prefix}_label.npz", aspect_ratio=image.shape[1] / image.shape[0], jmap=jmap, # [J, H, W] joff=joff, # [J, 2, H, W] lmap=lmap, # [H, W] junc=junc, # [Na, 3] Lpos=Lpos, # [M, 2] Lneg=Lneg, # [M, 2] lpos=lpos, # [Np, 2, 3] (y, x, t) for the last dim lneg=lneg, # [Nn, 2, 3] ) cv2.imwrite(f"{prefix}.png", image) # plt.imshow(jmap[0]) # plt.savefig("/tmp/1jmap0.jpg") # plt.imshow(jmap[1]) # plt.savefig("/tmp/2jmap1.jpg") # plt.imshow(lmap) # plt.savefig("/tmp/3lmap.jpg") # plt.imshow(Lmap[2]) # plt.savefig("/tmp/4ymap.jpg") # plt.imshow(jwgt[0]) # plt.savefig("/tmp/5jwgt.jpg") # plt.cla() # plt.imshow(jmap[0]) # for i in range(8): # plt.quiver( # 8 * jmap[0] * cdir[i] * np.cos(2 * math.pi / 16 * i), # 8 * jmap[0] * cdir[i] * np.sin(2 * math.pi / 16 * i), # units="xy", # angles="xy", # scale_units="xy", # scale=1, # minlength=0.01, # width=0.1, # zorder=10, # color="w", # ) # plt.savefig("/tmp/6cdir.jpg") # plt.cla() # plt.imshow(lmap) # plt.quiver( # 2 * lmap * np.cos(ldir), # 2 * lmap * np.sin(ldir), # units="xy", # angles="xy", # scale_units="xy", # scale=1, # minlength=0.01, # width=0.1, # zorder=10, # color="w", # ) # plt.savefig("/tmp/7ldir.jpg") # plt.cla() # plt.imshow(jmap[1]) # plt.quiver( # 8 * jmap[1] * np.cos(tdir), # 8 * jmap[1] * np.sin(tdir), # units="xy", # angles="xy", # scale_units="xy", # scale=1, # minlength=0.01, # width=0.1, # zorder=10, # color="w", # ) # plt.savefig("/tmp/8tdir.jpg") def main(): args = docopt(__doc__) data_root = args[""] data_output = args[""] os.makedirs(data_output, exist_ok=True) dataset = sorted(glob.glob(osp.join(data_root, "*/*.jpg"))) def handle(iname): prefix = osp.split(iname)[1].replace(".jpg", "") im = cv2.imread(iname) mat = loadmat(iname.replace(".jpg", "LinesAndVP.mat")) lines = np.array(mat["lines"]).reshape(-1, 2, 2) path = osp.join(data_output, prefix) save_heatmap(f"{path}", im[::, ::], lines) print(f"Finishing {path}") parmap(handle, dataset) if __name__ == "__main__": main()