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

Separable Filters

P__Ella
ビギナー
2,098件の閲覧回数

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 件の賞賛
5 返答(返信)
Andrey_B_Intel
従業員
2,098件の閲覧回数

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.

 

Igor_A_Intel
従業員
2,098件の閲覧回数

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

Nick17
ビギナー
1,876件の閲覧回数

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

 

 

 

Nick17
ビギナー
1,749件の閲覧回数

Hello everybody,

any answer to my question?

Thanks,

Nick

Nikolai_T_
ビギナー
2,098件の閲覧回数

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

返信