Модераторы: Aliance, skyboy, MoLeX, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Распознание цифр на изображении, Практикум 
:(
    Опции темы
CyClon
  Дата 26.9.2006, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



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

В общем, в качестве картинки берем: http://proteam.com.ru/image.jpg

Цель: получить переменную:

Код
$code = 605869;


Итак, меня интересует на данный момент несколько вопросов:

1. Теория распознания. Что нужно сделать сначала, что потом и т.д. В общем как распознать картинку за меньшее время и меньшей затратой ресурсов. И возможно ли это средствами PHP (Я считаю, да smile)?
2. Какие функции нужно использовать при распознани, т.к. чтобы я мог конекретно прочитать манул по определенным функциям. Вообще меня интересует функцию обрезания изображения, чтобы сразу после получения изображения обрежат его, т.к. цифры на картинке появляются в одном и том же месте и ежду ними и краем картинки немаленькое количество пустого пространства, которое скрипт анализирует и тратит на него время и системные ресурсы. Также функция обрежания нужно для сравнивания с эталонами каждой цифры, т.к. полностью картинку сравнить неудастся в связи с большым кол-во эталоном (999999 штук).

Вот код, который я уже написал - сравнение двух картинок и определение процента совпадения:

Код
<?php

function get_colors($location) {
    $image = imagecreatefromjpeg($location);
    $size = getimagesize($location);
    for ($w = 1; $w < $size[0]; $w++) {
        for ($h = 1; $h < $size[1]; $h++) {
            $colors[$w."x".$h] = imagecolorat($image, $w, $h);
        }
    }
    imagedestroy($image);
    return $colors;
}

function check_images($colors1, $colors2) {
    $ok = 0;
    $pixels1 = sizeof($colors1);
    $pixels2 = sizeof($colors2);
    if ($pixels1 != $pixels2) {
        return false;
    }
    foreach ($colors1 as $key => $value) {
        if (isset($colors2[$key]) && $colors2[$key] == $value) {
            $ok++;
        }
    }
    $new_percent = ($ok / $pixels1) * 100;
    return round($new_percent, 2);
}

$image1 = get_colors("image1.jpg");
$image2 = get_colors("image2.jpg");

$result = check_images($image1, $image2);

if ($result) {
    echo ($result > 70) ? "Картинки одинаковые" : "Картинки разные";
    echo "<br />\n";
    echo "Процент совпадения: ".$result."%";
}

?>


Это сообщение отредактировал(а) CyClon - 26.9.2006, 11:18


--------------------
user posted image
PM   Вверх
CyClon
Дата 26.9.2006, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



В общем, для начала нужно получить из http://proteam.com.ru/image.jpg - http://proteam.com.ru/edit.jpg. Как это сделать средствами PHP, то есть обрезать?

И еще вопрос: функция imagecolorat возвращает так называемые "индексы цветов". Что они обозначают, как из индекса получить RGB цвет? То есть я хочу произвети проверку не цвет, и светлые цвета откинуть.

Добавлено @ 11:48 
P.S. Обрезав картинку мы экономим ~65% времени и ресусрсов, ну учитывая время и ресурсы на саму обрезку.

Кол-во пикселей оригинальной картинки = 210 * 65 = 13650
Кол-во пикселей обрезаной картинки = 147 * 32 = 4704
Экономия = 100 - (4704 / 13650) * 100 ~ 66%

Так что варианты "Анализируй полностью, нах резать" не предлагать smile 


--------------------
user posted image
PM   Вверх
Garret
Дата 26.9.2006, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 16.9.2006
Где: Киев

Репутация: нет
Всего: 2



Эх спаммер...

Попробуй взять с captcha.ru
PM MAIL WWW ICQ   Вверх
MuToGeN
Дата 26.9.2006, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лесник
****


Профиль
Группа: Модератор
Сообщений: 4379
Регистрация: 15.8.2002
Где: Москва

Репутация: 2
Всего: 32



user posted image
Слабо? =)

А вообще, если нужен универсальныый вариант, то копать надо в сторону нейросетей. PHP в этом плане мало чем поможет.


--------------------
Three pings for the token rings,
Five pings for the UNIX machines,
Hundred pings for the broken links,
One special ping to check them all
Through Simple Network Management Protocol!
PM MAIL ICQ   Вверх
CyClon
Дата 26.9.2006, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



Делал бы ради спама, делал бы универсально. Просто хочется написать скрипт, который сможет распознать цифры, попрактиковаться с GD2 и вообще пару раз испытать smile))

Цитата
http://www.ljplus.ru/img/m/u/mutogen/spamcontrol.png


Жестко. Я в 10 классе, решать такое не умею smile


--------------------
user posted image
PM   Вверх
Garret
Дата 26.9.2006, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 16.9.2006
Где: Киев

