Координаты групп точек на изобаржении, php

Discussion in 'PHP' started by wildshaman, 18 May 2010.

  1. wildshaman

    wildshaman Elder - Старейшина

    Joined:
    16 Apr 2008
    Messages:
    477
    Likes Received:
    483
    Reputations:
    99
    Имеется изображение
    [​IMG]

    Один квадратик - один пиксель.
    Необходимо в массив с N элементов (где N - группа связанных черных пискселей, в нашем случае 3) занестив каждый элемент строку с координатами точек, входящих в кучу
    Тобдбишь на выходе из такой пикчи мы должны получить
    a[1]="2,3|2,4|3,4|3,5|"
    a[2]="7,6|7,7|8,5|8,6|"
    a[3]="10,1|10,2|"

    Надо на php и использованием gd.
    Бьюсь уже целый час :(
    Буду благодарен за код.
     
    #1 wildshaman, 18 May 2010
    Last edited: 18 May 2010
  2. dr.Web

    dr.Web Member

    Joined:
    2 Feb 2009
    Messages:
    7
    Likes Received:
    22
    Reputations:
    10
    берёшь первую строчку считаешь кол-во пикселей в ширину, пробегаешь попиксельно и считываешь цвет.если цвет чёрный то пишешь координату в массив. цвет узнавать функцией
    ImageColorAt(int image, int x, int y);


    image - это картинка
    x,y - координаты соответственно
     
  3. AK3RN

    AK3RN New Member

    Joined:
    25 Apr 2010
    Messages:
    9
    Likes Received:
    1
    Reputations:
    0
    Хинт: открой картинку в hex-редакторе
     
  4. dr.Web

    dr.Web Member

    Joined:
    2 Feb 2009
    Messages:
    7
    Likes Received:
    22
    Reputations:
    10
    а при чём тут хекс?
     
  5. GreenBear

    GreenBear наркоман с медалью

    Joined:
    7 May 2005
    Messages:
    2,547
    Likes Received:
    1,398
    Reputations:
    612
    [offtop]>Бьюсь уже целый час
    и все?) иногда и 3 дня на задачу убиваешь, получая в итоге 100 строк кода :)[/offtop]
    на самом деле задача очень легкая, главное не кодить, а продумать алгоритм. потом уже кодить.
     
  6. dr.Web

    dr.Web Member

    Joined:
    2 Feb 2009
    Messages:
    7
    Likes Received:
    22
    Reputations:
    10
    согласен.
     
  7. wildshaman

    wildshaman Elder - Старейшина

    Joined:
    16 Apr 2008
    Messages:
    477
    Likes Received:
    483
    Reputations:
    99
    Соль в том, что надо именно находить ГРУППЫ элементов


    Ан нет, решения не нашел верного :(
     
    #7 wildshaman, 18 May 2010
    Last edited: 18 May 2010
  8. astrologer

    astrologer Elder - Старейшина

    Joined:
    30 Aug 2007
    Messages:
    837
    Likes Received:
    267
    Reputations:
    59
    Похоже на ту самую задачу уровня продвинутого школьника из темы "Как стать программистом". Классификация ещё та, конечно, определенно радует "аналог wget" - а это огромный объем работы - сразу после чего следует BB-парсер для которого достаточно определить автомат со стеком.
     
  9. Kaimi

    Kaimi Well-Known Member

    Joined:
    23 Aug 2007
    Messages:
    1,732
    Likes Received:
    811
    Reputations:
    231
    Как вариант: найди реализацию алгоритма волновой трассировки и допиши под себя.
    Задача на графы же...
     
    _________________________
  10. eLWAux

    eLWAux Elder - Старейшина

    Joined:
    15 Jun 2008
    Messages:
    860
    Likes Received:
    616
    Reputations:
    211
    воть:

    сперва превращает твою картинку в матрицу, типа:
    Потом распознает.
    Результат:
    PHP:
    array(3) {
      [
    0]=>  string(7"0,9|1,9"
      
    [1]=>  string(15"2,1|3,1|3,2|4,2"
      
    [2]=>  string(15"4,7|5,6|5,7|6,6"
    }
    Сорс: http://paste.ly/1aF
     
    1 person likes this.
  11. roxblnfk

    roxblnfk Elder - Старейшина

    Joined:
    6 Feb 2010
    Messages:
    189
    Likes Received:
    42
    Reputations:
    19
    недавно как раз писал функцию для очистки изображения от малых площадей.

    щас подстёр лишнее, должно работать (не тестил)

    PHP:
    $ImgName='...';

    $im ImageCreateFromJpeg($ImgName);
    $W=imagesx($im);
    $H=imagesy($im);
    $IMAGE=array();
    $WHITE=array();
    for(
    $x=0;$x<$W;$x++){
        for(
    $y=0;$y<$H;$y++){
            
    $rgb ImageColorAt($im$x$y);
            
    $r = ($rgb >> 16) & 0xFF;
            
    $g = ($rgb >> 8) & 0xFF;
            
    $b $rgb 0xFF;
            
    $int1=63;
            
    $int2=195;
            if(
    $r<$int1 && $g<$int1 && $b<$int1$IMAGE[$x][$y]=2;
            if(
    $r<$int2 && $g<$int2 && $b<$int2$IMAGE[$x][$y]=1;
            else 
    $IMAGE[$x][$y]=0;
            
    $WHITE[$x][$y]=false;
        }
    }
    function 
    get_volume_pedratXD(&$IMAGE, &$WHITE$x$y$arrOk=array(1,2), $lim=200$towhite=true){
        
    $MA=array($x=>array($y=>true));//micro array
        
    $S=1;
        
    $arrow=array(array(0=>1,1=>0),array(0=>-1,1=>0),array(0=>0,1=>1),array(0=>0,1=>-1));
        do{
            
    $add=0;
            foreach(
    $MA as $X=>$z){
                foreach(
    $z as $Y=>$V){
                    if(
    $lim<$S) return array($S,$MA);
                    if(
    $V!==false){
                        foreach(
    $arrow as $arrrr){
                            
    $ax=$X+$arrrr[0];
                            
    $ay=$Y+$arrrr[1];
                            if(!isset(
    $MA[$ax][$ay]) && isset($IMAGE[$ax][$ay]))if($WHITE[$ax][$ay]!==true){
                                if(
    $towhite)$WHITE[$ax][$ay]=true;
                                if(
    in_array($IMAGE[$ax][$ay],$arrOk,true)){
                                    
    $MA[$ax][$ay]=true;
                                    
    $add++;
                                    
    $S++;
                                }else 
    $MA[$ax][$ay]=false;
                            }
                        }
                    }
                }
            }
        }while(
    $add>0);
        return array(
    $S,$MA);
    }
    function 
    kill_perperellipepidi(&$IMAGE$WHITE$arrOk=array(1,2), $lim=200$Min=1$Max=15$Salit=0){
        
    $arrow=array(array(1,0),array(-1,0),array(0,1),array(0,-1));
        foreach(
    $IMAGE as $x=>$z){
            foreach(
    $z as $y=>$Z){
                if(
    $WHITE[$x][$y]!==true && in_array($Z,$arrOk,true)){
                    
    $SS=get_volume_pedratXD($IMAGE,$WHITE,$x,$y,$arrOk,$lim);
                    
    $S=$SS[0];
                    
    $Arr=$SS[1];
                    
    //echo '<br>Scan SSS: ['.$x.','.$y.'] = '.$S;
                    
    if($S<=$Max && $S>=$Min){
                        foreach(
    $Arr as $X=>$v){
                            foreach(
    $v as $Y=>$V){
                                if(
    $V==true$IMAGE[$X][$Y]=$Salit;
                            }
                        }
                    }
                    
    //вот тут пиши функцию для преобразования массива 
                    //в строку, какую тебе угодно... например $RETURN[]=$Arr; return $RETURN; (и функция вернёт массивы $Arr на все пятна в отдельном массиве)
                    
                    //$S передаёт площадь пятен
                    //$Arr ===== $Arr[$x][$y]=$Value ($Value должно быть true, если он false, то пиксель был просканен, но он не относится к пятну)
                    // параметр этой функции $Salit - каким index'ом залить пятно, если его площадь от $Min до $Max включительно (если не надо, то назнач $Max=-1)
                    // $Lim для тех кто шарит, сам же ставь равным площади всей картинки
                    // $WHITE - массив предела сканирования, не парься, если задача простая
                
    }
            }
        }
    }
    //просчитываем массив картинки $IMAGE:
    kill_perperellipepidi($IMAGE,$WHITE,array(1,2),$W+$H,1,-1,0);
    раскуривай коменты
     
  12. roxblnfk

    roxblnfk Elder - Старейшина

    Joined:
    6 Feb 2010
    Messages:
    189
    Likes Received:
    42
    Reputations:
    19
    кстати, чтобы понять, что функция нашла нужные пиксели, то можно перекрасить их на картинке и посмотреть картинку
    (добавить)
    PHP:
    kill_perperellipepidi($IMAGE,$WHITE,array(1,2),$W+$H,1,$W+$H,1);
    $black=imagecolorallocate($im,0,0,0);
    $red=imagecolorallocate($im,255,0,0);
    $green=imagecolorallocate($im,0,255,0);
    $white=imagecolorallocate($im,255,255,255);
    for(
    $x=0;$x<$W;$x++){
        for(
    $y=0;$y<$H;$y++){
            if(
    $IMAGE[$x][$y]===0)imagesetpixel($im,$x,$y,$white);
            if(
    $IMAGE[$x][$y]===1)imagesetpixel($im,$x,$y,$red);
        }
    }
    imagegif($im,'result.gif');
    должно работать, с виду в коде багов нет

    ===============

    Ну что, автор, помог или нет?
     
    #12 roxblnfk, 18 May 2010
    Last edited: 18 May 2010