pytagmapper icon indicating copy to clipboard operation
pytagmapper copied to clipboard

Update guess function

Open adithyashankar-97 opened this issue 1 year ago • 1 comments

Hi @markisus

Thanks a lot for this amazing work. I was using the inside out tracker and i was wondering if you could explain this one function.

def update_guess(self, guess_idx, tags, force_update = False):
        tx_world_viewpoint = self.txs_world_viewpoint[guess_idx]
        error = self.errors[guess_idx]
        regularizer = self.regularizers[guess_idx]
        
        JtJ = np.zeros((6,6))
        rtJ = np.zeros((1,6))
        curr_error = 0

        for tag_id, corners in tags:
            tx_world_tag = self.txs_world_tag.get(tag_id, None)
            if tx_world_tag is None:
                continue

            corners = np.array(corners).reshape((8,1))
            tx_viewpoint_tag = SE3_inv(tx_world_viewpoint) @ tx_world_tag
            projected_corners, dcorners_dcamera, _ = project(self.camera_matrix, tx_viewpoint_tag, self.get_corners_mat(tag_id))

            residual = projected_corners - corners
            JtJ += dcorners_dcamera.T @ dcorners_dcamera
            rtJ += residual.T @ dcorners_dcamera
            curr_error += (residual.T @ residual)[0,0]

        if curr_error > error:
            regularizer *= 25
        else:
            regularizer *= 0.5

        improved = curr_error < error

        regularizer = min(regularizer, self.max_regularizer)
        regularizer = max(regularizer, 1e-3)

        if improved or force_update:
            update = np.linalg.solve(JtJ + regularizer * np.eye(6), -rtJ.T)
            tx_world_viewpoint = tx_world_viewpoint @ se3_exp(update)
            # tx_world_viewpoint = heuristic_flip_tx_world_cam(tx_world_viewpoint @ se3_exp(update))

        error = curr_error

        self.txs_world_viewpoint[guess_idx] = tx_world_viewpoint
        self.regularizers[guess_idx] = regularizer
        self.errors[guess_idx] = error

If possible can you please share a small blog or writeup on the total approach as well?

Thank you

adithyashankar-97 avatar Mar 14 '24 11:03 adithyashankar-97

Hi @adithyashankar-97

This is doing Levenberg Marquardt iterations. See this article https://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm

In my code, J stands for Jacobian, and r for residual. This is probably very similar to what OpenCV's solvePnP does under the hood as well.

markisus avatar Feb 28 '25 17:02 markisus