вообщем есть 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?