def add_next_img(self, new_img): self.prev_img = self.cur_img self.cur_img = new_img levels_number, self.frame_pyramid = cv2.buildOpticalFlowPyramid( (self.cur_img * 255).astype(np.uint8), self.lucas_kanade_params.win_size, self.lucas_kanade_params.max_level, None, False) next_pts, status, err = None, None, None for level in range(levels_number, -1, -1): next_pts, status, err = cv2.calcOpticalFlowPyrLK( self.prev_frame_pyramid[level], self.frame_pyramid[level], self.corners.astype(np.float32) / 2**level, (next_pts * 2) if next_pts is not None else None, flags=cv2.OPTFLOW_USE_INITIAL_FLOW if next_pts is not None else 0, winSize=self.lucas_kanade_params.win_size, maxLevel=self.lucas_kanade_params.max_level, criteria=self.lucas_kanade_params.criteria) mask = ((status == 1) & (err < np.quantile(err, 0.9))).reshape(-1) self.corners = next_pts[mask] self.corner_sizes = self.corner_sizes[mask] self.corner_ids = self.corner_ids[mask] self.detect_corners_pyramidal(self.create_filter_mask()) self.prev_frame_pyramid = self.frame_pyramid self.prev_img = self.cur_img
def remove_old_points(image_0, image_1, ids, points, sizes, depth): depth, image_0_pyramid = cv2.buildOpticalFlowPyramid((image_0 * 255).astype(np.uint8), WIN_SIZE, PYRAMID_DEPTH, None, False) depth, image_1_pyramid = cv2.buildOpticalFlowPyramid((image_1 * 255).astype(np.uint8), WIN_SIZE, PYRAMID_DEPTH, None, False) next_pts = None status = None err = None next_pts, status, err = cv2.calcOpticalFlowPyrLK(image_0_pyramid[0], image_1_pyramid[0], np.array(points, dtype=np.float32).reshape(-1, 2), None, status, err, WIN_SIZE, PYRAMID_DEPTH, (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, QUALITY_LEVEL)) prev_pts, prev_status, prev_err = cv2.calcOpticalFlowPyrLK(image_1_pyramid[0], image_0_pyramid[0], np.array(next_pts, dtype=np.float32).reshape(-1, 2), None, status, err, WIN_SIZE, PYRAMID_DEPTH, (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, QUALITY_LEVEL)) status = np.ravel(status) prev_status = prev_status.ravel() import math distances = np.array([math.sqrt(x * x + y * y) for (x, y) in np.reshape(points - prev_pts, (-1, 2))]) good_corners = (status == 1) & (prev_status == 1) & (distances < 0.7) return (list(np.asarray(ids)[good_corners]), list(np.asarray(next_pts)[good_corners]), list(np.asarray(sizes)[good_corners]))
def PyramidDemo(): maxLevel = 2 img1 = cv2.imread("D:/OpenCv4Programmers/datas/frm1.png") cv2.imshow("Img1", img1) cv2.waitKey(10) img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) ret, pyrLevels = cv2.buildOpticalFlowPyramid(img1, (21, 21), maxLevel) for i in list(range(0, len(pyrLevels), 2)): level = pyrLevels[i] cv2.imshow("Level %d" % (i / 2), level) print(" Level ", i / 2, " Size ", level.shape) cv2.waitKey(0) cv2.destroyAllWindows()
def add_new_points(image_1, ids, points, sizes, next_id, mask, first_frame=False): depth, image_1_pyramid = cv2.buildOpticalFlowPyramid((image_1 * 255).astype(np.uint8), WIN_SIZE, PYRAMID_DEPTH, None, False) for level in range(depth): # 0.00075 if first_frame else 0.075, new_points = cv2.goodFeaturesToTrack(image_1_pyramid[level], maxCorners=MAX_CORNERS - len(points), qualityLevel=0.00075 if first_frame else 0.075, minDistance=(2 ** depth) * MIN_DISTANCE_C, mask=mask, blockSize=BLOCK_SIZE) if new_points is not None: new_points = new_points.reshape(-1, 2).astype(np.float32) if new_points is not None: for (x, y) in new_points: if len(points) == MAX_CORNERS: break if mask[int(y), int(x)] > 0: ids.append(next_id) next_id += 1 points.append((int(x) * (2 ** level), int(y) * (2 ** level))) sizes.append((2 ** level) * BLOCK_SIZE) cv2.circle(mask, (int(x), int(y)), BLOCK_SIZE, color=0, thickness=-1) mask = cv2.pyrDown(mask).astype(np.uint8) return ids, points, sizes, next_id
def __init__(self, init_img, shi_tomasi_params=ShiTomasiParams(), lucas_kanade_params=LucasKanadeParams()): self.lucas_kanade_params = lucas_kanade_params self.shi_tomasi_params = shi_tomasi_params self.prev_img = None self.cur_img = init_img self.img_shape = init_img.shape self.corners = np.empty((0, 2)) self.corner_ids = np.empty((0, 1)) self.corner_sizes = np.empty((0, 1)) _, self.frame_pyramid = cv2.buildOpticalFlowPyramid( (self.cur_img * 255).astype(np.uint8), self.lucas_kanade_params.win_size, self.lucas_kanade_params.max_level, None, False) self.detect_corners_pyramidal(self.create_filter_mask()) self.prev_img = self.cur_img self.prev_frame_pyramid = self.frame_pyramid
height = img2.shape[0] length = len(corner_pts2) for i in range(length): x, y = corner_pts2[i] color = hsv(int(i/length * 255)) if x < height: pyplot.arrow(x, y, u[x][y], v[x][y], color=color) else: pyplot.arrow(x, y, u[y][x], v[y][x], color=color) # Show the images pyplot.show() # Parameters for making a pyramid kSize = 9 pyr_params = dict( winSize = (kSize, kSize), maxLevel = 4 ) # Open the images img1 = cv2.imread("./basketball1.png", cv2.IMREAD_GRAYSCALE) img2 = cv2.imread("./basketball2.png", cv2.IMREAD_GRAYSCALE) # Create a pyramid of the image retval, pyr1 = cv2.buildOpticalFlowPyramid(img1, **pyr_params) retval, pyr2 = cv2.buildOpticalFlowPyramid(img2, **pyr_params) # Apply the Lucas-Kanade algorithm to the images lucasKanade(img1, img2) # Apply the Lucas_kanade algorithm to the pyramids lucasKanade(pyr1, pyr2, True, retval + 1)
def _build_impl(frame_sequence: pims.FramesSequence, builder: _CornerStorageBuilder) -> None: height, width = frame_sequence.frame_shape[:2] max_levels = min(np.log2(height), np.log2(width)).astype(np.int8) MAX_CORNERS = 2000 WINDOW_SIZE = (15, 15) MIN_DIST = 10 BLOCK_SIZE = 3 QUALITY_LEVEL = 0.075 pyramid = None prev_pyramid = None levels = 0 prev_levels = 0 pts_id = 0 corner_pts = np.ndarray((0, 2), dtype=np.float32) corner_ids = np.ndarray(0, dtype=np.int32) corner_szs = np.ndarray(0, dtype=np.float32) for frame, image in enumerate(frame_sequence): levels, pyramid = cv2.buildOpticalFlowPyramid(img=(image * 255).astype( np.uint8), winSize=WINDOW_SIZE, maxLevel=max_levels, pyramid=None, withDerivatives=False) if corner_pts.size > 0: prev_corners = corner_pts cur_corners = None min_levels = min(levels, prev_levels) for level in reversed(range(min_levels)): cur_corners, status, err = cv2.calcOpticalFlowPyrLK( prevImg=prev_pyramid[level], nextImg=pyramid[level], prevPts=(prev_corners / (2**level)).astype(np.float32), nextPts=cur_corners * 2 if cur_corners is not None else None, winSize=WINDOW_SIZE) mask = status[:, 0] == 1 corner_pts = cur_corners[mask] corner_ids = corner_ids[mask] corner_szs = corner_szs[mask] def prohibit_circle(mask, x, y, r): mask = cv2.circle(img=mask, center=(np.int(x), np.int(y)), radius=np.int(r), color=0, thickness=-1) n = corner_szs.size if n >= MAX_CORNERS: prev_pyramid = pyramid prev_levels = levels builder.set_corners_at_frame( frame, FrameCorners(corner_ids, corner_pts, corner_szs)) continue new_pts = [] new_ids = [] new_szs = [] mask = np.full((height, width), 255, dtype=np.uint8) for x, y, r in np.column_stack((corner_pts, corner_szs)): prohibit_circle(mask, x, y, r) for i in range(levels): if i > 0: mask = cv2.pyrDown(mask).astype(np.uint8) new_corners = cv2.goodFeaturesToTrack(image=pyramid[i], maxCorners=max( 0, MAX_CORNERS - n), qualityLevel=QUALITY_LEVEL, minDistance=MIN_DIST, mask=mask, blockSize=BLOCK_SIZE) if new_corners is None: continue for x, y in new_corners[:, 0, :]: if not mask[np.int(y), np.int(x)]: continue new_pts.append((x * (2.0**i), y * (2.0**i))) new_ids.append(pts_id) new_szs.append(BLOCK_SIZE * (2.0**i)) pts_id += 1 prohibit_circle(mask, x, y, BLOCK_SIZE) if new_pts: corner_pts = np.concatenate((corner_pts, new_pts)) corner_ids = np.concatenate((corner_ids, new_ids)) corner_szs = np.concatenate((corner_szs, new_szs)) prev_pyramid = pyramid prev_levels = levels builder.set_corners_at_frame( frame, FrameCorners(corner_ids, corner_pts, corner_szs))
def _build_impl(frame_sequence: pims.FramesSequence, builder: _CornerStorageBuilder) -> None: h, w = frame_sequence.frame_shape[:2] # Corner detection parameters: blocks_approx_count = 1500 block_size = round((w * h / blocks_approx_count)**0.5) corner_min_rel_quality = 0.05 # Flow tracking parameters: window_size = (21, 21) pyramid_max_level = 4 - 1 def mask_exclude_neighbors(positions, sizes): result = np.full((h, w), 255, dtype=np.uint8) for (y, x), s in zip(positions, sizes): cv2.circle(result, (int(np.rint(y)), int(np.rint(x))), int(np.rint(s)), color=0, thickness=-1) return result prev_pyramid = None corner_ids = np.array([], dtype=int).reshape((0, 1)) corners = np.array([], dtype=np.float32).reshape((0, 2)) corner_sizes = np.array([], dtype=np.float32).reshape((0, 1)) next_id = 1 for frame_idx, frame_img in enumerate(frame_sequence): img8 = np.rint(255 * frame_img).astype(np.uint8) last_level, pyramid = cv2.buildOpticalFlowPyramid( img8, winSize=window_size, maxLevel=pyramid_max_level, withDerivatives=False) if corners.size != 0: next_corners, status, err = cv2.calcOpticalFlowPyrLK( prevImg=prev_pyramid[0], nextImg=pyramid[0], prevPts=corners, winSize=window_size, nextPts=None, minEigThreshold=1e-6) err_flat = err.reshape(-1).astype(np.float64) err_ok = err_flat[status.flat == 1] err_q = np.quantile(err_ok, 0.9) keep = np.logical_and(status.flat == 1, err_flat < 2.0 * err_q) corner_ids = corner_ids[keep] corners = next_corners[keep] corner_sizes = corner_sizes[keep] mask = mask_exclude_neighbors(corners, corner_sizes) for level, level_img in enumerate(pyramid): new_corners = cv2.goodFeaturesToTrack( level_img, maxCorners=0, qualityLevel=corner_min_rel_quality, minDistance=block_size * 0.7, blockSize=block_size, mask=mask, gradientSize=3) if new_corners is not None: new_corners = new_corners.reshape((-1, 2)) * 2**level count = new_corners.shape[0] corner_ids = np.concatenate( (corner_ids, np.arange(next_id, next_id + count).reshape( (-1, 1)))) next_id += count corners = np.concatenate((corners, new_corners)) corner_sizes = np.concatenate( (corner_sizes, np.full(count, block_size * 1.5**level).reshape( (-1, 1)))) mask = mask_exclude_neighbors(corners, corner_sizes) for _ in range(level + 1): mask = cv2.pyrDown(mask).astype(np.uint8) mask[mask <= 100] = 0 prev_pyramid = pyramid builder.set_corners_at_frame( frame_idx, FrameCorners(corner_ids, corners, corner_sizes))
def buildOpticalFlowPyramid(img, win_size, max_level): """ :Returns: retval, pyramid """ return cv2.buildOpticalFlowPyramid(img, win_size, max_level)