Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #73, ЯНВАРЬ 2005 г.

Программа с глазами

Филипп Коряка

Хакер, номер #073, стр. 073-120-2


1. Одиночно стоящие точки.

2. Пара точек не соприкасающаяся с другими точками.

3. Точки "прилипшие" к цифрам.

4. Точки, нанесенные на цифры.

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

for ($j=0; $j<20; $j++){

for ($i=0; $i<47; $i++){

if ( ($img-> getPixel($i-1, $j) == 0 && $img-> getPixel($i+1, $j) == 0) ||

($img-> getPixel($i+1, $j) != 0 && $img-> getPixel($i-1, $j) == 0 &&

$img-> getPixel($i-1, $j+1) == 0 && $img-> getPixel($i-1, $j-1) == 0 &&

$img-> getPixel($i, $j+1) == 0 && $img-> getPixel($i, $j-1) == 0) ||

($img-> getPixel($i-1, $j) != 0 && $img-> getPixel($i+1, $j) == 0 &&

$img-> getPixel($i+1, $j+1) == 0 && $img-> getPixel($i+1, $j-1) == 0 &&

$img-> getPixel($i, $j+1) == 0 && $img-> getPixel($i, $j-1) == 0)

){

$img-> setPixel($i, $j, 0)

}

}

}

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

Теперь изображение вполне пригодно к прочтению. Количество искажающей информации в нем минимально. Однако в нем присутствует избыточная информация. В частности от каждой цифры нам нужен только силуэт. И чем тоньше он будет, тем проще будет с ним работать. В идеале это, конечно, должен быть силуэт шириной в один пиксел, но на практике не всегда удается достичь этого и потому силуэт шириной в два пиксела считается вполне приемлемым. На картинке 1 видно, что каждая цифра имеет силуэт из пикселов с цветом 1 и 2 облепленный символами с цветами 3, 4, 5 и т.д. С ними-то нам и предстоит бороться. Алгоритм борьбы достаточно простой: нужно еще раз пройтись по всем пикселам изображения и закрасить все пикселы, цвет которых не равен 1 или 2 цветом фона, а для дальнейшего удобства распознавания заменить цвет 2 на 1 тем самым, сделав наше изображение двухцветным без каких либо оттенков.

for ($j=0; $j<20; $j++){

for ($i=0; $i<47; $i++){

if ($img-> getPixel($i, $j) > 2){

$img-> setPixel($i, $j, 0)

}

if ($img-> getPixel($i, $j) == 2){

$img-> setPixel($i, $j, 1)

}

}

}

Разделяем изображение на цифры

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

Назад на стр. 073-120-1  Содержание  Вперед на стр. 073-120-3