分割验证码图像中的字母
Segmenting letters in a Captcha image
我在 Python 中编写了这个算法,用于使用 scikit-image 读取验证码:
from skimage.color import rgb2gray
from skimage import io
def process(self, image):
"""
Processes a CAPTCHA by removing noise
Args:
image (str): The file path of the image to process
"""
input = io.imread(image)
histogram = {}
for x in range(input.shape[0]):
for y in range(input.shape[1]):
pixel = input[x, y]
hex = '%02x%02x%02x' % (pixel[0], pixel[1], pixel[2])
if hex in histogram:
histogram[hex] += 1
else:
histogram[hex] = 1
histogram = sorted(histogram, key = histogram.get, reverse=True)
threshold = len(histogram) * 0.015
for x in range(input.shape[0]):
for y in range(input.shape[1]):
pixel = input[x, y]
hex = '%02x%02x%02x' % (pixel[0], pixel[1], pixel[2])
index = histogram.index(hex)
if index < 3 or index > threshold:
input[x, y] = [255, 255, 255, 255]
input = rgb2gray(~input)
io.imsave(image, input)
之前:
之后:
它工作得很好,我在 运行 之后通过 Google 的 Tesseract OCR 得到了不错的结果,但我想让它变得更好。我认为将字母拉直会产生更好的结果。我的问题是我该怎么做?
我知道我需要以某种方式将字母装箱,如下所示:
然后,对于每个字符,根据垂直线或水平线将其旋转一定度数。
我最初的想法是确定一个字符的中心(可能是通过在直方图中找到最常用颜色的簇)然后扩展一个框直到它找到黑色,但同样,我不太确定如何去做吧。
在图像分割中使用哪些常见做法来实现此结果?
编辑:
最后,进一步细化滤色器并将 Tesseract 限制为仅字符产生了几乎 100% 准确的结果,没有任何偏斜校正。
从技术上讲,您想要执行的操作在计算机视觉中称为对象的校正,为此您必须对对象应用几何变换,我有一段代码可以对对象应用校正(二进制).这是代码(使用 opencv 库):
def deskew(image, width):
(h, w) = image.shape[:2]
moments = cv2.moments(image)
skew = moments["mu11"] / moments["mu02"]
M = np.float32([[1, skew, -0.5 * w * skew],[0, 1, 0]])
image = cv2.warpAffine(image, M, (w, h), flags = cv2.WARP_INVERSE_MAP | cv2.INTER_LINEAR)
return image
我在 Python 中编写了这个算法,用于使用 scikit-image 读取验证码:
from skimage.color import rgb2gray
from skimage import io
def process(self, image):
"""
Processes a CAPTCHA by removing noise
Args:
image (str): The file path of the image to process
"""
input = io.imread(image)
histogram = {}
for x in range(input.shape[0]):
for y in range(input.shape[1]):
pixel = input[x, y]
hex = '%02x%02x%02x' % (pixel[0], pixel[1], pixel[2])
if hex in histogram:
histogram[hex] += 1
else:
histogram[hex] = 1
histogram = sorted(histogram, key = histogram.get, reverse=True)
threshold = len(histogram) * 0.015
for x in range(input.shape[0]):
for y in range(input.shape[1]):
pixel = input[x, y]
hex = '%02x%02x%02x' % (pixel[0], pixel[1], pixel[2])
index = histogram.index(hex)
if index < 3 or index > threshold:
input[x, y] = [255, 255, 255, 255]
input = rgb2gray(~input)
io.imsave(image, input)
之前:
之后:
它工作得很好,我在 运行 之后通过 Google 的 Tesseract OCR 得到了不错的结果,但我想让它变得更好。我认为将字母拉直会产生更好的结果。我的问题是我该怎么做?
我知道我需要以某种方式将字母装箱,如下所示:
然后,对于每个字符,根据垂直线或水平线将其旋转一定度数。
我最初的想法是确定一个字符的中心(可能是通过在直方图中找到最常用颜色的簇)然后扩展一个框直到它找到黑色,但同样,我不太确定如何去做吧。
在图像分割中使用哪些常见做法来实现此结果?
编辑:
最后,进一步细化滤色器并将 Tesseract 限制为仅字符产生了几乎 100% 准确的结果,没有任何偏斜校正。
从技术上讲,您想要执行的操作在计算机视觉中称为对象的校正,为此您必须对对象应用几何变换,我有一段代码可以对对象应用校正(二进制).这是代码(使用 opencv 库):
def deskew(image, width):
(h, w) = image.shape[:2]
moments = cv2.moments(image)
skew = moments["mu11"] / moments["mu02"]
M = np.float32([[1, skew, -0.5 * w * skew],[0, 1, 0]])
image = cv2.warpAffine(image, M, (w, h), flags = cv2.WARP_INVERSE_MAP | cv2.INTER_LINEAR)
return image