You are right, I was hoping to stay (do all work) in PDL domain, i.e. maybe I overlooked function e.g. similar to CORE::index or even List::Util::first.
Now my solution is this:
# $s is our segmented image use integer; my ( $w, $h ) = $s-> dims; my $str = ${ $s-> byte-> get_dataref }; my @b = map { [ [ $w, 0 ], [ $h, 0 ] ] } 1 .. $s-> max; while ( $str =~ /[^\x00]/g ) { my $i = pos( $str ) - 1; my $x = $i % $w; my $y = $i / $w; my $c = ord( $& ) - 1; $b[ $c ][ 0 ][ 0 ] = $x if $x < $b[ $c ][ 0 ][ 0 ]; $b[ $c ][ 0 ][ 1 ] = $x if $x > $b[ $c ][ 0 ][ 1 ]; $b[ $c ][ 1 ][ 0 ] = $y if $y < $b[ $c ][ 1 ][ 0 ]; $b[ $c ][ 1 ][ 1 ] = $y if $y > $b[ $c ][ 1 ][ 1 ]; }
It's fast, and will get slightly more complex for 2-byte "characters", if number of "objects" is more than 255.
Btw, this single scan with regex engine is twice (or _only_ twice?) as fast as multiple scans with index and rindex (actually 4 scans per "object", on concatenated rows and concatenated columns).
p.s. But, ehm, direct per-pixel scan (accessing $s-> at( $x, $y )) is 5 times slower than PDL-only solution.In reply to Re^2: PDL: Looking for efficient way to extract sub-images, by finding bounding boxes of "objects"
by vr
in thread PDL: Looking for efficient way to extract sub-images, by finding bounding boxes of "objects"
by vr
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |