Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > PHP
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.04.2012, 23:22   #1
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
Восклицание Оптимизировать, подправить OCR

Доброго времени суто форумчанам.
Пишу OCR, так вот как бы оптимизировать код, чтобы выполнялся минимальное время? Что тут можно выбросить?

PHP код:
<?php 
error_reporting
(E_ERROR E_WARNING E_PARSE);

Class 
Number
{
    public 
$W;
    public 
$G = array();
    public 
$B = array();
    
     public function 
ask($vector
     { 
         
$this->weight_load('numbers.dat');
         
$this->Parse("0"$vector);
         
$this->Parse("1"$vector);
         
$this->Parse(2$vector);
         
$this->Parse(3$vector);
         
$this->Parse(4$vector);
         
$this->Parse(5$vector);
         
$this->Parse(6$vector);
         
$this->Parse(7$vector);
         
$this->Parse(8$vector);
         
$this->Parse(9$vector);
         
         foreach(
$this->as $k=>$bad){
             
//echo $k.": = ".$bad/100;
            // echo "\n";
             
if($bad/100 >=&& $bad/100 <= 0.20){
                 
//echo $k;
                 
$result $k;
                 break;
             }
         }
        
// echo"\n";
         
return $result;
         
     }

        public function 
weight_load($filename
        { 
            
$this->unserialize(file_get_contents($filename)); 

        }
        
        
/** 
         * Сохраняем в файл 
         * Если файл есть - перезапишет 
         * 
         * @param string $filename 
         */ 
        
public function weight_save($filename
        { 
                
//$serialize = array($n => $vector);
                
$serialize serialize($this->W); 
                
fwrite(fopen($filename,"w"), $serialize); 
        } 
        
        public function 
Parse($n$vector){
            
$this->W[$n];
            
            
$this->G[$n] = 0;
            
            
$this->B[$n] = 0;
            
            foreach(
$vector as $k=>$value){
                if(
$this->W[$n][$k] == $value){$this->G[$n]++;}else{$this->B[$n]++;}
            }
        }
        
        public function 
teach($vector$n
        { 
            
$this->W[$n] = $vector;
            
//weight_save('numbers.dat', $vector, $n);
        
}
        
        public function 
HorisontalCut($file$Hystogram$w_n$h_n){
    
                
$captcha imagecreatefrompng($file); 
             
//echo"\n";
             
            
list($width$height) = getimagesize($file);

            
$i 1;
            foreach(
$Hystogram as $key=>$value){
                 
//width:30px - height:46px
                 
$im imagecreatetruecolor($w_n+2$h_n); 
                 
                 
imagecopy($im$captcha00$value0$w_n+2$h_n); 
                  
                 
imagepng($im'tmp/'.$i."_".$file);
                 
imagedestroy($im);
                 
                 
$i++;
             }
        }

Последний раз редактировалось dem66; 12.04.2012 в 23:38.
dem66 вне форума Ответить с цитированием
Старый 12.04.2012, 23:23   #2
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
По умолчанию

Продолжение кода:

PHP код:
public function Convert($file$type=NULL){
            
            
$image=imagecreatefrompng($file);
            
            list(
$width$height) = getimagesize($file);
            
$arr = array();
            
            for (
$h=0;$h<$height;$h++)
            {
                for (
$w=0;$w<$width;$w++)
                {
                    
                    
$color_indeximagecolorat($image$w$h);

                    
$color_tran imagecolorsforindex($image$color_index);
                    
                    
$index $color_tran['red'];
                    
                    if(
$index==0){
                        
$arr[] = 1;
                    }else{
                        
$arr[] = 0;
                    }
                }
            }
            return 
$arr;
        }
        
        public function 
CpImg($file){
             
$captcha imagecreatefrompng($file); 

             list(
$width$height) = getimagesize($file);

                 
$im imagecreatetruecolor($width$height); 
                 
                 
imagecopy($im$captcha0000$width$height); 
                  
                 
imagepng($im$file);
                 
imagedestroy($im);

            }
        
        public function 
clear($file){
    
            
$image imagecreatefrompng($file);
            
            list(
$width$height) = getimagesize($file);
                
            
$arr = array();        
            
            for (
$w=0;$w<$width;$w++)
                {
                for (
$h=0;$h<$height;$h++)
                    {
                    
                    
$color_indeximagecolorat($image$w$h);

                    
$color_tran imagecolorsforindex($image$color_index);
                    
                
                    
$top_index 255;
                    
$right_index 255;
                    
$bottom_index 255;
                    
$left_index 255;
                    
                    if(
$color_index == 0){
                        
                        if(
$h!=0){
                            
$top_index imagecolorat($image$w$h-1);
                        
                            
$color_tran imagecolorsforindex($image$top_index);
                            
//переводим индекс в человеческий ргб, функция вернет ассоциативный массив
                            
$top_index $color_tran['red'];
                        }
                        
                        if(
$w<$width){
                            
$right_index imagecolorat($image$w+1$h);
                            
                            
$color_tran imagecolorsforindex($image$right_index);
                            
//переводим индекс в человеческий ргб, функция вернет ассоциативный массив
                            
$right_index $color_tran['red'];
                            }
                        if(
$h<$height){
                            
$bottom_index imagecolorat($image$w$h+1);
                            
                            
$color_tran imagecolorsforindex($image$bottom_index);
                            
//переводим индекс в человеческий ргб, функция вернет ассоциативный массив
                            
$bottom_index $color_tran['red'];
                        }
                        if(
$w!=0){
                            
$left_index imagecolorat($image$w-1$h);
                            
                            
$color_tran imagecolorsforindex($image$left_index);
                            
//переводим индекс в человеческий ргб, функция вернет ассоциативный массив
                            
$left_index $color_tran['red'];
                        }

                    }
                    
                    
$sum $top_index+$right_index+$bottom_index+$left_index;
                    
//1=16777215
                    //0-black
                    //255-white
                    

                    
if($sum<=510){$r="0";$g="0";$b="0";}else{$r="255";$g="255";$b="255";}

                    
$arr[$w][$h] = $r;
                }
            }

            return 
$arr;
        }
        
        public function 
Hystogram($array){
                
            
$arr = array();
            

            foreach(
$array as $k=>$value){
                foreach(
$value as $key=>$val){
                    if(
$val==0){$arr[$k][$key] = 1;}
                }
                    
            }


            
$number = array();
            
$s 0;
            
$b 0;
            for(
$i=0$i<count($array); $i++){
                
                if(isset(
$arr[$i])){
                    
$s 1;
                    if(
$b==0)$number[] = $i;$b 1;
                }
                if(!isset(
$arr[$i]) && $s==1){
                    
$number[] = $i;
                }

            }

            foreach(
$number as $k=>$n){
                if(
$number[$k]-== $number[$k-1] && $number[$k]+==$number[$k+1]){
                    unset(
$number[$k-1]);unset($number[$k+1]);
                }elseif(
$number[$k]-== $number[$k-1]){
                    unset(
$number[$k-1]);
                }elseif(
$number[$k]+== $number[$k+1]){
                    unset(
$number[$k+1]);
                }
                
            }
            unset(
$number[count($number)]);
            
            if(
count($number)>=6){
                foreach(
$number as $k=>$v){
                    if(
$k>=6)unset($number[$k]);
                }
            }

            return 
$number;
            
        } 
dem66 вне форума Ответить с цитированием
Старый 12.04.2012, 23:28   #3
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
По умолчанию

Последняя часть:
PHP код:
function VertycalCut($array$file){

            
$arr = array();

            foreach(
$array as $k=>$value){
                foreach(
$value as $key=>$val){
                    if(
$val==0){$arr[$key][$k] = 1;}
                }            
            }
        
            
$number = array();
            
$s 0;
            
$b 0;
            for(
$i=0$i<count($array); $i++){    
                if(isset(
$arr[$i])){
                    
$s 1;
                    if(
$b==0)$number[] = $i;$b 1;
                }
                if(!isset(
$arr[$i]) && $s==1){
                    
$number[] = $i;
                }
            }
            

            foreach(
$number as $k=>$n){
                if(
$number[$k]-== $number[$k-1] && $number[$k]+==$number[$k+1]){
                    unset(
$number[$k-1]);unset($number[$k+1]);
                }elseif(
$number[$k]-== $number[$k-1]){
                    unset(
$number[$k-1]);
                }elseif(
$number[$k]+== $number[$k+1]){
                    unset(
$number[$k+1]);
                }

            }
            
            unset(
$number[count($number)]);
            
            if(
count($number)>=2){
                foreach(
$number as $k=>$v){
                    if(
$k>=2)unset($number[$k]);
                }
            }
            
            
$width 50;
                
            
$height 20;
            
            
$im imagecreatetruecolor(5010);
                
imagefill($im000xFFFFFF);
                
                
$i 0;
                foreach(
$array as $w=>$width){
                    
$j 0;    
                    foreach(
$width as $h=>$value){
                        
                        if(
$h >= $number[0] && $h <= $number[1]){
                            if(
$value==0){$col=0;}else{$col=16777215;}    
                            
imagesetpixel($im $i $j $col);
                            
$j++;
                        }
                        
                    }
                    
$i++;
                }
                
imagepng($im$file);
                
imagedestroy($im);
            
        }
        
        public function 
Decode($file){
            
$this->CpImg($file);

            
$vector $this->Clear($file);

            
$this->VertycalCut($vector$file);

            
$Hystogram $this->Hystogram($vector);

            
$this->HorisontalCut($file$Hystogram,  710);

            
$number NULL;
            for(
$i=1;$i<5;$i++){
                
$vector $this->Convert('tmp/'.$i.'_'.$file);

                
$number .= $this->ask($vector);
            }
            return 
$number;
        }
}

$test = new Number;

$file 'runneri.png';

echo 
$test->Decode($file);

echo
"\n";
/*
for($i=0;$i<10;$i++){
    $vector = $test->Convert('tmp/'.$i.'.png');

    $test->teach($vector, $i);
}

$test->weight_save('numbers.dat');

*/ 
Пытаюсь рохгадать капчу.

И вот что из этого получается после очистки:

Вот что получается после розделения на цифры:
Первая:
Вторая:
Третья:
И четвертая сюда уже не помещается.

Работает следующим образом: Почемуто изображения этой капчи с первого раза нормально не очищаются, они получаются все черные, поэтому был создан метод который копирует содержимое картинки в новую и потом уже с ней ведется вся робота.
Удаление шума происходит анализом окружения каждого пикселя, если вокруг ниже нормы то закрашиваем в баелый. Очищает довольно эфективно.
Потом ищем начало цифр на изображении и обрезаем его (сначала по горизонтали отризаем всерху и снизу), потом ищем начало цифр и обрезем по вертикали, по полученым кординатам, размер цирф неизменный.
Ну и дальше создаём маску изображения и проверяем с тем что есть в базе. Выбираем на наименьшим количеством ошибок. Сейчас до 20%(тоесть картинка с цифрой может отличатся на 20 пикселей).

Большую часть операций проводим не с самим изображением а с массивом, зделано для ускорения работы, и меньшей нагрузки.
Изображения
Тип файла: png runneri4 (копия).png (192 байт, 80 просмотров)
Тип файла: png runneri4.png (211 байт, 83 просмотров)
Тип файла: png 1_runneri4.png (117 байт, 103 просмотров)
Тип файла: png 2_runneri4.png (122 байт, 80 просмотров)
Тип файла: png 3_runneri4.png (123 байт, 80 просмотров)

Последний раз редактировалось dem66; 12.04.2012 в 23:38.
dem66 вне форума Ответить с цитированием
Старый 13.04.2012, 13:28   #4
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
По умолчанию

Аууу. помогите. или я чтото такое нереальное прошу?
dem66 вне форума Ответить с цитированием
Старый 13.04.2012, 14:42   #5
Cronos20
Форумчанин
 
Регистрация: 08.07.2010
Сообщений: 679
По умолчанию

1. Много кода, никто читать не хочет
2. Наверное мало кто занимался такими задачами
3. Распознавать капчу на php ??? Я очень давно занимался подобным, но уж точно это был не php .... вы задаете вопрос про оптимизацию - единственный совет : возьмите нормальный язык для этого )))
Cronos20 вне форума Ответить с цитированием
Старый 13.04.2012, 14:46   #6
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
По умолчанию

не ну а php чем плох?
Нужен именно php, ну так всетаки почистить картинку, обрезать, и т.д вот и большой.

Главный вопрос - как овысить процент распознавания?
dem66 вне форума Ответить с цитированием
Старый 14.04.2012, 17:27   #7
dem66
Форумчанин
 
Регистрация: 31.05.2011
Сообщений: 316
По умолчанию

Есть вот у меня например гистограмма

Как по ней ПРАВЕЛЬНО розделить картинку? Допустим здесь четыре цифры, тоесть четыре впадины - разделители между цифрами, тобишь белый.

Вот как делаю я:
PHP код:
$captcha imagecreatefrompng($file); 
        
            list(
$width$height) = getimagesize($file);

            
$arr = array();

            for (
$w=1$w<=$width$w++)
                {
                for (
$h=1$h<=$height$h++)
                    {
                        
$index imagecolorat($captcha$w-1$h-1);
                        
                        
$color_tran imagecolorsforindex($captcha$index);
                        
                        if(
$color_tran['red'] == 0)$arr[$w][$h] = 1;

                    }
                }
                
            
$number = array();
            
$s 0;
            
$n 0;
            
$tmp = array();
            
            for(
$i=1$i<$width$i++){
                
                if(isset(
$arr[$i])){
                    
$s 1;
                    if(
$b==0)$number[] = $i;$b 1;
                }
                if(!isset(
$arr[$i]) && $s==1){
                    
$number[] = $i;
                }
                
            } 
Это только получаю минимальные знчения, дальше идет уже чистка.
Сдесь убираю по бокам от точи.
PHP код:
foreach($number as $k=>$n){
                if(
$number[$k]-== $number[$k-1] && $number[$k]+==$number[$k+1]){
                    unset(
$number[$k-1]);unset($number[$k+1]);
                }elseif(
$number[$k]-== $number[$k-1]){
                    unset(
$number[$k-1]);
                }elseif(
$number[$k]+== $number[$k+1]){
                    unset(
$number[$k+1]);
                }
                
            } 
Если растояние между цифрами например 1-2 пикселя то все нормально, а вот если больше то начинаются проблемы.
Например олучаю уже тогда:

PHP код:
Array
(
    [
0] => 1
    
[1] => 8
    
[2] => 9
    
[3] => 10
    
[4] => 16
    
[5] => 17
    
[6] => 18
    
[7] => 26

А нужно чтобы соседних небыло:
PHP код:
Array
(
    [
0] => 1
    
[2] => 8
    
[4] => 16
    
[7] => 26

Просто на ровные части розделить не получится так как некоторый цифры портят всю картину
Изображения
Тип файла: png his.png (3.0 Кб, 96 просмотров)
dem66 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
OCR delphi Maincore Общие вопросы Delphi 0 10.02.2012 13:38
Бот для онлайн игры. Считывание данных с использованием OCR Поиск Фриланс 3 25.02.2011 14:13
Распознавание с использованием OCR Поиск Фриланс 0 16.02.2011 21:33
распознание текста на картинке (не OCR) Xsires Общие вопросы Delphi 18 19.01.2011 18:18
Ocr в Delphi waterya Общие вопросы Delphi 1 19.06.2010 17:41