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

ipprWarpAffine not producing expected results in IPP 7.0 Update 5

Matthew_Holladay
Beginner
390 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
390 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
390 Views
Hi Matthew,
Actually,in about12 minutes you've found the problem! :)
Best regards,
Sergey
0 Kudos
Matthew_Holladay
Beginner
390 Views
Actually 24 hours plus 12 minutes. :-)
Pulling my hair out the whole time...

Regards,
-- matt
0 Kudos
Reply