【发布时间】:2011-11-29 18:09:38
【问题描述】:
我确实有一组值在 0 到 255 之间的数组 (20x40)(灰度图像)。
我需要将给定数组与用作参考的其他 10 个数组进行比较,然后选择最接近给定图像的数组。
我知道这看起来像 OCR,但在这种情况下,OCR 没有任何好处。
我已经尝试计算abs(x-y),但结果还不够好。
捕获:
参考:
【问题讨论】:
标签: python image-processing numpy scipy ocr
我确实有一组值在 0 到 255 之间的数组 (20x40)(灰度图像)。
我需要将给定数组与用作参考的其他 10 个数组进行比较,然后选择最接近给定图像的数组。
我知道这看起来像 OCR,但在这种情况下,OCR 没有任何好处。
我已经尝试计算abs(x-y),但结果还不够好。
捕获:
参考:
【问题讨论】:
标签: python image-processing numpy scipy ocr
我在 bskyb 用从视频流中提取的 OCRing 帧解决了一个类似的问题。
我最终为图像(x,y, w, h) 中的每个数字创建了一个坐标字典,并编写了一个脚本来生成数百个这些数字并将它们保存为掩码。然后其中一位测试人员选择了最好的掩码(失真最小的掩码)并将它们保存为 1.bmp 用于数字 1,2.bmb 用于数字 2...
我们必须为每个数字创建 18 个不同的图像,以支持我们拥有的各种分辨率 aspect_ratio。然后在 OCR 过程开始时将这些掩码加载到字典中。我们将图像存储为一个 numpy 数组。
def load_samples(parent_dir=r'c:\masks'):
"""Loads the OCR samples of all digits of all possible variations into
memory.
"""
m = dict() # m is our map, a dict of lists of numpy arrays
for d in os.listdir(parent_dir):
if not os.path.isdir(os.path.join(parent_dir, d)):
continue
m[d] = []
for i in range(10): # 10 images [0..9]
filename = os.path.join(parent_dir, d, '%d.bmp'%i)
m[d].append(imread(filename))
return m
然后对于我们读取的每张图像,我们通过将数字转换为 numpy 数组并将其与所有掩码进行比较来将其划分为数字,以找到最接近的匹配并据此选择它。 digits_map 是从上面的 load_samples 返回的内容。
def image2digit(image, digits_map, video_args):
"""Our home made OCR, we compare each image of digit with 10 images of all
possible digits [0..10] and return the closest match.
"""
def absdiff(img1, img2):
func = numpy.vectorize(lambda a, b: abs(int(a)-int(b)))
v = func(img1, img2)
w = coordinates[video_args]['w']
h = coordinates[video_args]['h']
return numpy.sum(v)/(w*h) # takes the average
# convert the image to a numpy array
image_array = fromimage(image) # from scipy.misc
# compare it with all variations
scores = []
for (i, ir) in enumerate(digits_map[video_args]):
scores.append(absdiff(ir, image_array))
# return the best match as a string
index = numpy.argmin(scores)
return str(index)
这对我们来说效果很好,除了在一些失真帧中 6 被 OCRed 视为 5。我正在尝试在比较之前将图像转换为灰度,看看这是否有助于解决图像失真问题。
【讨论】:
只需将像素相乘,然后取所有像素的总和:
这就像没有偏移的cross-correlation。 (scipy.signal.correlate)
numpy 中的命令就是
sum(a * b)
这可能有一个名字,但我不知道它是什么。
我猜你打算将参考数字与测量图像一一进行比较,看看它是哪个数字?
您必须首先将参考数字与它们自己进行比较,以找出完美匹配的样子,并以此标准化每个数字以获得相似度。不完美的匹配将是一个小于此的值。例如:
0 1 3
1 2 3
2 0 0
与自身比较会产生 28,但与自身比较会产生 25
0 1 3
0 2 3
1 0 0
所以你的匹配是 25/28 = 0.89。所以你知道第二张图片很接近,但不一样
【讨论】: