我希望在我确定的坐标上将图像放置在捕获的视频帧上。
我之前询问过,被告知使用
我之前询问过,被告知使用
cvCopy
和cvSetImageROI
,但我不想在这些坐标上裁剪,而是要添加另一张图片。也许这是正确的方法,但我没明白(如果是正确的,请解释一下)。cvCopy
和cvSetImageROI
,但我不想在这些坐标上裁剪,而是要添加另一张图片。也许这是正确的方法,但我没明白(如果是正确的,请解释一下)。我之前用SetRoi完成了这个操作,大致如下。我有两张图片,一张缩略图名为thumb_frame,它是我要在展示图片show_frame中包含的小图。
//I set the ROI to the same size as the thumb_frame
cvSetImageROI(show_frame.image, cvRect(thumbnail_x_pos,
thumbnail_y_pos, thumb_frame->width, thumb_frame->height));
//I add the image to the designated ROI
cvAddWeighted(thumb_frame, alpha, show_frame, beta, 0, show_frame);
void cvOverlayImage(IplImage* src, IplImage* overlay, CvPoint location, CvScalar S, CvScalar D)
{
int x,y,i;
for(x=0;x < overlay->width -10;x++)
//replace '-10' by whatever x position you want your overlay image to begin.
//say '-varX'
{
if(x+location.x>=src->width) continue;
for(y=0;y < overlay->height -10;y++)
//replace '-10' by whatever y position you want your overlay image to begin.
//say '-varY'
{
if(y+location.y>=src->height) continue;
CvScalar source = cvGet2D(src, y+location.y, x+location.x);
CvScalar over = cvGet2D(overlay, y, x);
CvScalar merged;
for(i=0;i<4;i++)
merged.val[i] = (S.val[i]*source.val[i]+D.val[i]*over.val[i]);
cvSet2D(src, y+location.y, x+location.x, merged);
}
}
}
使用它
cvOverlayImage(largerimage, overlayimage, cvPoint(10, 10), cvScalar(0.5,0.5,0.5,0.5), cvScalar(0.5,0.5,0.5,0.5));
//The cvPoint(10,10) can be the cvPoint(varX,varY) depending on how you write the function
//and how you want to use it.
//You cannot choose values less than 'varX' and 'varY' in this case
//else you would see a runtime error.
你需要逐像素地从源图像复制到目标图像。下面的代码正是这样做的,使用坐标x
和y
进行偏移。我实际上还没有尝试过这个方法,但我相当确定它应该能够按照你的预期工作。
只要确保目标图像的大小至少等于源图像加上偏移量即可!
void drawImage(IplImage* target, IplImage* source, int x, int y) {
for (int ix=0; x<source->width; x++) {
for (int iy=0; y<source->height; y++) {
int r = cvGet2D(source, iy, ix).val[2];
int g = cvGet2D(source, iy, ix).val[1];
int b = cvGet2D(source, iy, ix).val[0];
CvScalar bgr = cvScalar(b, g, r);
cvSet2D(target, iy+y, ix+x, bgr);
}
}
}
IplImage
复制到目标上,否则不需要任何额外的循环。 - Paul LammertsmaIplImage
即可实现。本质上,您需要做的是将捕获的视频作为“目标”,要叠加的图像作为“源”,并指定您想要在视频上放置图像的“x”和“y”偏移量。由于目标视频是通过指针传递的,因此在调用drawImage()
后,您可以继续处理捕获的视频帧。 - Paul Lammertsma很不幸,“Paul Lammertsma”代码在这里混淆了索引,这是修正后的代码:
void drawImage(IplImage* target, IplImage* source, int x, int y) {
for (int ix=0; ix<source->width; ix++) {
for (int iy=0; iy<source->height; iy++) {
int r = cvGet2D(source, iy, ix).val[2];
int g = cvGet2D(source, iy, ix).val[1];
int b = cvGet2D(source, iy, ix).val[0];
CvScalar bgr = cvScalar(b, g, r);
cvSet2D(target, iy+y, ix+x, bgr);
}
}
}