def get_hw(pt, return_rot=False): pt = pt.copy() R = su.unrotate2d(pt) mu = np.median(pt, axis=0) pt = (pt - mu[None, :]).dot(R.T) + mu[None, :] h, w = np.max(pt, axis=0) - np.min(pt, axis=0) if return_rot: return h, w, R return h, w
def get_hw(pt,return_rot=False): pt = pt.copy() R = su.unrotate2d(pt) mu = np.median(pt,axis=0) pt = (pt-mu[None,:]).dot(R.T) + mu[None,:] h,w = np.max(pt,axis=0) - np.min(pt,axis=0) if return_rot: return h,w,R return h,w
def get_text_placement_mask(xyz, mask, plane, pad=2, viz=False): """ Returns a binary mask in which text can be placed. Also returns a homography from original image to this rectified mask. XYZ : (HxWx3) image xyz coordinates MASK : (HxW) : non-zero pixels mark the object mask REGION : DICT output of TextRegions.get_regions PAD : number of pixels to pad the placement-mask by """ contour, hier = cv2.findContours(mask.copy().astype('uint8'), mode=cv2.RETR_CCOMP, method=cv2.CHAIN_APPROX_SIMPLE) contour = [np.squeeze(c).astype('float') for c in contour] # plane = np.array([plane[1],plane[0],plane[2],plane[3]]) H, W = mask.shape[:2] # bring the contour 3d points to fronto-parallel config: pts, pts_fp = [], [] center = np.array([W, H]) / 2 n_front = np.array([0.0, 0.0, -1.0]) for i in range(len(contour)): cnt_ij = contour[i] xyz = su.DepthCamera.plane2xyz(center, cnt_ij, plane) R = su.rot3d(plane[:3], n_front) xyz = xyz.dot(R.T) pts_fp.append(xyz[:, :2]) pts.append(cnt_ij) # unrotate in 2D plane: rect = cv2.minAreaRect(pts_fp[0].copy().astype('float32')) box = np.array(cv2.boxPoints(rect)) R2d = su.unrotate2d(box.copy()) box = np.vstack([box, box[0, :]]) # close the box for visualization mu = np.median(pts_fp[0], axis=0) pts_tmp = (pts_fp[0] - mu[None, :]).dot(R2d.T) + mu[None, :] boxR = (box - mu[None, :]).dot(R2d.T) + mu[None, :] # rescale the unrotated 2d points to approximately # the same scale as the target region: s = rescale_frontoparallel(pts_tmp, boxR, pts[0]) boxR *= s for i in range(len(pts_fp)): pts_fp[i] = s * ((pts_fp[i] - mu[None, :]).dot(R2d.T) + mu[None, :]) # paint the unrotated contour points: minxy = -np.min(boxR, axis=0) + pad // 2 ROW = np.max(ssd.pdist(np.atleast_2d(boxR[:, 0]).T)) COL = np.max(ssd.pdist(np.atleast_2d(boxR[:, 1]).T)) place_mask = 255 * np.ones( (int(np.ceil(COL)) + pad, int(np.ceil(ROW)) + pad), 'uint8') pts_fp_i32 = [(pts_fp[i] + minxy[None, :]).astype('int32') for i in range(len(pts_fp))] cv2.drawContours(place_mask, pts_fp_i32, -1, 0, thickness=cv2.FILLED, lineType=8, hierarchy=hier) if not TextRegions.filter_rectified((~place_mask).astype('float') / 255): return # calculate the homography H, _ = cv2.findHomography(pts[0].astype('float32').copy(), pts_fp_i32[0].astype('float32').copy(), method=0) Hinv, _ = cv2.findHomography(pts_fp_i32[0].astype('float32').copy(), pts[0].astype('float32').copy(), method=0) if viz: plt.subplot(1, 2, 1) plt.imshow(mask) plt.subplot(1, 2, 2) plt.imshow(~place_mask) for i in range(len(pts_fp_i32)): plt.scatter(pts_fp_i32[i][:, 0], pts_fp_i32[i][:, 1], edgecolors='none', facecolor='g', alpha=0.5) plt.show() return place_mask, H, Hinv
def get_text_placement_mask(xyz,mask,plane,pad=2,viz=False): """ Returns a binary mask in which text can be placed. Also returns a homography from original image to this rectified mask. XYZ : (HxWx3) image xyz coordinates MASK : (HxW) : non-zero pixels mark the object mask REGION : DICT output of TextRegions.get_regions PAD : number of pixels to pad the placement-mask by """ img, contour, hier = cv2.findContours(mask.copy().astype('uint8'), mode=cv2.RETR_CCOMP, method=cv2.CHAIN_APPROX_SIMPLE) contour = [np.squeeze(c).astype('float') for c in contour] #plane = np.array([plane[1],plane[0],plane[2],plane[3]]) H,W = mask.shape[:2] # bring the contour 3d points to fronto-parallel config: pts,pts_fp = [],[] center = np.array([W,H])/2 n_front = np.array([0.0,0.0,-1.0]) for i in range(len(contour)): cnt_ij = contour[i] xyz = su.DepthCamera.plane2xyz(center, cnt_ij, plane) R = su.rot3d(plane[:3],n_front) xyz = xyz.dot(R.T) pts_fp.append(xyz[:,:2]) pts.append(cnt_ij) # unrotate in 2D plane: rect = cv2.minAreaRect(pts_fp[0].copy().astype('float32')) box = np.array(cv2.boxPoints(rect)) R2d = su.unrotate2d(box.copy()) box = np.vstack([box,box[0,:]]) #close the box for visualization mu = np.median(pts_fp[0],axis=0) pts_tmp = (pts_fp[0]-mu[None,:]).dot(R2d.T) + mu[None,:] boxR = (box-mu[None,:]).dot(R2d.T) + mu[None,:] # rescale the unrotated 2d points to approximately # the same scale as the target region: s = rescale_frontoparallel(pts_tmp,boxR,pts[0]) boxR *= s for i in range(len(pts_fp)): pts_fp[i] = s*((pts_fp[i]-mu[None,:]).dot(R2d.T) + mu[None,:]) # paint the unrotated contour points: minxy = -np.min(boxR,axis=0) + pad//2 ROW = np.max(ssd.pdist(np.atleast_2d(boxR[:,0]).T)) COL = np.max(ssd.pdist(np.atleast_2d(boxR[:,1]).T)) place_mask = 255*np.ones((int(np.ceil(COL)+pad),int(np.ceil(ROW)+pad)),'uint8') pts_fp_i32 = [(pts_fp[i]+minxy[None,:]).astype('int32') for i in range(len(pts_fp))] cv2.drawContours(place_mask,pts_fp_i32,-1,0, thickness=cv2.FILLED, lineType=8,hierarchy=hier) if not TextRegions.filter_rectified((~place_mask).astype('float')/255): return # calculate the homography H,_ = cv2.findHomography(pts[0].astype('float32').copy(), pts_fp_i32[0].astype('float32').copy(), method=0) Hinv,_ = cv2.findHomography(pts_fp_i32[0].astype('float32').copy(), pts[0].astype('float32').copy(), method=0) if viz: plt.subplot(1,2,1) plt.imshow(mask) plt.subplot(1,2,2) plt.imshow(~place_mask) plt.hold(True) for i in range(len(pts_fp_i32)): plt.scatter(pts_fp_i32[i][:,0],pts_fp_i32[i][:,1], edgecolors='none',facecolor='g',alpha=0.5) plt.show() return place_mask,H,Hinv