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

Perspective Warping coefficient errors

petemoss
Beginner
464 Views
I am trying to use ippiWarpPerspective to warp from one arbitrary quad to another. If I calculate the transform coefficients myself, and pass them in to WarpPerspective, I get a ippStsCoeffErr returned, indicating invalid coefficients. I know the transform is good, because I can successfully map points through it.

If I instead use ippiWarpPerspectiveQuad, and give it the 2 quads directly, it works fine and gives me no problems. But it also doesnt give me the coeffs for the transform. And I need to store the transform for later use.

Does anyone out there have any insight on what would invalidate the coeffs given to WarpPerspective? I am stumped on why it fails when WarpPerspectiveQuad works, and the error returned is not very informative.

Thanks in advance
Pete
0 Kudos
5 Replies
petemoss
Beginner
464 Views
Well, I will partially answer my own question. Has Intel abandoned these forums?

I used ippmQRDecomp and ippmQRBackSubst to generate a quad to quad transform matrix that WarpPerspective will accept without error. However, it is still slightly different than the coefficients that GetPerspectiveTransform generates. Can anyone describe the method the GetPerspectiveTransform uses to generate its coefficients? It is odd that the coefficients it generates have a value greater than 1 in coeffs[2][2], when the QR Decomp method requires settings that element to 1.0.

Now for a feature request: could Intel make a new transform generator, say GetPerspectiveTransformQuadToQuad? Rather than mapping a rect to a quad, this new function would map one quad to another.
WarpPerspectiveQuad is useless for such a task, as it only maps pixels within the source quad, not those within the src ROI.

0 Kudos
Vladimir_Dudnik
Employee
464 Views
Hello,

what version of IPP do you use? Did you have a look at IPP documentation for functions you are interested in?

Note, you can submit your feature request through Intel Premier Support where it will be reviewed at the next IPP version planning stage.

Regards,
Vladimir
0 Kudos
Yuri_Tikhomirov__Int
New Contributor I
464 Views

Hi Pete,

Could you give me information about your coefficient values? What are the parameters of ippiWarpPerspective functions?

Thanks,
Yuri
0 Kudos
petemoss
Beginner
464 Views
Hi Thanks for replying,

I am running IPP 5.1, but am in the process of upgrading to 6.0.

I have a set of coefficients that are failing. They are:
{ -0.21229439963447044, -3.1952057934942384, 6143.4751932121098,
-0.061480970976556061, -0.68851840755310234, 1346.6652439707534,
-4.7327858506523429e-005, -0.00051703559721577228, 1.0000000000000000 }

These coefficients should be mapping the quad:
446, 1700
566, 1720
359. 1760
71, 1759

to quad:
6174, 1488
6287, 1521
6075, 1545
5827, 1505

(point values are truncated from more precise doubles)

If I use that transform to map those points by hand, then the transform works just fine. But if I pass the coeffs to WarpPerspective, then it returns ippStsCoeffErr.

My WarpPerspective call is:
ippiWarpPerspective_8u_C3R( img2, srcRoi, img2_step, srcRect, canvas, canvas_step, dstRect, coeffs, IPPI_INTER_LINEAR );

where:
img2 is type Ipp8u*
srcRoi is (4288, 2848)
img2_step is 12864
srcRect is (0, 0, 4288, 2848)
canvas is type Ipp8u*
canvas_step is 25728
dstRect is (0, 0, 8576, 5696)
coeffs is the same as above


Also, just for completeness, my code for generating the coeffs is:

QTransform CalcQuadToQuadTransform( QPolygonF& quad1, QPolygonF& quad2 )
{
double A[8*8] = {
quad1.at(0).x(), quad1.at(0).y(), 1, 0, 0, 0, -quad1.at(0).x()*quad2.at(0).x(), -quad1.at(0).y()*quad2.at(0).x(),
quad1.at(1).x(), quad1.at(1).y(), 1, 0, 0, 0, -quad1.at(1).x()*quad2.at(1).x(), -quad1.at(1).y()*quad2.at(1).x(),
quad1.at(2).x(), quad1.at(2).y(), 1, 0, 0, 0, -quad1.at(2).x()*quad2.at(2).x(), -quad1.at(2).y()*quad2.at(2).x(),
quad1.at(3).x(), quad1.at(3).y(), 1, 0, 0, 0, -quad1.at(3).x()*quad2.at(3).x(), -quad1.at(3).y()*quad2.at(3).x(),
0, 0, 0, quad1.at(0).x(), quad1.at(0).y(), 1, -quad1.at(0).x()*quad2.at(0).y(), -quad1.at(0).y()*quad2.at(0).y(),
0, 0, 0, quad1.at(1).x(), quad1.at(1).y(), 1, -quad1.at(1).x()*quad2.at(1).y(), -quad1.at(1).y()*quad2.at(1).y(),
0, 0, 0, quad1.at(2).x(), quad1.at(2).y(), 1, -quad1.at(2).x()*quad2.at(2).y(), -quad1.at(2).y()*quad2.at(2).y(),
0, 0, 0, quad1.at(3).x(), quad1.at(3).y(), 1, -quad1.at(3).x()*quad2.at(3).y(), -quad1.at(3).y()*quad2.at(3).y(),
};
double QR[8*8];
double buf[8];
IppStatus st = ippmQRDecomp_m_64f( A, 8*sizeof(double), sizeof(double), buf, QR, 8*sizeof(double), sizeof(double), 8, 8 );

double b[8] = { quad2.at(0).x(), quad2.at(1).x(), quad2.at(2).x(), quad2.at(3).x(), quad2.at(0).y(), quad2.at(1).y(), quad2.at(2).y(), quad2.at(3).y() };
double x[8];
st = ippmQRBackSubst_mv_64f( QR, 8*sizeof(double), sizeof(double), buf, b, sizeof(double), x, sizeof(double), 8, 8 );

QTransform tf( x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], 1.0 );
return tf.transposed();
}


We are using Qt in conjunction with IPP, so the coeffs get stored as QTransforms, which are transposed with respect to IPP. Also, the input quads are stored in QPolygonFs, where the .at( ) method acts like the array accessor [].

I will note that if I compare my generated coeffs to what GetPerspectiveTransform returns, there are differences. Most notably, the last coeff is always 1.0 in my code, but is not equal to 1.0 in the coeffs from GetPerspectiveTransform. If GetPerspectiveTransform uses QR decomposition to calculate these, then there must be a bug there. That said, GetPerspectiveTransform has always worked for me when transforming a rect to a quad. Too bad there is not quad to quad calculator. I will add that as a feature request.

I hope that is enough information. Let me know if you need anything else. I am quite perplexed by this problem, and it is really holding me up from finishing this project.

Pete
0 Kudos
petemoss
Beginner
464 Views
Hello,

what version of IPP do you use? Did you have a look at IPP documentation for functions you are interested in?

Note, you can submit your feature request through Intel Premier Support where it will be reviewed at the next IPP version planning stage.

Regards,
Vladimir

Currently using 5.1, but in the process of upgrading to 6.0. I have read the docs many times, and have had quite some success with WarpPerspective in the past. It is only recntly where I have been warping from quad to quad where problems have appeared. Warping from rect to quad, the way GetPerspectiveTransform works, has never given me a problem. And using using WarpPerspectiveQuad works, but has the disadvantage that I dont know what coeffs it is using, and it only warps the pixels within a quad, not all the ones within the srcRect.

Thanks for the pointer on adding a feature request, I will do that right now. EDIT - I went to that link, and it sent me right back to this forum page. Is there something I can search for to add a feature request? I dont know where to go.

Pete

0 Kudos
Reply