【问题标题】:Optical Braille recognition using OpenCV使用 OpenCV 的光学盲文识别
【发布时间】:2018-11-13 22:39:49
【问题描述】:

我实际上是在尝试识别文档中的盲文字符。我打算将盲文文档转换为纯文本。 我正在使用带有 Java 的 OpenCV 来进行图像处理。

首先,我导入了一个盲文文档的图像:

然后,我进行了一些图像处理,以便对原始图像进行二值化。我读过重要的步骤是:

  • 将图像转换为灰度级
  • 降低噪音
  • 增强边缘对比度
  • 二值化图像

这是我使用的代码:

public static void main(String args[]) {

    Mat imgGrayscale = new Mat();

    Mat image = Imgcodecs.imread("C:/Users/original_braille.jpg", 1);  


    Imgproc.cvtColor(image, imgGrayscale, Imgproc.COLOR_BGR2GRAY);

    Imgproc.GaussianBlur(imgGrayscale, imgGrayscale, new Size(3, 3), 0);
    Imgproc.adaptiveThreshold(imgGrayscale, imgGrayscale, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 5, 4);

    Imgproc.medianBlur(imgGrayscale, imgGrayscale, 3);
    Imgproc.threshold(imgGrayscale, imgGrayscale, 0, 255, Imgproc.THRESH_OTSU);

    Imgproc.GaussianBlur(imgGrayscale, imgGrayscale, new Size(3, 3), 0);
    Imgproc.threshold(imgGrayscale, imgGrayscale, 0, 255, Imgproc.THRESH_OTSU);

    Imgcodecs.imwrite( "C:/Users/Jean-Baptiste/Desktop/Reconnaissance_de_formes/result.jpg", imgGrayscale );

}

这一步我得到了以下结果:

据我说,我们可以提高这张图片的质量以获得更好的效果,但我对不同的图片处理技术没有经验。我可以提高过滤器的质量吗?

之后,我想对图像进行分割,以检测该文档的不同字符。我想将文档的不同字符分开,以便将它们转换为文本。

例如我手动绘制了文档的分隔线:

但是我没有找到这一步的解决方案。是否有可能对 OpenCV 做同样的事情?

【问题讨论】:

  • 要在图像上查找点,您可能会从这里得到一些想法:docs.opencv.org/3.3.1/d3/db4/tutorial_py_watershed.html
  • 要找到分隔线,如果您的文档格式正确(即行间距均匀),您可以执行以下操作: 1- 从您的第一遍获取平均点大小 s 2- 获取与点 3 没有交集的大小为 s/2 的行组 - 递归合并彼此相邻的行
  • 您好,感谢您的回复
  • 我会尝试实现这种方法。我不是很有经验,但我希望我能做到。

标签: java opencv image-processing ocr image-segmentation


【解决方案1】:

这是一个小脚本,用于查找图像中的线条。它在 python 中,我没有安装 java 版本的 openCV,但我认为无论如何你都可以了解该算法。

找到垂直线并不容易,因为点之间的间距取决于彼此跟随的字母。您可能可以尝试使用一些常见字母的模板匹配算法。鉴于此时您知道字母的高度,它不应该太难。

当然,整个方法假设文档没有旋转。

import numpy as np
import cv2

# This is just the transposition of your code in python
img      = cv2.imread('L1ZzA.jpg')
gray     = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur     = cv2.GaussianBlur(gray,(3,3),0)
thres    = cv2.adaptiveThreshold(blur,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,5,4)
blur2    = cv2.medianBlur(thres,3)
ret2,th2 = cv2.threshold(blur2,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
blur3    = cv2.GaussianBlur(th2,(3,3),0)
ret3,th3 = cv2.threshold(blur3,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

# Find connected components and extract the mean height and width
output = cv2.connectedComponentsWithStats(255-th3, 6, cv2.CV_8U)
mean_h = np.mean(output[2][:,cv2.CC_STAT_HEIGHT])
mean_w = np.mean(output[2][:,cv2.CC_STAT_WIDTH])

# Find empty rows, defined as having less than mean_h/2 pixels
empty_rows = []
for i in range(th3.shape[0]):
  if np.sum(255-th3[i,:]) < mean_h/2.0:
    empty_rows.append(i)           

# Group rows by labels
d = np.ediff1d(empty_rows, to_begin=1)

good_rows   = []
good_labels = []
label       = 0

# 1: assign labels to each row
# based on whether they are following each other or not (i.e. diff >1)
for i in range(1,len(empty_rows)-1):
  if d[i+1] == 1:
    good_labels.append(label)
    good_rows.append(empty_rows[i])

  elif d[i] > 1 and d[i+1] > 1:
    label = good_labels[len(good_labels)-1] + 1

# 2: find the mean row value associated with each label, and color that line in green in the original image
for i in range(label):
  frow = np.mean(np.asarray(good_rows)[np.where(np.asarray(good_labels) == i)])
  img[int(frow),:,1] = 255 

# Display the image with the green rows
cv2.imshow('test',img)
cv2.waitKey(0)

【讨论】:

    猜你喜欢
    • 2012-03-13
    • 2011-07-16
    • 2016-08-09
    • 2013-12-25
    • 2014-04-25
    • 2015-09-07
    • 2021-11-28
    • 1970-01-01
    相关资源
    最近更新 更多