With packed binary pixel - 1 bit per pixel - morphology operation can be done with number of bits together. i.e. 8 pixels - 1 byte - can be read and dilated and eroded in a go.
When morphology is done in unit of byte, then the number of thread needs is pixel count divide by 8.
Below is a OpenCL kernel code that does dilation in 8 neighbor hood.
__kernel void Dilation(
__global uchar *d_src,
__global uchar *d_dst,
int width, int height,
int roiLeft, int roiTop, int roiRight, int roiBottom )
{
int x = (roiLeft & (~0x07)) + ( get_global_id(0) << 3 );
int y = roiTop + get_global_id(1);
int stride = width >> 3;
if( x <= roiRight )
{
int idx = x + (y-1) * width;
int bidx = idx >> 3;
uchar dilated = 0, C;
if( y > roiTop )
{
C = d_src[bidx];
dilated |= C; // North
dilated |= (C >> 1) | ( d_src[bidx-1] << 7); // North West
dilated |= (C << 1) | ( d_src[bidx+1] >> 7); // North East
}
bidx += stride;
if( y <= roiBottom )
{
C = d_src[ bidx ];
dilated |= C; // Center
dilated |= (C >> 1) | (d_src[ bidx - 1] << 7); // West
dilated |= (C << 1) | (d_src[ bidx + 1] >> 7); // East
}
bidx += stride;
if( y < roiBottom )
{
C = d_src[ bidx ];
dilated |= d_src[ bidx ]; // South
dilated |= (C >> 1) | (d_src[ bidx - 1] << 7); // South West
dilated |= (C << 1) | (d_src[ bidx + 1] >> 7); // South East
}
bidx -= stride;
if( y <= roiBottom )
{
d_dst[ bidx ] = dilated;
}
}
}
Below is a OpenCL kernel code that does erosion in 8 neighbor hood.
__kernel
void Erosion(
__global uchar *d_src,
__global uchar *d_dst,
int width, int height,
int roiLeft, int roiTop, int roiRight, int roiBottom )
{
int x = (roiLeft & (~0x07)) + ( get_global_id(0) << 3 );
int y = roiTop + get_global_id(1);
int stride = width >> 3;
if( x <= roiRight )
{
int idx = x + (y-1) * width;
int bidx = idx >> 3;
uchar eroded = 0xFF, C;
if( y > roiTop )
{
C = d_src[bidx];
eroded &= C;
eroded &= (C >> 1) | ( d_src[bidx-1] << 7);
eroded &= (C << 1) | ( d_src[bidx+1] >> 7);
}
bidx += stride;
if( y <= roiBottom )
{
C = d_src[ bidx ];
eroded &= C;
eroded &= (C >> 1) | (d_src[ bidx - 1] << 7);
eroded &= (C << 1) | (d_src[ bidx + 1] >> 7);
}
bidx += stride;
if( y < roiBottom )
{
C = d_src[ bidx ];
eroded &= d_src[ bidx ];
eroded &= (C >> 1) | (d_src[ bidx - 1] << 7);
eroded &= (C << 1) | (d_src[ bidx + 1] >> 7);
}
bidx -= stride;
if( y <= roiBottom )
{
d_dst[ bidx ] = eroded;
}
}
}
No comments:
Post a Comment