Репутация: нет
Всего: 2



Я закончил курс высшей математики и тоже не решу smile 
PM MAIL WWW ICQ   Вверх
CyClon
Дата 26.9.2006, 12:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



Естественный отбор ;)

Кто что может сказать по теме. Смотрел http://captcha.ru/ - весело. Только исходников там нет, а работает вроде быстро smile


--------------------
user posted image
PM   Вверх
Garret
Дата 26.9.2006, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 16.9.2006
Где: Киев

Репутация: нет
Всего: 2



CyClon, исходники там есть, посмотри внимательнее.
PM MAIL WWW ICQ   Вверх
CyClon
Дата 26.9.2006, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



Процесс немного продвигается - обрезал изображение с помощью функции imagecopy до нужных размеров. Теперь интересует, как повысить контраст и определить цвет пикселя в RGB, а не индексом.

Хочу затереть все светлые пиксели. чтобы осталось только цифры. Потом нарисовать эталонов и вуоля.

Добавлено @ 12:54 
Да нет, там вроде только исходники защиты, то есть чтобы заменить этот код на более совершенный. А исходников распознания не видел. Сейчас еще посмотрю.


--------------------
user posted image
PM   Вверх
MuToGeN
Дата 26.9.2006, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Лесник
****


Профиль
Группа: Модератор
Сообщений: 4379
Регистрация: 15.8.2002
Где: Москва

Репутация: 2
Всего: 32



Цитата(CyClon @  26.9.2006,  12:53 Найти цитируемый пост)
определить цвет пикселя в RGB

imagecolorat() + GD 2.0 + картинка, созданная при помощи imagecreatetruecolor()

Цитата(CyClon @  26.9.2006,  12:53 Найти цитируемый пост)
А исходников распознания не видел.

Их там и нет.


--------------------
Three pings for the token rings,
Five pings for the UNIX machines,
Hundred pings for the broken links,
One special ping to check them all
Through Simple Network Management Protocol!
PM MAIL ICQ   Вверх
Mal Hack
Дата 26.9.2006, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 1
Всего: 261



Ты реаьлно думаешь реализовать алгоритм FineReader'a? Слишком высокие амбиции...
Читай про нейросети, как сказал Мутоген, а лучше займись чем-ть реально реализуемым.
PM ICQ   Вверх
CyClon
Дата 26.9.2006, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



Ребят вы или не читаете или хз что... Я же сказал, пишу этот скрипт только ради практики работы с GD2, чтобы потом, при создании графического счетчика я не лез в мануал за справкой по imagestring. Также просто хочется написать хитрый, но не муторный скрипт, которые на интернет-свалках не валяются, как гостевые книги и голосовалки. Голосование или ту же гостевую книгу писать - не для меня. Единстевнное, над чем там нужно подумать - организация БД / каталогов / работы скрипта. А сам скрипт - потсоянные запросы в БД, обрабока и вывод.

А по делу - вроде бы все сделал, все работает. Единственные проблемы - это чудесное превращение указателя (resouce) и число (int) и вылет ошибки и то, что я не знаю, как убрать фон. Мне нужно как то убрать все кроме более-менее черного цвета, т.к. сравнивает обсолютно не правильно, ведь фон содердит основное кол-во пикселей.

Подскажите как затереть задний фон или сравнивать только темные пиксели. С ошибкой попробую пока сам разобарться.

Это сообщение отредактировал(а) CyClon - 26.9.2006, 18:05


--------------------
user posted image
PM   Вверх
CyClon
Дата 26.9.2006, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



Так кто нибудь может рассказать, как убрать фон и оставить только фицры или сравнивать только темные пиксели? Кстати, на счет createimagetruecolor, когда его создаю, то получается черный квадрат, а с createimage норм все.

Это сообщение отредактировал(а) CyClon - 26.9.2006, 19:07


--------------------
user posted image
PM   Вверх
CyClon
Дата 5.11.2006, 10:07 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



Значит, вернулся к этой теме smile)) В общем, вчера снова начал разбираться что к чему, немного подредактировал код... Что получилось - распознаются цифры, на фоне которых нет шумов. Если шумы есть - цифры распознаются не правильно. Помогите, как исправить, как игнорировать шумы. Вроде бы поставил фильтр по индексу ниже 1000, но похоже мало чем помогает. Подтолкните хотя бы идею...

Код
<?php

ini_set('display_errors', 1);
error_reporting(E_ALL);

function get_colors($image) {
    for ($w = 1; $w < 12; $w++) {
        for ($h = 1; $h < 32; $h++) {
            $rgb = imagecolorat($image, $w, $h);
         $colors[$w . 'x' . $h] = $rgb;
        }
    }
    return $colors;
}

