PHP: подсчет групп объектов в изображении - PullRequest
1 голос
/ 25 июня 2019

Мне нужно автоматизировать подсчет точек на этом изображении.Мы можем предположить, что точки всегда красные (или черные, если это помогает) и всегда такого размера на белом фоне.Позиции и счетчики часто меняются

Сначала я подумал, что могу использовать оптическое распознавание символов Tesseract и могу считать периоды или маркеры, но результаты пусты независимо от того, как я манипулирую изображением или символами белого списка.

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

Я смотрел в OpenCV, но единственный порт для PHP использует документацию, написанную преимущественно на китайском языкеи не поддерживает полную библиотеку, так что выдает Hough Transform из окна.

Код ниже: Наконец, я рискнул прочитать изображение с помощью PHP и перебрать пиксели и найти что-либо за пределами определенной области.порог, но я застрял в том, как я на самом деле сгруппировать отдельные пиксели для объекта.- Одно замечание: я не смог заставить это работать с полноразмерными изображениями (даже если они уже уменьшены), несмотря на отсутствие ограничений памяти и времени выполнения.

Я провел деньс половиной на это, и это кажется таким простым с формами, являющимися постоянными, но не ...

Вот изображение: Image to count

// creating the initial image
  $starting_img = imagecreatefrompng("converted.png");
  //Dimentions
  $imgDims = getimagesize($source_image);
  $scanWidth = $imgDims[0];
  $scanHeight = $imgDims[1];
  //New image
  $final = imagecreatetruecolor($scanWidth,$scanHeight);
  $white = imagecolorallocate($final, 255, 255, 255);
  imagefill($final,0,0,$white);

  $imageData = array();

  for ($y=1; $y < $scanHeight - 1; $y++) {
    // Get First Row, the scan each row col
    $currentRow = array();
    for ($x=1; $x < $scanWidth - 1; $x++) {
      // Get first col in row 1 and check its data
      $rgb = imagecolorat($starting_img,$x,$y);
      $color = array(
        'r' => ($rgb >> 16) & 255,
        'g' => ($rgb >> 8) & 255,
        'b' => $rgb & 255
      );
      $currentCol = array(
        'x' => $x,
        'y' => $y,
        'r' => $color['r'],
        'g' => $color['g'],
        'b' => $color['b'],
      );
      //Is the pixel red?
      // if ($color['r'] > 200 && $color['g'] < 100 && $color['b'] < 100) {
        array_push($currentRow, $currentCol);
      // }
    }
    //Does this row have any red pixels?
    // if (count($currentRow) > 1) {
      array_push($imageData, $currentRow);
    // }
  }

  foreach ($imageData as $currentRow => $row) {
    foreach ($row as $currentCol => $col) {
      $newColoredPixel  = imagecolorallocate($final,$col['r'],$col['g'],$col['b']);
      // adding the new pixel to the new image
      imagesetpixel($final,$col['x'],$col['y'],$newColoredPixel);
    }
  }

  file_put_contents('imageData.txt', print_r($imageData, true));

  imagepng($final,"final.png");

  imagedestroy($final);
  imagedestroy($starting_img);

1 Ответ

2 голосов
/ 25 июня 2019

Хороший вопрос!

Если капли не перекрываются - вы можете сосчитать их по формуле:

blob_count = total_blob_area / blob_unit_area

в вашем случае капля - это круг, поэтому формуластановится:

blob_count = total_blob_area / (π * r^2)

total_blob_area - это просто красноватое число пикселей , но вы должны найти диаметр блока капли эмпирически.

Кстати, функция imagecolorat () возвращает значение RGB только в том случае, если изображение имеет тип truecolor , однако ваш заданный PNG имеет индексированное цветовое пространство, так что можно извлечь из него реальные значения RGB -вы должны передать выходные данные imagecolorat () в imagecolorsforindex () .

Код метода подсчета BLOB, описанный выше, таков:

function countBlobs($imfile, $blob_diameter) {

    $blob_area = pi()*pow($blob_diameter/2, 2);

    $im = imagecreatefrompng($imfile);
    list($width, $height, $type, $attr) = getimagesize($imfile);

    $total_blob_area = 0;
    for ($x=0; $x < $width; $x++) {
        for ($y=0; $y < $height; $y++) {
            $rgb = imagecolorat($im, $x, $y);
            $colors = imagecolorsforindex($im, $rgb);
            $avg = ($colors['red']+$colors['green']+$colors['blue'])/3;
            if ($avg < 150) 
            {
                $total_blob_area++;
            }
        }
    }

    $blobs = $total_blob_area / $blob_area;

    return round($blobs);
}

echo ('blobs : ' . countBlobs('countblobs.png', 16));

Диаметр блока BLOB, который вы можетенайти с помощью инструментов измерения расстояния в GIMP.Однако, если ваши капли могут быть разных форм / размеров - тогда вам понадобится какое-то усреднение для области блока капли.

...