Udayraj123 / OMRChecker

Evaluate OMR sheets fast and accurately using a scanner 🖨 or your phone 🤳.
MIT License
784 stars 324 forks source link

Autorotation stabilzation #189

Closed palash018 closed 4 months ago

palash018 commented 4 months ago
palash018 commented 4 months ago

some functions in file AutoAlign.py are not used they may have some use in future to make this more generic with a lot of experimentation.

palash018 commented 4 months ago

Experimental code for future more generic use case for zoom in zoom out cases and decoupling from croppage,croponmarkers

def get_best_match(self, image):
        res = cv2.matchTemplate(image, self.reference_image, cv2.TM_CCOEFF)
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
        best_val, best_rotation = max_val, None
        rotations = [
            None,
            cv2.ROTATE_90_CLOCKWISE,
            cv2.ROTATE_180,
            cv2.ROTATE_90_COUNTERCLOCKWISE,
        ]
        values = [best_val]
        scale = 2

        for applied_scale in np.arange(
            -scale,
            scale,
            0.5,
        ):
            if applied_scale <= 0:
                continue
            if applied_scale > 0:
                rescaled_marker = ImageUtils.resize_util(
                    self.reference_image,
                    u_width=int(
                        min(
                            self.reference_image.shape[0] * applied_scale,
                            image.shape[0],
                        )
                    ),
                    u_height=int(
                        min(
                            self.reference_image.shape[1] * applied_scale,
                            image.shape[1],
                        )
                    ),
                )
            else:
                applied_scale = -1 / applied_scale
                rescaled_marker = ImageUtils.resize_util(
                    self.reference_image,
                    u_width=int(self.reference_image.shape[0] * applied_scale),
                    u_height=int(self.reference_image.shape[1] * applied_scale),
                )
            for angle in range(0, 20, 5):
                logger.info(angle)
                logger.info("SHOW SOMETHING HERE")
                reference_image = self.rotate_image(self.reference_image, angle)
                InteractionUtils.show("reference", reference_image, pause=True)
                for rotation in rotations:
                    rotated_img = cv2.rotate(image, rotation)
                    res = cv2.matchTemplate(rotated_img, reference_image, cv2.TM_CCOEFF)
                    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
                    logger.info(rotation, max_val)
                    if max_val > best_val:
                        best_val = max_val
                        best_rotation = rotation
                        values.append(max_val)
        logger.info(
            "AutoRotate Applied with rotation",
            best_rotation,
            "best value",
            best_val,
            "having values",
            values,
        )
        logger.info(
            "AutoRotate Applied with rotation",
            best_rotation,
            "having value",
            best_val,
            "having values",
            values,
        )
        return best_rotation

additional methods methods = [ "cv.TM_CCOEFF", "cv.TM_CCOEFF_NORMED", "cv.TM_CCORR", "cv.TM_CCORR_NORMED", "cv.TM_SQDIFF", "cv.TM_SQDIFF_NORMED", ]

Udayraj123 commented 4 months ago

This should help close https://github.com/Udayraj123/OMRChecker/issues/36

Udayraj123 commented 3 months ago

@palash018 there's an issue with the current template matching algorithm - when white areas are dominated for the detection, we're not getting a unique maxima to use - https://discord.com/channels/590134763784896514/1239153894479626290/1267171400595017768

edit: Sorted, reference image size wasn't accurate (due to an imshow resize issue on macos) Now we can see the spike