How to create an image that is the maximum of each band?
axkirillov opened this issue ยท 4 comments
For further math operations I need something like
// $image is a 3-band RGB
// $max is a one-band image where each pixel is the max of RGB
$max = $image->max();So far I have come up with:
[$r, $g, $b] = $image->bandsplit();
$rvg = $r->more($g);
$rvb = $r->more($b);
$rvgarvb = $rvg->andimage($rvb);
$gvr = $g->more($r);
$gvb = $g->more($b);
$gvragvb = $gvr->andimage($gvb);
$max = $rvgarvb->ifthenelse($r, $gvragvb->ifthenelse($g, $b));But maybe there is a more efficient way of doing that?
Hi again @axkirillov,
You need bandrank:
https://www.libvips.org/API/current/libvips-conversion.html#vips-bandrank
So eg.:
$max_at_each_pixel = $image->bandrank(["index" => $image->bands - 1]);The function list is handy for finding things like this:
I saw bandrank but I didn't quite understand what it does at first. It seems to be that in your example there is a missing $other parameter. I'm not sure what that should be since it doesn't quite match what is there in documentation
Ooop, you're right, there was a bug in php-vips. I've fixed it in head and credited you.
This now works for me:
#!/usr/bin/env php
<?php
require __DIR__ . '/vendor/autoload.php';
use Jcupitt\Vips;
if(count($argv) != 3) {
echo("usage: ./maxband.php input-image output-image\n");
exit(1);
}
$image = Vips\Image::newFromFile($argv[1], ["access" => "sequential"]);
[$r, $g, $b] = $image->bandsplit();
$image = $r->bandrank([$g, $b], ["index" => $image->bands - 1]);
$image->writeToFile($argv[2]);Thanks ๐! I am happy to have helped find a bug, albeit rather accidentally ๐ .