Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.
6711 Discussions

Help with definition of IppiBorderType and use of ippiFilterRowBorderPipeline

stormythecat10
Beginner
1,185 Views
Try as I might, I cannot find explainations of the IppiBorderType mentioned with the ippiFilterRowBorderPipeline function. Is see their enumerated type in the ippi manula, but not an example of what type of border they add:

ippBorderMirror
ippBorderMirrorR

I'm hoping one of them does:

original row
1 2 3 4 5
riw with a new border of 2 elements on each side
3 2 1 2 3 4 5 4 3

Also, one of my colleagues implemented a Gaussian Filter using repeated calls to ippsFIR_32f to
rows, a transpose and then again to columns.

It seems like I should be able to use ippiFilterRowBorder??? and ippiFilterCol but only if the build in
mirror does what we call "reflection" like in my example above.

Thank you,
Steven
Thank you,
Steven
0 Kudos
1 Solution
Chao_Y_Intel
Moderator
1,185 Views

Steven,

ippiFilterColumnPipeline is some different. There is no default border value and anchor for filter.
Users need to provide border value by themselves. See the sample code bellow:


IppiSize size={3,3};
Ipp16s data[7][3]={{1,1,1},
{2,2,2},
{3,3,3},
{4,4,4},
{5,5,5},
{6,6,6},
{100,100,100}
};

Ipp8u out[3*3];
Ipp8u bigbuffer[20000];
Ipp16s kernel[5]={1,1,1,1,1};
Ipp16s * pSrc[7];
Ipp16s ** ppSrc;
IppStatus re;

pSrc[0]=data[0];pSrc[1]=data[1];pSrc[2]=data[2];
//need set the border
pSrc[3]=data[3];pSrc[4]=data[4];pSrc[5]=data[5];pSrc[6]=data[6];

ppSrc=pSrc;
re=ippiFilterColumnPipeline_16s8u_C1R((const Ipp16s **) ppSrc, out, 3, size, kernel, 5, 1, bigbuffer);

the filter lenth is 5. pSrc[0],pSrc[1],pSrc[2] in input data.
pSrc[3],pSrc[4],pSrc[5],psrc[6] is border data.


Answer your questions:
1) I need to have mirrored borders for my columns just like I have on my rows. It need the data, not to the mirrored data.
1a) must i add my own physical borders? Or can I add extra pointers that point to the mirrored columns I want?
not necessary onthe physical borders. You can point to some mirrored columns. For example, in the code before, it can set:
pSrc[3]=pSrc[4]=pSrc[5]=pSrc[6]=data[3];
now it uses data[3] as the border.
2) if so, how does this affect ROI?
to the dst image size.
3) See my ppDst pointer (in the code above) prior to the column function call - is it even remotely right?
It looks some problem. the border need to keep at the bottom.
4) Is there a sample of a BorderPipeline Row & Column function set that is for a 2D image.
Hope the code before can help?
5) Should I be trying to use the ColumnPipeline function? (using IPP5.0).
IPP 6.1 is available now. Maybe you try the latest version. :-)
6) What exactly is the double pointer array pointing to in the colum function. The row pointers for RowBorderPipeline are offset by the width of the image in bytes. Are the column pointers set to be one image column offset (4 bytes for floats)?
see the sample before.

Thanks,
Chao



View solution in original post

0 Kudos
8 Replies
Chao_Y_Intel
Moderator
1,185 Views

Steven,

Ay test code that can show the problem? I just write a simple code for ippBorderMirror.
It looks fine. The output for the code bellow is:
11 12 15 18 19

Thanks,
Chao



IppiSize size={5,1};
Ipp8u data[5]={1,2,3,4,5};
Ipp16s output[5];
Ipp16s kernel[]={1,1,1,1,1};
Ipp16s * ppDst[1];
Ipp8u bigbuffer[20000];

ppDst[0]=output;

ippiFilterRowBorderPipeline_8u16s_C1R(data,5, ppDst, size, kernel, 5,2, ippBorderMirror,0,1, bigbuffer);
0 Kudos
stormythecat10
Beginner
1,185 Views
Quoting - stormythecat10
Try as I might, I cannot find explainations of the IppiBorderType mentioned with the ippiFilterRowBorderPipeline function. Is see their enumerated type in the ippi manula, but not an example of what type of border they add:

ippBorderMirror
ippBorderMirrorR

I'm hoping one of them does:

original row
1 2 3 4 5
riw with a new border of 2 elements on each side
3 2 1 2 3 4 5 4 3

Also, one of my colleagues implemented a Gaussian Filter using repeated calls to ippsFIR_32f to
rows, a transpose and then again to columns.

It seems like I should be able to use ippiFilterRowBorder??? and ippiFilterCol but only if the build in
mirror does what we call "reflection" like in my example above.

Thank you,
Steven
Thank you,
Steven

Thank you. I still find it odd that these border type enums's aren't spelled out somewhere.
I ran into another problem though, if you could please help.

