【问题标题】:How to improve image alignment with OpenCV如何使用 OpenCV 改进图像对齐
【发布时间】:2022-03-24 01:42:25
【问题描述】:

我有一个项目,人们可以在其中添加有关水电费的数据,并且里面还有 OCR 服务。因此,我所在城市的人们只需加载账单照片即可识别账单数据。问题是我无法完全达到这个目标。

所以我有 4 个高质量的账单模板(例如供暖、水、煤气等)。示例如下:

我的用户可以加载这样的图片:

对齐后我得到这个结果:

很明显,我无法通过这样的图像获得良好的识别。 我用于图像对齐的代码:

import os

import cv2
import numpy as np

from config import folder_path_aligned_images

MAX_FEATURES = 500
GOOD_MATCH_PERCENT = 0.15


class OpenCV:
    @classmethod
    def match_img(cls, im1, im2):
        # Convert images to grayscale
        im1_gray = cv2.cvtColor(im1, cv2.COLOR_BGR2GRAY)
        im2_gray = cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY)

        # Detect ORB features and compute descriptors.
        orb = cv2.ORB_create(MAX_FEATURES)
        keypoints_1, descriptors_1 = orb.detectAndCompute(im1_gray, None)
        keypoints_2, descriptors_2 = orb.detectAndCompute(im2_gray, None)

        # Match features.
        matcher = cv2.DescriptorMatcher_create(cv2.DESCRIPTOR_MATCHER_BRUTEFORCE_HAMMING)
        matches = matcher.match(descriptors_1, descriptors_2, None)

        # Sort matches by score
        matches.sort(key=lambda x: x.distance, reverse=False)

        # Remove not so good matches
        num_good_matches = int(len(matches) * GOOD_MATCH_PERCENT)
        matches = matches[:num_good_matches]

        # Draw top matches
        im_matches = cv2.drawMatches(im1, keypoints_1, im2, keypoints_2, matches, None)
        cv2.imwrite(os.path.join(folder_path_aligned_images, "matches.jpg"), im_matches)

        # Extract location of good matches
        points_1 = np.zeros((len(matches), 2), dtype=np.float32)
        points_2 = np.zeros((len(matches), 2), dtype=np.float32)

        for i, match in enumerate(matches):
            points_1[i, :] = keypoints_1[match.queryIdx].pt
            points_2[i, :] = keypoints_2[match.trainIdx].pt

        # Find homography
        h, mask = cv2.findHomography(points_1, points_2, cv2.RANSAC)

        # Use homography
        height, width, channels = im2.shape
        im1_reg = cv2.warpPerspective(im1, h, (width, height))

        return im1_reg, h

    @classmethod
    def align_img(cls, template_path, raw_img_path, result_img_path):
        # Read reference image
        ref_filename = template_path
        print("Reading reference image: ", ref_filename)
        im_reference = cv2.imread(ref_filename, cv2.IMREAD_COLOR)

        # Read image to be aligned
        im_filename = raw_img_path
        print("Reading image to align: ", im_filename)
        im = cv2.imread(raw_img_path, cv2.IMREAD_COLOR)

        print("Aligning images ...")
        # Registered image will be resorted in im_reg.
        im_reg, h = OpenCV.match_img(im, im_reference)

        # Write aligned image to disk.
        print("Saving aligned image : ", result_img_path)
        cv2.imwrite(result_img_path, im_reg)

        return result_img_path

我该如何改进?

编辑: 匹配的图像:

【问题讨论】:

  • 能否在两张图片中显示检测到的特征点?
  • 请注意,匹配特征点可能不是最好的主意,因为图像包含无数相似的特征。另一方面,找到轮廓(在对比鲜明的背景上)很容易。
  • 我附上了带有火柴的图片。那么@YvesDaoust,您认为有更好的方法来对齐此类内容吗?
  • “更好”是“好”的最高级,但我看到计算出的单应性非常差。我已经给过提示了。
  • 我会使用 SIFT(SIFT 专利最近过期)和 Lowe 比率距离来过滤匹配项。如果背景始终是这张桌子(与纸张颜色不同的统一背景),另一种方法是检测并提取这张纸。

标签: python opencv image-processing ocr


【解决方案1】:

不知道这是否有帮助将近一年,但我使用了您拥有的类似代码,对我有用的是增加 MAX_FEATURES 的数量(我使用 80000,但您甚至可能不需要那么多) 并减少 GOOD_MATCH_PERCENT 到喜欢 0.05。试着玩数字!

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 2019-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-31
  • 2014-01-02
  • 1970-01-01
  • 2022-08-16
  • 2016-12-12
相关资源
最近更新 更多