我从视频(1.)中捕获帧,并希望将此矩形区域作为子图像投影到目标图像中的检测区域(2.)。
目标图像(2.)中的区域不正交我已经具有在目标区域周围绘制线条的坐标(由单应性确定)。
是否有任何方法可以将源帧(3.)(例如使用双线性插值)复制到不同区域(4.)中的目标图像中?
我还需要翻译smaler(视频帧)图像。
答案 0 :(得分:2)
我认为您希望使用warpPerspective()
来实现此目标。首先使用getPerspectiveTransform()
获得适当的透视变换(您在问题中绘制的四边形不是平行四边形,因此仿射变换不会这样做)。该函数将视频帧的角点([0; 0] [0; frame.cols]等)的像素坐标和您在目标区域中绘制的线的角的像素坐标作为输入参数。
现在您已进行转换,请将其与warpPerspective()
一起使用,将视频帧扭曲为目标图像大小的空白图像。使用带有ROI掩码的复制操作(例如FrankH描述的那些)将扭曲区域插入到实际目标图像中。
答案 1 :(得分:2)
该图阐明了确切的需求。这样的事情应该做:
void warpVideoToQuad(
IplImage *videoFrame,
IplImage *target,
CvSeq *tgt_quad)
{
int width = videoFrame->width, height = videoFrame->height;
CvPoint2D32f src_rect[] =
{ { 0.0, 0.0 }, { 0.0, height }, { width, height }, { width, 0.0 } };
CvPoint2D32f dst_quad[4];
// a little kludgy as cvGetPerspectiveTransform() and cvBoundingRect()
// use different arg types - the former a point array the latter a seq
cvCvtSeqToArray(tgt_quad, dst_quad);
CvMat *warper = cvCreateMat(3,3,CV_32FC1);
CvRect tgt_rect = cvBoundingRect(tgt_quad);
IplImage *warpTgt = cvCreateImage(CvSize(tgt_rect.width, tgt_rect.height),
videoFrame->depth, videoFrame->nChannels);
cvZero(warpTgt);
cvGetPerspectiveTransform(src_rect, dst_quad, &warper);
cvGetQuadrangleSubPix(videoFrame, warpTgt, warper);
cvSetImageROI(target, tgt_rect);
cvCopy(warpTgt, target, warpTgt);
cvResetImageROI(target);
delete warpTgt;
delete warper;
}
我现在无法测试,所以只是为了说明。稍后将进行适当的编辑。