Hentikan preg_match_all setelah merekam perubahan grup

Saya mencoba mengidentifikasi lebar persegi panjang berwarna di dalam gambar. Untuk penanganan gambar saya menggunakan Imagick untuk PHP.

Idenya adalah untuk mengubah gambar menjadi txt dan mencari txt ini dengan regex untuk semua piksel yang memiliki warna tertentu (#00FF00).

Berikut adalah contoh tampilan txt tersebut (kutipan dimulai dari piksel kolom 0 baris 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)
....

Ini Kode saya:

$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;

Sejauh ini berfungsi dengan baik, tetapi sangat lambat karena menemukan semua piksel dalam persegi panjang berwarna termasuk tinggi penuh sumbu y.

Sekarang karena saya hanya tertarik pada lebar persegi panjang #00FF00 ini, saya pikir akan lebih cepat jika regex hanya menemukan piksel pertama yaitu #00FF00 dan kemudian menelusuri baris piksel hingga akhir (baris 83 dalam contoh saya) dan berhenti segera setelah mencapai baris ke-84.

Apakah ada modifikasi yang dapat saya lakukan pada regex saya sehingga dapat melakukan apa yang saya cari?


person micharuss    schedule 31.01.2016    source sumber
comment
Serius, jika Anda ingin kecepatan lebih, gunakan fungsi manipulasi gambar daripada.... ini.   -  person Lucas Trzesniewski    schedule 31.01.2016
comment
Saya melihat Anda hanya tertarik pada yang terakhir dan pertama?   -  person Yehia Awad    schedule 31.01.2016
comment
@яша ya, hanya yang terakhir dan pertama   -  person micharuss    schedule 31.01.2016
comment
@LucasTrzesniewski saya mencoba, tetapi tidak menemukan apa pun yang sesuai dengan kebutuhan saya   -  person micharuss    schedule 31.01.2016
comment
php.net/manual/en/book.image.php   -  person Lucas Trzesniewski    schedule 31.01.2016
comment
jadi jika saya memahami Anda dengan benar untuk keseluruhan proses, Anda tidak akan memulai dan mengakhiri setiap baris? misalnya untuk baris 83 Anda ingin yang terakhir dan akhir untuk baris 84 Anda ingin yang terakhir dan akhir dan seterusnya dan seterusnya atau Anda hanya ingin awal dan akhir keseluruhan teks?   -  person Yehia Awad    schedule 31.01.2016
comment
@яша saya hanya ingin baris pertama dan terakhir dari baris pertama warna ini muncul. baris lainnya tidak masalah. tapi saya tidak tahu di mana baris pertama dimulai. jadi pada dasarnya temukan baris pertama dengan warna itu dan lihat di mana ujungnya pada baris itu. kemudian berhenti.   -  person micharuss    schedule 31.01.2016
comment
Anda mendapatkan keluaran ini sebagai tipe string?   -  person Yehia Awad    schedule 31.01.2016
comment
@яша maksudnya file txt?   -  person micharuss    schedule 31.01.2016
comment
Pertama: lakukan seperti yang dikatakan @LucasTrzesniewski - gunakan fungsi gambar yang tepat. Namun Anda dapat mengaitkan regex ke awal - pendekatan pertama Anda memerlukan 558 langkah (menurut regex101.com/r /pU7fL1/1), dengan jangkar hanya 58 - peningkatan sebesar 90% (lihat di sini: regex101.com/r/pU7fL1/2)   -  person Jan    schedule 31.01.2016
comment
Terima kasih teman-teman, fungsi gambar lebih disukai, tetapi sepertinya tidak ada yang mampu memenuhi keinginan saya. Tapi saya menemukan regex yang melakukan apa yang saya inginkan: regex101.com/r/pU7fL1/3   -  person micharuss    schedule 01.02.2016
comment
@micharuss Apakah Anda mengerjakan soal pekerjaan rumah yang sama dengan orang ini: stackoverflow.com/questions/34939555/   -  person Danack    schedule 01.02.2016


Jawaban (1)


Anda dapat menggunakan $imagick->trimImage() dan kemudian $imagick->getImagePage() untuk mendapatkan lokasi jika persegi panjang adalah satu-satunya hal pada gambar, atau Anda dapat mengulangi piksel, dan melakukan deteksi tepi Anda sendiri.

$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();
person Danack    schedule 31.01.2016
comment
terima kasih, itu berhasil untuk saya! sayangnya, trimImage() tidak berfungsi karena ada banyak gambar selain persegi panjang berwarna saya... - person micharuss; 01.02.2016