I just noticed that the FilterColumnPipeline functions do not have border functionality.
I tried creating my own pointers for columnwise border mirroring with no luck.
Something appears to be wrong with the pointers to the Column function and/or
the size of the intermediate image. Can it be image size (512x512) or must it be larger
for "border" padding?

512x512 image, square kernel of max size 21, Matrix=512

static void HUEC_IPPGaussian( float *origPtr, float *outPtr, int NptGauss, float *GaussFilt, int32_t thread, HUEC_CORE_PARAMS *p )
{
IppStatus status;
int i;

int hNptGauss = (NptGauss - 1) / 2;
int Matrix = p->Matrix;
int imageSize = Matrix*Matrix;

IppiSize roi = { Matrix, Matrix }; // 512, 512

int sizeRow, sizeCol;
Ipp8u *pBufferRow, *pBufferCol;

Ipp32f *ppDst[512];

HUEC_THREAD_BUFS *threadBufs = &(p->HUECThrdBufs[thread]);


//This function computes the size of the working buffer required for ippiFilterRowBorderPipeline function.
//The buffer with the length pBufferSize[0] can be used to filter images with width equal to or less than roiSize.
status = ippiFilterRowBorderPipelineGetBufferSize_32f_C1R( roi, hNptGauss, &sizeRow );

//This function computes the size of the working buffer required for ippiFilterColumnPipeline function.
//The buffer with the length pBufferSize[0] can be used to filter images with width equal to or less than roiSize.
status = ippiFilterColumnPipelineGetBufferSize_32f_C1R( roi, hNptGauss, &sizeCol );

printf("sizeRow %dn", sizeRow);

pBufferRow = ippsMalloc_8u( sizeRow );
pBufferCol = ippsMalloc_8u( sizeCol );

for (i = 0; i < Matrix; i++)
ppDst = threadBufs->tmpGauss + i*Matrix;

status = ippiFilterRowBorderPipeline_32f_C1R( origPtr, Matrix*sizeof(float), ppDst,
roi, GaussFilt, NptGauss, hNptGauss, ippBorderMirror, 0, pBufferRow );

//Offset by one float for each column??? (Attempt border mirror column wise
for (i = hNptGauss; i < hNptGauss; i++)
ppDst = threadBufs->tmpGauss + hNptGauss-i;
for (i = hNptGauss; i < Matrix+hNptGauss; i++)
ppDst = threadBufs->tmpGauss + i;
for (i = Matrix+hNptGauss; i < Matrix+NptGauss; i++)
ppDst = threadBufs->tmpGauss + Matrix+hNptGauss-i;

status = ippiFilterColumnPipeline_32f_C1R( ppDst, outPtr, Matrix*sizeof(float),
roi, GaussFilt, NptGauss, pBufferCol );


Thank you,
Steven
0 Kudos
Chao_Y_Intel
Moderator
1,185 Views

Hi, Steven,

There is no need to pad the "border" by yourself. The function internally does the border handling. ippiFilterRowBorderPipeline is belong to computer vision library. This function has a bit different with some other common filters. Some other filter need to pad the border by user themselves. Is this the problem in the code?

Thanks,
Chao

0 Kudos
stormythecat10
Beginner
1,185 Views
Quoting - Chao Yu (Intel)

Hi, Steven,

There is no need to pad the "border" by yourself. The function internally does the border handling. ippiFilterRowBorderPipeline is belong to computer vision library. This function has a bit different with some other common filters. Some other filter need to pad the border by user themselves. Is this the problem in the code?

Thanks,
Chao


The ippiFilterRowBorderPipeline works and give me a good result. (I dumped the intermediate buffer)
I'm attempting a 2D Gaussian by way of 2 1D Gaussian functions - Row then Column.

The ippiFilterColumnPipeline a few lines down does not work. I need to border the intermediate
image to handle the column processing myself it appears. Here are my questions?

1) I need to have mirrored borders for my columns just like I have on my rows.
1a) must i add my own physical borders? Or can I add extra pointers that point to the mirrored columns I want?
2) if so, how does this affect ROI?
3) See my ppDst pointer (in the code above) prior to the column function call - is it even remotely right?
4) Is there a sample of a BorderPipeline Row & Column function set that is for a 2D image. (The one sample
I've seen isn't all that help ful as it's 1D or nearly so)
5) Should I be trying to use the ColumnPipeline function? (using IPP5.0)
6) What exactly is the double pointer array pointing to in the colum function. The row pointers for RowBorderPipeline are offset by the width of the image in bytes. Are the column pointers set to be one
image column offset (4 bytes for floats)?

I'm sure what I'm trying to do has been done before.
a 2D Gaussian Filter using RowBorderPipeline and ColumnPipeline.

Thank you,
Steven

0 Kudos
Chao_Y_Intel
Moderator
1,186 Views

Steven,

ippiFilterColumnPipeline is some different. There is no default border value and anchor for filter.
Users need to provide border value by themselves. See the sample code bellow:


