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

Separable Filters

P__Ella
Beginner
1,138 Views

Hi, 

I’m implementing a pipeline for separable filter, using function ippiFilterRowBorderPipeline_16u_C1R and ippiFilterColumnPipeline_16u_C1R.

Since the documentation for these functions is quite poor, I use as a reference the example FilterColumnPipeline_Low.c.

The kernel size in the example is 3, and I’m trying to adjust it to different kernel size. Some adjustments are obvious, and some less.

In the second call to ippiFilterRowBorderPipeline_Low_16s_C1R (inside the loop) the destination is (Ipp16u**)(pGet + 2). What it the correct destination for kernel size=5? My first guess (4) doesn't seem to work.

Thanks,

Ella

 

 

 

0 Kudos
5 Replies
Andrey_B_Intel
Employee
1,138 Views

Hi Ella.

I'm attaching new modified example for arbitrary kernel size. I hope it is very easy now.

Thanks for your interest to IPP library.

 

0 Kudos
Igor_A_Intel
Employee
1,138 Views

Hi Ella,

in the latest IPP versions we added the new special API for separable filters - you can use it instead of sequential calls of FilterRowPipeline & FilterColumnPipeline with circular bugffer in a loop:

IPPAPI(IppStatus, ippiFilterSeparableGetBufferSize, (IppiSize roiSize, IppiSize kernelSize, IppDataType dataType, IppDataType kernelType, int numChannels, int* pBufferSize))
IPPAPI(IppStatus, ippiFilterSeparableGetSpecSize, (IppiSize kernelSize, IppDataType dataType, int numChannels, int* pSpecSize))

IPPAPI(IppStatus, ippiFilterSeparableInit_16s, (const Ipp16s* pRowKernel, const Ipp16s* pColumnKernel, IppiSize kernelSize, int divisor, int scaleFactor, IppDataType dataType,
    int numChannels, IppiFilterSeparableSpec* pSpec))
IPPAPI(IppStatus, ippiFilterSeparableInit_32f, (const Ipp32f* pRowKernel, const Ipp32f* pColumnKernel, IppiSize kernelSize, IppDataType dataType,
    int numChannels, IppiFilterSeparableSpec* pSpec))

IPPAPI(IppStatus, ippiFilterSeparable_8u_C1R, (const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp8u borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))
IPPAPI(IppStatus, ippiFilterSeparable_8u_C3R, (const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp8u* borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))
IPPAPI(IppStatus, ippiFilterSeparable_8u_C4R, (const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp8u* borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))

IPPAPI(IppStatus, ippiFilterSeparable_8u16s_C1R, (const Ipp8u* pSrc, int srcStep, Ipp16s* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp8u borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))
IPPAPI(IppStatus, ippiFilterSeparable_8u16s_C3R, (const Ipp8u* pSrc, int srcStep, Ipp16s* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp8u* borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))
IPPAPI(IppStatus, ippiFilterSeparable_8u16s_C4R, (const Ipp8u* pSrc, int srcStep, Ipp16s* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp8u* borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))

IPPAPI(IppStatus, ippiFilterSeparable_16s_C1R, (const Ipp16s* pSrc, int srcStep, Ipp16s* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp16s borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))
IPPAPI(IppStatus, ippiFilterSeparable_16s_C3R, (const Ipp16s* pSrc, int srcStep, Ipp16s* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp16s* borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))
IPPAPI(IppStatus, ippiFilterSeparable_16s_C4R, (const Ipp16s* pSrc, int srcStep, Ipp16s* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp16s* borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))

IPPAPI(IppStatus, ippiFilterSeparable_16u_C1R, (const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp16u borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))
IPPAPI(IppStatus, ippiFilterSeparable_16u_C3R, (const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp16u* borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))
IPPAPI(IppStatus, ippiFilterSeparable_16u_C4R, (const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp16u* borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))

IPPAPI(IppStatus, ippiFilterSeparable_32f_C1R, (const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp32f borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))
IPPAPI(IppStatus, ippiFilterSeparable_32f_C3R, (const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp32f* borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))
IPPAPI(IppStatus, ippiFilterSeparable_32f_C4R, (const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep, IppiSize roiSize,
    IppiBorderType borderType, Ipp32f* borderValue, const IppiFilterSeparableSpec* pSpec, Ipp8u* pBuffer))

regards, Igor

0 Kudos
Nick17
Beginner
916 Views

Hello Igor,

to me, the implementation of separable filter does not make sense when using different row- and column-kernels:

There is only one parameter which is used as divisor for both row- and column-calculations.

 

-> As an example for mean-filtering, how shall one set the "divisor" and "scaleFactor" when filtering with row-kernel={1, 1, 1} and col-kernel={1, 1, 1, 1, 1} ?

Function ippiFilterSeparableInit_16s() has relevant parameters "int divisor, int scaleFactor".

In my test, when using "divisor=3", the resulting image-values are too high, when using "divisor=5", the values are too low.

"scaleFactor" does not seem to be used internally at all.

 

-> I would expect to have distinct parameters "divisorRow" and "divisorCol", which are applied to the row- and column-calculations, resp.

 

Thank you for feedback.

Regards,

Nick

 

 

 

0 Kudos
Nick17
Beginner
789 Views

Hello everybody,

any answer to my question?

Thanks,

Nick

0 Kudos
Nikolai_T_
Beginner
1,138 Views

Hi Igor,

I just tried using the new functions but had a problem that it was writing one row past the destination buffer. I described it in another post. Can you verify what is the source of the problem?

In the mean time can I use the ippiFilterRow(Column)BorderPipeline functions as an alternative? Do they provide equivalent performance?

Regards Nikolai

0 Kudos
Reply