Geben Sie ein Ursprungs-zu warpPerspective () - Funktion in OpenCV 2.x
Ich versuche zu geben Sie eine andere Herkunft für die warpPerspective () - Funktion als die grundlegende (0,0), um die Transformation unabhängig von der Unterstützung der Bild-Größe. Ich habe ein CvPoint parameter der original-code, aber ich kann nicht finden, wo diese Koordinaten. Ich versuchte Sie zu nutzen, in die Berechnung von X0, Y0 und W0, aber es hat nicht funktioniert, diese nur verschieben, das transformierte Bild in der Bild. Irgendeine Idee?
Hier der code:
void warpPerspective( const Mat& src, Mat& dst, const Mat& M0, Size dsize,
int flags, int borderType, const Scalar& borderValue, CvPoint origin )
{
dst.create( dsize, src.type() );
const int BLOCK_SZ = 32;
short XY[BLOCK_SZ*BLOCK_SZ*2], A[BLOCK_SZ*BLOCK_SZ];
double M[9];
Mat _M(3, 3, CV_64F, M);
int interpolation = flags & INTER_MAX;
if( interpolation == INTER_AREA )
interpolation = INTER_LINEAR;
CV_Assert( (M0.type() == CV_32F || M0.type() == CV_64F) && M0.rows == 3 && M0.cols == 3 );
M0.convertTo(_M, _M.type());
if( !(flags & WARP_INVERSE_MAP) )
invert(_M, _M);
int x, y, x1, y1, width = dst.cols, height = dst.rows;
int bh0 = std::min(BLOCK_SZ/2, height);
int bw0 = std::min(BLOCK_SZ*BLOCK_SZ/bh0, width);
bh0 = std::min(BLOCK_SZ*BLOCK_SZ/bw0, height);
for( y = 0; y < height; y += bh0 )
{
for( x = 0; x < width; x += bw0 )
{
int bw = std::min( bw0, width - x);
int bh = std::min( bh0, height - y);
Mat _XY(bh, bw, CV_16SC2, XY), _A;
Mat dpart(dst, Rect(x, y, bw, bh));
for( y1 = 0; y1 < bh; y1++ )
{
short* xy = XY + y1*bw*2;
double X0 = M[0]*x + M[1]*(y + y1) + M[2];
double Y0 = M[3]*x + M[4]*(y + y1) + M[5];
double W0 = M[6]*x + M[7]*(y + y1) + M[8];
if( interpolation == INTER_NEAREST )
for( x1 = 0; x1 < bw; x1++ )
{
double W = W0 + M[6]*x1;
W = W ? 1./W : 0;
int X = saturate_cast<int>((X0 + M[0]*x1)*W);
int Y = saturate_cast<int>((Y0 + M[3]*x1)*W);
xy[x1*2] = (short)X;
xy[x1*2+1] = (short)Y;
}
else
{
short* alpha = A + y1*bw;
for( x1 = 0; x1 < bw; x1++ )
{
double W = W0 + M[6]*x1;
W = W ? INTER_TAB_SIZE/W : 0;
int X = saturate_cast<int>((X0 + M[0]*x1)*W);
int Y = saturate_cast<int>((Y0 + M[3]*x1)*W);
xy[x1*2] = (short)(X >> INTER_BITS);
xy[x1*2+1] = (short)(Y >> INTER_BITS);
alpha[x1] = (short)((Y & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE +
(X & (INTER_TAB_SIZE-1)));
}
}
}
if( interpolation == INTER_NEAREST )
remap( src, dpart, _XY, Mat(), interpolation, borderType, borderValue );
else
{
Mat _A(bh, bw, CV_16U, A);
remap( src, dpart, _XY, _A, interpolation, borderType, borderValue );
}
}
}
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ok, ich fand es selbst! Sie haben 2 Dinge zu tun:
Hier ist der code so verändert:
mit dieser Funktion:
int bw = std::min(bw0, width - x); int bh = std::min(bh0, height - y);
sollte ersetzt werden, mitint bw = std::min(bw0, width - xDest); int bh = std::min(bh0, height - yDest);
. Das funktioniert-für mich zumindest.Eine viel einfachere und sauberere Lösung ist die Veränderung der perspektivischen transformation. Sie können eine übersetzung, die verschiebt den Nullpunkt auf die gewünschte position, dann tun die perspektivische transformation und schließlich die inverse übersetzung.
Hier ist ein kleines Beispielprogramm in python, der dreht ein Bild um 45 Grad um den Punkt(100, 100):
Nicht, dass du dir die Reihenfolge der Transformationen von rechts nach Links.
gilt t1 zuerst, dann rot, und dann t2.
Für diejenigen, die für dieses Stück in Python, hier ist ein Anfang. Ich bin mir nicht 100% sicher, dass es funktioniert wie ich es ausgezogen habe einige Optimierungen aus. Auch gibt es ein Problem mit der linearen interpolation, die ich einfach nicht verwenden, aber möchten Sie vielleicht, um einen genaueren Blick nehmen, wenn Sie tun.