function check_images($colors1, $colors2) {
    $ok = 0;
    foreach ($colors1 as $key => $value) {
     if ($value < 1000) {
            $color1 = $value;
            $color2 = $colors2[$key];
            $min = $color1 - 512;
            $max = $color1 + 512;
            if (($color2 > $min) && ($color2 < $max)) {
                $ok++;
            }
        }
    }
    return $ok;
}

function create_etalon($number) {
    $temp = imagecreate(8, 10);
    $white = imagecolorallocate($temp, 255, 255, 255);
    $black = imagecolorallocate($temp, 0, 0, 0);
    imagestring ($temp, 5, 0, -3, $number, $black);
    $image = imagecreate(12, 32);
    imagecopyresized($image, $temp, 0, 0, 0, 0, 12, 32, 8, 10);
    return $image;
}

$original = imagecreatefromjpeg('image.jpg');

for ($i = 0; $i < 6; $i++) {
    $width = 27 + ($i * 27);
    $number = imagecreatetruecolor(12, 32);
    imagecopy($number, $original, 0, 0, $width, 16, 12, 32);
    for ($c = 0; $c < 10; $c++) {
        imagejpeg(create_etalon($c), 'temp.jpg');
        $etalon = imagecreatefromjpeg('temp.jpg');
        unlink('temp.jpg');
        $colors1 = get_colors($number);
        $colors2 = get_colors($etalon);
        $result[$c] = check_images($colors1, $colors2);
    }
    $code = "";
    $max = max($result);
    foreach ($result as $key => $value) {
        if ($value == $max) {
            echo $key;
         break;
        }
    }
    unset($result);
}

?>



--------------------
user posted image
PM   Вверх
ВасяТриллер
Дата 6.11.2006, 22:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 2.9.2005

Репутация: нет
Всего: 1



CyClon, http://php.russofile.ru/ru/translate/images/img_fun/
Играйся, может, что и выйдет smile
PM MAIL WWW ICQ AOL YIM   Вверх
CyClon
Дата 7.11.2006, 14:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



Я это уже как-то читал, токо мало чем помогло smile)) По теории я вроде делаю все правильно, но я не знаю, или погрешность какая-то существует или еще что. В общем цвета разные. Лимит цвета до 1000 индексов, а пофиг фон сравнивается.


--------------------
user posted image
PM   Вверх
capitan
Дата 26.1.2007, 23:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 27.2.2005
Где: Москва

Репутация: нет
Всего: 13



Да, написать распознавалку captcha не так просто, но возможно. Я например ради интереса написал распознавалку для captcha  с почтового сервера http://www.nm.ru/. Пример можно глянуть на http://capitanstudio.net.ru/captcha_nm/index.php   Процент распознавания 100%. Картинка лёгкая. Белыми цифрами по синему фону. Вот сам код:
Код

<?
$filename = 'http://www.nm.ru/cgi-bin/defence.cgi';
//$filename = '6.gif';
$width1 = 10;
$height1 = 10;
$per1 = 5;
$per2 = 5;

// Get new sizes
list($width, $height) = getimagesize($filename);
$newwidth = $width -$width1;
$newheight = $height -$height1;
$width = $width-$width1;
$height = $height -$height1;

// Load
$thumb = imagecreatetruecolor($newwidth, $newheight);
$source = imagecreatefromgif($filename);

// Resize
imagecopyresized($thumb, $source, 0, 0, $per1, $per2, $newwidth, $newheight, $width, $height);

// Output
//imagegif($thumb);

for ($i = 0; $i < $newwidth; $i++){
    
        for ($j = 0; $j < $newheight; $j++){
        $se[$i][$j] = (imagecolorat ($thumb, $i, $j)); 
            
        }            
    }
imagegif($thumb, 'test.gif'); 
imagedestroy($thumb);

