【发布时间】: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