Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
6815 Discussions

ipprWarpAffine not producing expected results in IPP 7.0 Update 5

Matthew_Holladay
Beginner
789 Views

I'm having a problem using the ipprWarpAffine_16u_C1PV call in IPP 7.0 update 5 to perform an affine transform on a volume.

To narrow down the problem, I created a simple program that creats an 8x8x8 volume with a known value written into each slice. It then uses a set of coefficients that should represent an identity transformation on the data, meaning that the output volume should be exactly the same as the input volume.

However, when I run the program the output does not appear to match the expected results. Sample source and output is included below.

// ----------------------------------- sample source

[cpp]// WarpAffineTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include 
#include 
#include 
#include "ippcore.h"
#include "ipps.h"
#include "ippr.h"

static void testIpp(int inX, int inY, int inZ, int outX, int outY, int outZ)
{
    try
    {
        // create input and output buffers
        short *inData = new short[inX * inY * inZ];
        short *outData = new short[outX * outY * outZ];
        memset(inData, 0, inX * inY * inZ * sizeof(short));
        memset(outData, 0, outX * outY * outZ * sizeof(short));
        short *pData = inData;
        for (int i = 0; i < inZ; ++i)
        {
            for (int y = 0; y < inY; ++y)
            {
                for (int x = 0; x < inX; ++x)
                {
                    *pData = (short)(i + 1);
                    ++pData;
                }
            }
        }

        // print data info
        std::cout << "inX, inY, inZ = " << inX << ", " << inY << ", " << inZ << std::endl;
        std::cout << "outX, outY, outZ = " << outX << ", " << outY << ", " << outZ << std::endl;
        std::cout << std::endl;

        // print input data
        pData = inData;
        std::cout << "Input Data:" << std::endl;
        for (int z = 0; z < inZ; ++z)
        {
            for (int y = 0; y < inY; ++y)
            {
                for (int x = 0; x < inX; ++x)
                {
                    std::cout << (*pData) << ", ";
                    ++pData;
                }
                std::cout << std::endl;
            }
            std::cout << std::endl;
        }

        // peform the transform
        ippInit();

        // set up input
        IpprVolume inVolume;
        inVolume.width = inX;
        inVolume.height = inY;
        inVolume.depth = inZ;
        
        IpprCuboid inVoi;
        inVoi.x = 0;
        inVoi.y = 0;
        inVoi.z = 0;
        inVoi.width = inX;
        inVoi.height = inY;
        inVoi.depth = inZ;

        // set up output
        IpprCuboid outVoi;
        outVoi.x = 0;
        outVoi.y = 0;
        outVoi.z = 0;
        outVoi.width = outX;
        outVoi.height = outY;
        outVoi.depth = outZ;

        int inStepBytes = inX * sizeof(short);
        int outStepBytes = outX * sizeof(short);

        // set up identity matrix transform
        double coeffs[3][4];
        coeffs[0][0] = 1;
        coeffs[0][1] = 0;
        coeffs[0][2] = 0;
        coeffs[0][3] = 0;
        coeffs[1][0] = 0;
        coeffs[1][1] = 1;
        coeffs[1][2] = 0;
        coeffs[1][3] = 0;
        coeffs[2][0] = 0;
        coeffs[2][1] = 0;
        coeffs[2][2] = 1;
        coeffs[2][3] = 0;
        
        int inVoxelsPerSlice = inX * inY;
        int outVoxelsPerSlice = outX * outY;

        // set up vectors of slice pointers
        std::vector pInSlices(inZ);
        std::vector pOutSlices(outZ);
        for (int slice = 0; slice < inZ; ++slice)
        {
            pInSlices[slice] = (Ipp16u *)(inData + (slice * inVoxelsPerSlice));
        }
        for (int slice = 0; slice < outZ; ++slice)
        {
            pOutSlices[slice] = (Ipp16u *)(outData + (slice + outVoxelsPerSlice));
        }

        // create work buffer
        int bufferSize = 0;
        IppStatus status = ipprWarpAffineGetBufSize(inVoi, outVoi, 1, IPPI_INTER_NN, &bufferSize);
        Ipp8u *pBuffer = ippsMalloc_8u(bufferSize);

        // perform the transform
        status = ipprWarpAffine_16u_C1PV(&(pInSlices[0]), inVolume, inStepBytes, inVoi,
            &(pOutSlices[0]), outStepBytes, outVoi, coeffs, IPPI_INTER_NN, pBuffer);

        if (status != ippStsNoErr)
        {
            std::cout << "ipprWarpAffine_16u_C1PV failed with error code: " << (int)status << std::endl;
        }
        else
        {
            std::cout << "ipprWarpAffine_16u_C1PV success" << std::endl;
        }

        // print output data
        pData = outData;
        std::cout << "Output Data:" << std::endl;
        for (int z = 0; z < outZ; ++z)
        {
            for (int y = 0; y < outY; ++y)
            {
                for (int x = 0; x < outX; ++x)
                {
                    std::cout << (*pData) << ", ";
                    ++pData;
                }
                std::cout << std::endl;
            }
            std::cout << std::endl;
        }

        // clean up memory
        delete [] inData;
        delete [] outData;
        ippsFree(pBuffer);
    }
    catch (...)
    {
        std::cout << "Exception during test" << std::endl;
    }

    return;
}

int _tmain(int argc, _TCHAR* argv[])
{
    testIpp(8, 8, 8, 8, 8, 8);
    return 0;
}

[/cpp]


// ----------------------------------- sample output

[plain]inX, inY, inZ = 8, 8, 8
outX, outY, outZ = 8, 8, 8

Input Data:
1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 

2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 2, 

3, 3, 3, 3, 3, 3, 3, 3, 
3, 3, 3, 3, 3, 3, 3, 3, 
3, 3, 3, 3, 3, 3, 3, 3, 
3, 3, 3, 3, 3, 3, 3, 3, 
3, 3, 3, 3, 3, 3, 3, 3, 
3, 3, 3, 3, 3, 3, 3, 3, 
3, 3, 3, 3, 3, 3, 3, 3, 
3, 3, 3, 3, 3, 3, 3, 3, 

4, 4, 4, 4, 4, 4, 4, 4, 
4, 4, 4, 4, 4, 4, 4, 4, 
4, 4, 4, 4, 4, 4, 4, 4, 
4, 4, 4, 4, 4, 4, 4, 4, 
4, 4, 4, 4, 4, 4, 4, 4, 
4, 4, 4, 4, 4, 4, 4, 4, 
4, 4, 4, 4, 4, 4, 4, 4, 
4, 4, 4, 4, 4, 4, 4, 4, 

5, 5, 5, 5, 5, 5, 5, 5, 
5, 5, 5, 5, 5, 5, 5, 5, 
5, 5, 5, 5, 5, 5, 5, 5, 
5, 5, 5, 5, 5, 5, 5, 5, 
5, 5, 5, 5, 5, 5, 5, 5, 
5, 5, 5, 5, 5, 5, 5, 5, 
5, 5, 5, 5, 5, 5, 5, 5, 
5, 5, 5, 5, 5, 5, 5, 5, 

6, 6, 6, 6, 6, 6, 6, 6, 
6, 6, 6, 6, 6, 6, 6, 6, 
6, 6, 6, 6, 6, 6, 6, 6, 
6, 6, 6, 6, 6, 6, 6, 6, 
6, 6, 6, 6, 6, 6, 6, 6, 
6, 6, 6, 6, 6, 6, 6, 6, 
6, 6, 6, 6, 6, 6, 6, 6, 
6, 6, 6, 6, 6, 6, 6, 6, 

7, 7, 7, 7, 7, 7, 7, 7, 
7, 7, 7, 7, 7, 7, 7, 7, 
7, 7, 7, 7, 7, 7, 7, 7, 
7, 7, 7, 7, 7, 7, 7, 7, 
7, 7, 7, 7, 7, 7, 7, 7, 
7, 7, 7, 7, 7, 7, 7, 7, 
7, 7, 7, 7, 7, 7, 7, 7, 
7, 7, 7, 7, 7, 7, 7, 7, 

8, 8, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 

ipprWarpAffine_16u_C1PV success
Output Data:
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 

1, 2, 3, 4, 5, 6, 7, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 

8, 8, 8, 8, 8, 8, 8, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 

0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 

0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 

0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 

0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 

0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 

[/plain]
0 Kudos
3 Replies
Matthew_Holladay
Beginner
789 Views
Ahh, never mind. Found the problem... This:
  1. for(intslice=0;slice
  2. {
  3. pOutSlices[slice]=(Ipp16u*)(outData+(slice+outVoxelsPerSlice));
  4. }
Needs to be:
  1. for(intslice=0;slice
  2. {
  3. pOutSlices[slice]=(Ipp16u*)(outData+(slice * outVoxelsPerSlice));
  4. }
I must have looked at that 100 times before I finally saw the problem.
0 Kudos
SergeyKostrov
Valued Contributor II
789 Views
Hi Matthew,
Actually,in about12 minutes you've found the problem! :)
Best regards,
Sergey
0 Kudos
Matthew_Holladay
Beginner
789 Views
Actually 24 hours plus 12 minutes. :-)
Pulling my hair out the whole time...

Regards,
-- matt
0 Kudos
Reply