IppiSize size={3,3};
Ipp16s data[7][3]={{1,1,1},
{2,2,2},
{3,3,3},
{4,4,4},
{5,5,5},
{6,6,6},
{100,100,100}
};

Ipp8u out[3*3];
Ipp8u bigbuffer[20000];
Ipp16s kernel[5]={1,1,1,1,1};
Ipp16s * pSrc[7];
Ipp16s ** ppSrc;
IppStatus re;

pSrc[0]=data[0];pSrc[1]=data[1];pSrc[2]=data[2];
//need set the border
pSrc[3]=data[3];pSrc[4]=data[4];pSrc[5]=data[5];pSrc[6]=data[6];

ppSrc=pSrc;
re=ippiFilterColumnPipeline_16s8u_C1R((const Ipp16s **) ppSrc, out, 3, size, kernel, 5, 1, bigbuffer);

the filter lenth is 5. pSrc[0],pSrc[1],pSrc[2] in input data.
pSrc[3],pSrc[4],pSrc[5],psrc[6] is border data.


Answer your questions:
1) I need to have mirrored borders for my columns just like I have on my rows. It need the data, not to the mirrored data.
1a) must i add my own physical borders? Or can I add extra pointers that point to the mirrored columns I want?
not necessary onthe physical borders. You can point to some mirrored columns. For example, in the code before, it can set:
pSrc[3]=pSrc[4]=pSrc[5]=pSrc[6]=data[3];
now it uses data[3] as the border.
2) if so, how does this affect ROI?
to the dst image size.
3) See my ppDst pointer (in the code above) prior to the column function call - is it even remotely right?
It looks some problem. the border need to keep at the bottom.
4) Is there a sample of a BorderPipeline Row & Column function set that is for a 2D image.
Hope the code before can help?
5) Should I be trying to use the ColumnPipeline function? (using IPP5.0).
IPP 6.1 is available now. Maybe you try the latest version. :-)
6) What exactly is the double pointer array pointing to in the colum function. The row pointers for RowBorderPipeline are offset by the width of the image in bytes. Are the column pointers set to be one image column offset (4 bytes for floats)?
see the sample before.

Thanks,
Chao



0 Kudos
idoo
Beginner
1,185 Views

Steven,

Ay test code that can show the problem? I just write a simple code for ippBorderMirror.
It looks fine. The output for the code bellow is:
11 12 15 18 19

Thanks,
Chao



IppiSize size={5,1};
Ipp8u data[5]={1,2,3,4,5};
Ipp16s output[5];
Ipp16s kernel[]={1,1,1,1,1};
Ipp16s * ppDst[1];
Ipp8u bigbuffer[20000];

ppDst[0]=output;

ippiFilterRowBorderPipeline_8u16s_C1R(data,5, ppDst, size, kernel, 5,2, ippBorderMirror,0,1, bigbuffer);

Dear Chao,

When I try the following code (mainly changing size to {5 , 2} from your previous example)

IppiSize size={5,2};
const int dataSize = 5000;
Ipp8u data[dataSize];//={1,2,3,4,5};
Ipp16s output[500];
memset(data, 0, dataSize);
Ipp16s kernel[]={1,1,1,1,1};
Ipp16s ppDst[1];
Ipp8u bigbuffer[20000];
ppDst[0]=output;
ippiFilterRowBorderPipeline_8u16s_C1R(data, 5, ppDst, size, kernel, 5,2, ippBorderMirror,0,1, bigbuffer);

it crash.
Do you have any idea why?
0 Kudos
SergeyKostrov
Valued Contributor II
1,185 Views
...
Ipp8u bigbuffer[20000];
...

You're creating an array of 20,000 bytes on the stack. I don't know if this is the exact reason of your crash, but I would consider:

1. Declareas static:
...
static Ipp8u bigbuffer[20000] = { 0x0 };
...

2. Or, pre-allocate on the Heap with malloc or new

3. Or, increase Linker'sStack & Heapsettings ( be carefull! ). I usually use power of 2 numbers and you need toselect your own values.If asum of all these values exceeds the amount of available memory anapplication won't start:


0 Kudos
idoo
Beginner
1,185 Views
Thank you Sergey. I had no idea.
But the problem is different (I found it).
I used:
[bash]IppiSize size={5,2};
const int dataSize = 5000;
Ipp8u data[dataSize];//={1,2,3,4,5};
Ipp16s output[500];
memset(data, 0, dataSize);
Ipp16s kernel[]={1,1,1,1,1}; 
Ipp16s ppDst[1]; 
Ipp8u bigbuffer[20000];
ppDst[0]=output;
ippiFilterRowBorderPipeline_8u16s_C1R(data, 5, ppDst, size, kernel, 5,2, ippBorderMirror,0,1, bigbuffer);
[/bash]
I should change:
[bash]Ipp16s ppDst[1];
ppDst[0] = output;
// to 
Ipps pDst[2];
pDst[0] = output;
pDst[1] = output + size.width;[/bash]
[bash]
[/bash]
0 Kudos
Reply