вообщем есть 2 функции одна двигает углы изображения, другая делает преобразование подушка\бочка, хотелось бы объединить их сразу в 1 через remap чтобы выполнялось быстрей.вообще даже скорей вопрос как фун-ию warp_patch запихнуть в рамки mapx,mapy.
похожий вопрос тут обсуждается http://tech.groups.yahoo.com/group/OpenCV/message/40225
IplImage* warp_patch(IplImage* src, std::vector<coor> vec, bool crop)
{
CvPoint2D32f srcQuad[4], dstQuad[4];
CvMat* warp_matrix = cvCreateMat(3,3,CV_32FC1);
IplImage* dst= NULL;
IplImage* src_ext= NULL;
//src координаты
srcQuad[0].x = 0; //src Top left
srcQuad[0].y = 0;
srcQuad[1].x = src->width-1; //src Top right
srcQuad[1].y = 0;
srcQuad[2].x = 0; //src Bottom left
srcQuad[2].y = src->height-1;
srcQuad[3].x = src->width-1; //src Bot right
srcQuad[3].y = src->height-1;
//отрицательные значения cx налево
// cy вверх
if (vec.size()!=4) //проверка вектора на содержание 4 углов
return NULL;
int dx= abs(MIN(vec[0].x,vec[2].x))+MAX(vec[1].x,vec[3].x);
int dy= abs(MIN(vec[0].y,vec[1].y))+MAX(vec[2].y,vec[3].y);
dst= cvCreateImage(cvSize(src->width+dx,src->height+dy),IPL_DEPTH_8U,3);
src_ext= cvCreateImage(cvSize(src->width+dx,src->height+dy),IPL_DEPTH_8U,3);//из-за требования на одинаковый размер src и dst в cvWarpPerspective
cvSetImageROI(src_ext,cvRect(0,0,src->width,src->height));
cvResetImageROI(src);
cvCopy(src,src_ext);
//1 сторона 0 2
if (vec[0].x<vec[2].x)
{
if(vec[0].x<0)
{
dstQuad[0].x= 0;
dstQuad[2].x= vec[2].x+abs(vec[0].x);
}
else
{
dstQuad[0].x= 0;
dstQuad[2].x= vec[2].x-vec[0].x;
}
}
else
{
if(vec[0].x<0)
{
dstQuad[0].x= vec[0].x-(vec[0].x);
dstQuad[2].x= 0;
}
else
{
dstQuad[0].x= vec[0].x-vec[2].x;
dstQuad[2].x= 0;
}
}
//2 сторона 0 1
if (vec[0].y<vec[1].y)
{
if(vec[0].y<0)
{
dstQuad[0].y= 0;
dstQuad[1].y= vec[1].y+abs(vec[0].y);
}
else
{
dstQuad[0].y= 0;
dstQuad[1].y= vec[1].y-vec[0].y;
}
}
else
{
if(vec[0].y<0)
{
dstQuad[0].y= vec[0].y-(vec[0].y);
dstQuad[1].y= 0;
}
else
{
dstQuad[0].y= vec[0].y-vec[1].y;
dstQuad[1].y= 0;
}
}
//3 сторона 1 3
dstQuad[1].x= abs(MIN(vec[0].x,vec[2].x))+src->width-1+vec[1].x;
dstQuad[3].x= abs(MIN(vec[0].x,vec[2].x))+src->width-1+vec[3].x;
//4 сторона 2 3
dstQuad[2].y= abs(MIN(vec[0].y,vec[1].y))+src->height-1+vec[2].y;
dstQuad[3].y= abs(MIN(vec[0].y,vec[1].y))+src->height-1+vec[3].y;
cvGetPerspectiveTransform(srcQuad,dstQuad,warp_matrix);
cvWarpPerspective( src_ext, dst, warp_matrix );
if (crop) // обрезается максимальный вписаный прямоугольник
{
int cx1= MAX(dstQuad[0].x,dstQuad[2].x);
int cx2= MIN(dstQuad[1].x,dstQuad[3].x);
int cy1= MAX(dstQuad[0].y,dstQuad[1].y);
int cy2= MIN(dstQuad[2].y,dstQuad[3].y);
IplImage* dst_crop= cvCreateImage(cvSize(cx2-cx1,cy2-cy1),IPL_DEPTH_8U,3);
cvSetImageROI(dst,cvRect(cx1,cy1,cx2-cx1,cy2-cy1));
cvCopy(dst,dst_crop);
return dst_crop;
}
else
{
return dst;
}
}
void barrel_pincusion_dist(IplImage* img, double kx, double ky)
{
IplImage* mapx = cvCreateImage( cvGetSize(img), IPL_DEPTH_32F, 1 );
IplImage* mapy = cvCreateImage( cvGetSize(img), IPL_DEPTH_32F, 1 );
int w= img->width;
int h= img->height;
int Cx= w/2;
int Cy= h/2;
for (int y = 0; y < h; y++)
{
int ty= y-Cy;
for (int x = 0; x < w; x++)
{
int tx= x-Cx;
int rt= tx*tx+ty*ty;
double u= tx*(1+kx*rt)+Cx;
cvSetReal2D(mapx, y, x, u);
}
}
for (int y = 0;y < h; y++)
{
int ty= y-Cy;
for (int x = 0; x < w; x++)
{
int tx= x-Cx;
int rt= tx*tx+ty*ty;
double v= ty*(1+ky*rt)+Cy;
cvSetReal2D(mapy, y, x, v);
}
}
IplImage* temp = cvCloneImage(img);
cvRemap( temp, img, mapx, mapy );
cvReleaseImage(&temp);
cvReleaseImage(&mapx);
cvReleaseImage(&mapy);
}
и еще может есть что побыстрей cvSetReal2D?