Программа с глазами Филипп Коряка Хакер, номер #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) } } } Разделяем изображение на цифры Разделение на цифры состоит из двух этапов. Первое что нужно сделать - это разбить изображение на три части, в каждой из которых будет ровно по одной цифре. Для этого поочередно просмотрим изображение столбцами. При этом мы будем считать столбец пустым, если он полностью состоит из нулей. Далее необходимо найти в изображении участки, где подряд идет три и более пустых столбцов. Очевидно, что это будут разделители между цифрами. По ним и нужно дробить изображение на четыре неравные части. |