echo '<img src="test.gif" /><br>';
$captcha_code ='';
for ($ish = 1; $ish <= 9; $ish++){
$img = imageCreateTrueColor(75, 20);
$background_color = imagecolorallocate ($img, 255, 255, 255); //white background
$black = imageColorAllocate($img, 0, 0, 255);    

//print_r ($se);
$sum_let =0;
$nach ='';
$captcha =0;
$array_col ='';

if($ish == '1'){$ish1=0;$ish2=10;}
if($ish == '2'){$ish1=10;$ish2=20;}
if($ish == '3'){$ish1=20;$ish2=25;}
if($ish == '4'){$ish1=25;$ish2=35;}
if($ish == '5'){$ish1=35;$ish2=43;}
if($ish == '6'){$ish1=43;$ish2=50;}
if($ish == '7'){$ish1=50;$ish2=56;}
if($ish == '8'){$ish1=56;$ish2=65;}
if($ish == '9'){$ish1=65;$ish2=73;}

for ($w = $ish1; $w < $ish2; $w++){
$ws = count($se[$w]);
for ($w1 = 0; $w1 < $ws; $w1++){ 

if($se[$w][$w1]=='16777215' AND $nach==''){$nach=$w1;}
if($se[$w][$w1]=='16777215'){
$array_col[] = '16777215'; 
$w3= $w1- $nach;
$captcha=$captcha+$w3;
imagesetpixel($img, $w, $w1, $se[$w][$w1]);    
}

}    
}

//header("Content-Type: image/png");
//imagepng($img);
imagepng($img, 'test.png'); 
imagedestroy($img);

if($captcha=='21' AND array_sum($array_col)=='234881010'){$captcha_code .= '0';}
if($captcha=='31' AND array_sum($array_col)=='234881010'){$captcha_code .= '1';}
if($captcha=='42' AND array_sum($array_col)=='251658225'){$captcha_code .= '2';}
if($captcha=='37' AND array_sum($array_col)=='251658225'){$captcha_code .= '3';}
if($captcha=='10' AND array_sum($array_col)=='268435440'){$captcha_code .= '4';}
if($captcha=='57' AND array_sum($array_col)=='318767085'){$captcha_code .= '5';}
if($captcha=='30' AND array_sum($array_col)=='301989870'){$captcha_code .= '6';}
if($captcha=='28' AND array_sum($array_col)=='201326580'){$captcha_code .= '7';}
if($captcha=='47' AND array_sum($array_col)=='318767085'){$captcha_code .= '8';}
if($captcha=='42' AND array_sum($array_col)=='301989870'){$captcha_code .= '9';}
}

echo '<b>Секретный код:</b> '.$captcha_code;
?>


Написал за 20 минут.  Лень было делать красивый код, думаю и так всё понятно. 
Обрезаем картинку, делаем трассировку по цифрам и ищем белые пиксели, дальше считаем их и точки по оси Y. Сравниваем с эталоном и получаем ответ.
PM MAIL WWW ICQ   Вверх
CyClon
Дата 22.2.2007, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 3.12.2005

Репутация: нет
Всего: 4



Спс за код, посмотрю, может что хорошее вычерпну smile))


--------------------
user posted image
PM   Вверх
-SMall-
Дата 8.6.2007, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 29.5.2007

Репутация: нет
Всего: нет



Есть ли шансы распознать вот эти варианты?

1. user posted image
2. user posted image
PM MAIL   Вверх
Golda
Дата 9.6.2007, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 26.3.2007
Где: Ариель, Израиль

Репутация: нет
Всего: 42



Шансы всегда есть   smile

Основная слабость первой captcha: шумовые линии значительно тоньше линий цифр. А значит, легко убираются операциями математической морфологии (сжатие/расширение). Отсутствие пересечений и разные цвета позволяют легко отделить буквы друг от друга.

Во второй сначала убирается чересполосица. Сравниваем количество черных и белых пикселей на вертикали (для надежности можно работать с площадью узкой полоски шириной чуть больше ширины буквы) и если количество черного превосходит - инвертируем цвета. А можно и просто вычислить шаг полос. Он же не меняется, как и их ширина. Беспорядочные точки убираются сжатием/расширением. Буквы не пересекаются и не деформированы, что тоже не добавляет стойкости captcha. Возможно, проблемой являются жирные полосы, которые могут пересекать буквы. Чтобы сказать, насколько они являются проблемой, нужно увидеть их закономерности (количество/длина/расположение/пересечение с буквами и друг с другом) на большем количестве примеров. 

Но это все, если кто-то займется именно Вашей captcha. Если Ваш ресурс не представляет какой-то исключительной ценности, вероятность того, что ею займутся спамеры пропорциональна ее распространенности в сети.    smile 

Это сообщение отредактировал(а) Golda - 9.6.2007, 22:18


--------------------
"For every problem, there exists a simple and elegant solution which is absolutely wrong." -- J. Wagoner, U.C.B. Mathematics
PM MAIL   Вверх
XseZ
Дата 30.7.2007, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 30.7.2007

Репутация: нет
Всего: нет



может кто поможет с кодом   smile 
user posted image
PM MAIL   Вверх
Golda
Дата 30.7.2007, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 460
Регистрация: 26.3.2007
Где: Ариель, Израиль

Репутация: нет
Всего: 42



Э нет, так не пойдет. На этом форуме помогают понять, как построить защиту, а не как взламывать чужие системы


--------------------
"For every problem, there exists a simple and elegant solution which is absolutely wrong." -- J. Wagoner, U.C.B. Mathematics
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Графика | Следующая тема »


 




[ Время генерации скрипта: 0.0651 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.