Оптическое распознавание Брайля с использованием OpenCV - PullRequest
0 голосов
/ 04 июня 2018

Я на самом деле пытаюсь распознать символы Брайля в документе.Я намерен преобразовать документ Брайля в обычный текст.Я использую OpenCV с Java для обработки изображений.

Сначала я импортировал изображение документа Брайля:

Image of the original Braille document

Затем я выполнил некоторую обработку изображения, чтобы оцифровать исходное изображение.Я прочитал, что важными шагами являются:

  • Преобразование изображения в уровни серого
  • Уменьшение шума
  • Повышение контрастности края
  • Binarizeизображение

Вот код, который я использовал:

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 );

}

Я получил следующий результат для этого шага:

Image Binarization

По моему мнению, мы можем улучшить качество этого изображения для улучшения результатов, но я не разбираюсь в различных методах обработки изображений.Могу ли я улучшить качество своих фильтров?

После этого я хотел бы выполнить сегментацию изображения для обнаружения различных символов этого документа.Я хотел бы разделить различные символы документа, чтобы преобразовать их в текст.

Например, я нарисовал разделительные линии документа вручную:

Separation lines

Но я не нашел решения для этого шага.Есть ли возможность сделать то же самое с OpenCV?

1 Ответ

0 голосов
/ 06 июня 2018

Вот небольшой скрипт, который находит строки на вашем изображении.Это на 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)
...