Forum

Barycenter (Baricenter?) or centroid of a PNG

hallo guys! I have some PNGs with alpha channel, there is a way to found the center, and also the “bounding box” of the image?
thanks!

little-house-png-image-31107|600x300

Yea, you can do that in compute, but that’s not too easy, something like:
for loop, if switch with break
basically you take center and then with forloop move your coords while you hit boder then do the break… then another direction…

it should be easier to use the stuff in VL.OpenCV instead of trying to do it in shader though

nah it’s easy in compute (for very naive AABB (axis aligned bounding box, meaning it’s not the smallest bounding box)

Texture2D InputTex;

// [0] min, [1] max, (pixels from top left) only 2 elements are used, strides = 8
RWStructuredBuffer<uint2> Outbuf;

// in the dispatcher node pass in TextureSize / *THREADS threadgroups
#define XTHREADS 16
#define YTHREADS 16

cbuffer cbuf : register(b0)
{
    float2 TextureSize = 256;
    float AlphaTest = 0.5;
}

// call this with a single thread group in dispatcher before MyNaiveAlphaBoundCS
[1, 1, 1]
void MyNaiveAlphaBoundClearCS(uint3 gtid : SV_GROUPTHREADID)
{
    Outbuf[0] = (uint2)TextureSize;
    Outbuf[1] = 0;
}

[XTHREADS, YTHREADS, 1]
void MyNaiveAlphaBoundCS(uint3 gtid : SV_GROUPTHREADID)
{
    float alpha = InputTex.Load(int3(gtid.xy, 0)).a;
    if(alpha > AlphaTest)
    {
        InterlockedMin(Outbuf[0], gtid.xy);
        InterlockedMax(Outbuf[1], gtid.xy);
    }
}

technique11 Clear { pass P0{SetComputeShader( CompileShader( cs_5_0, MyNaiveAlphaBoundClearCS() ) );} }
technique11 Bounds { pass P0{SetComputeShader( CompileShader( cs_5_0, MyNaiveAlphaBoundCS() ) );} }

in theory. I haven’t tested it. but it should provide a faster and less cluttered solution than opencv, although opencv contour gives you way much more accurate results.
and you just read back your end result or use it directly in your next shader

here is a solution that requires b39-preview and VL.OpenCV.

opening the patch it should have a red node, because you need to install VL.OpenCV first:

  • rightlclick the red node to open the vl editor
  • in the quad menu (topleft) go to manage nugets -> commandline
  • type: nuget install vl.opencv -pre
  • pressing enter this should take a while to download things
  • unfortunately now you’ll have to restart vvvv (but only this one time, since vl.opencv is then installed)

also shows that we’re still missing a centroid node in vl. but there is one in vvvv, as the patch shows.

PNGCentroid.zip (43.7 KB)