捕获组更改后使 preg_match_all 停止

Make preg_match_all stop after capturing group changes

我正在尝试识别图像中彩色矩形的宽度。对于图像处理,我将 Imagick 用于 PHP.

我们的想法是将图像转换为 txt 并使用正则表达式搜索此 txt 以查找具有特定颜色 (#00FF00) 的所有像素。

这是该 txt 的示例(摘录从像素列 0 第 83 行开始):

0,83: (255,255,255,1)  #FFFFFF  graya(255,1)
1,83: (255,255,255,1)  #FFFFFF  graya(255,1)
2,83: (255,255,255,1)  #FFFFFF  graya(255,1)
3,83: (0,255,0,1)  #00FF00  graya(0,1)
4,83: (0,255,0,1)  #00FF00  graya(0,1)
5,83: (0,255,0,1)  #00FF00  graya(0,1)
6,83: (255,255,255,1)  #FFFFFF  graya(255,1)
7,83: (255,255,255,1)  #FFFFFF  graya(255,1)
8,83: (255,255,255,1)  #FFFFFF  graya(255,1)
0,84: (255,255,255,1)  #FFFFFF  graya(255,1)
1,84: (255,255,255,1)  #FFFFFF  graya(255,1)
2,84: (255,255,255,1)  #FFFFFF  graya(255,1)
3,84: (0,255,0,1)  #00FF00  graya(0,1)
4,84: (0,255,0,1)  #00FF00  graya(0,1)
5,84: (0,255,0,1)  #00FF00  graya(0,1)
....

这是我的代码:

$canvasImg = new Imagick("_sources/passepartout/". $deviceName .".png");

$canvasImg->setFormat(txt);

preg_match_all("/(\d+),(\d+): \(0,255,0,1\)/is", $canvasImg, $colorMatchAll);

$firstPixelX = reset($colorMatch[1]);
$lastPixelX = end($colorMatch[1]);

$canvasWidth = $lastPixelX - $firstPixelX;

目前为止一切正常,但速度非常慢,因为它会找到彩色矩形中的所有像素,包括 y 轴的整个高度。

现在我只对这个 #00FF00 矩形的宽度感兴趣,我认为如果正则表达式只找到第一个像素 #00FF00 然后遍历像素行直到结束(行在我的示例中为 83)并在到达第 84 行时立即停止。

是否可以对我的正则表达式进行修改以使其满足我的要求?

如果图像上只有矩形,您可以使用 $imagick->trimImage() 然后使用 $imagick->getImagePage() 来获取位置,或者您可以遍历像素,然后执行你自己的边缘检测。

$imagick = new \Imagick(realpath($imagePath));
$imageIterator = $imagick->getPixelRegionIterator(0, 0, 
     $imagick->getImageWidth(),
     $imagick->getImageHeight(),
 );

/* Loop through pixel rows */
foreach ($imageIterator as $pixels) {
    /** @var $pixel \ImagickPixel */
    /* Loop through the pixels in the row (columns) */
    foreach ($pixels as $column => $pixel) {
        $red = $pixel->getColorValue(\Imagick::COLOR_RED);
        $green = $pixel->getColorValue(\Imagick::COLOR_GREEN);
        $blue = $pixel->getColorValue(\Imagick::COLOR_BLUE);
        //Do detection here
    }
    /* Sync the iterator, this is important to do on each iteration */
    $imageIterator->syncIterator();
}

$imageIterator->clear();