Pull to refresh

PHP и чтение текста на изображении: начало

Вероятно многим приходилось сталкиваться с расшифровкой текста на изображениях, по совершенно разным причинам.
Совсем недавно мне понадобился такой алгоритм, которым я буду рад с вами поделиться. Данный пример не претендует на универсальность и требует доработки, но в частном случае он выполняет свою задачу.


1. Работа с исходным изображением.

У нас есть изображения фиксированного размера, но с разным текстом.
В моем случае такие:
image
image

1.1 Упрощаем изображения

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

<?php
public function prepareImage($contrast = -1500) {
	imagefilter($this->im, IMG_FILTER_GRAYSCALE);
	imagefilter($this->im, IMG_FILTER_CONTRAST,$contrast);
	$output = imagecreatetruecolor(imagesx($this->im)-2, imagesy($this->im)-2);
	imagecopy($output, $this->im, 0, 0, 1, 1, imagesx($this->im), imagesy($this->im));
	for($i=1;$i<imagesy($output);$i++){
		for($j=1;$j<imagesx($output);$j++){
			$rgb = imagecolorat($output,$j,$i);
			imagecolorset($output, $rgb, 255, 255, 255);
		}
	}
	imagefilter($output, IMG_FILTER_NEGATE);
	return $this->im = $output;
}

После этого я получаю инвертированное двухцветное черно-белое изображение.

1.2 Находим символы на изображении

В моем случае задача простая: все символы находятся всегда на одних и тех же местах. Поэтому немного хардкода:

<?php
public function splitImage() {
	$width=15;
	$left=8;
	for($sample=1;$sample<7;$sample++){
		$this->splited[$sample] = imagecreatetruecolor($width, imagesy($this->im)-1);
		imagecopy($this->splited[$sample], $this->im, 0, 0, $left, 1, $width, imagesy($this->im)-1);
		$left=$left+$width;
                 //.......
	}
}


2. Преобразуем символы в массив


<?php
$this->arrays[$sample-1] = array();
for($sh=1;$sh<imagesy($this->splited[$sample]);$sh++){
	for($sw=1;$sw<imagesx($this->splited[$sample]);$sw++){
		$rgb = imagecolorat($this->splited[$sample],$sw,$sh);
		if($rgb==0){
			array_push($this->arrays[$sample-1], 0);
		}else {
			array_push($this->arrays[$sample-1], 1);
		}
	}
}

На выходе получаем нечто такое:
01111111110000
00000100000000
00000100000000
00000100000000
00000100000000
00000100000000
00000100000000
00000100000000
00000100000000
00000100000000
00000100000000
00000100000000
00000000000000

3. Распознание символа в массиве

Используем простую однослойную нейронную сеть. Для начала необходимо ее научить.

<?php
public function teach()
    {
        $filename = 'neuroData.txt';
        $neural = $this->_loadNeuro($filename);
        $last = 0;
        foreach ($this->arrays as $arr) {
            for ($l = 0; $l < count($neural->letters); $l++) {
                //for($iteration; $iteration < 10; $iteration++) //для ускорения обучения
                $neural->teach($arr, ($neural->letters[$l] == $this->text[$last] ? 1 : -1), $l);
            }
            $last++;
        }
        $neural->weight_save($filename);
    }


Для ускорения, можно проводить обучение в несколько итераций.
На самое главное это «покормить» нашу нейросеть всеми символами.
Что бы спросить сеть используем метод:

<?php
    public function ask()
    {
        $filename = 'neuroData.txt';
        $neural = $this->_loadNeuro($filename);
        $s = '';
        foreach ($this->arrays as $arr) {
            for ($l = 0; $l < count($neural->letters); $l++) {
                $s .= ($neural->ask($arr, $l) == 1 ? $neural->letters[$l] : '');
            }
        }
        $this->text = $s;
        return $this->text;
    }


Пример работы алгоритма:


PHP исходники

Для общего развития:
Нейронные сети: Лекция 1
Нейронные сети: Лекция 2

Пригодится для прокачки:
Контурный анализ
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.