矩阵和图像操作(2)
这个函数可用来实现alpha 融合 [Smith79; Porter84];也就是说,它可以用于一个图像同另一个图像的融合,函数的形式如下:
- void cvAddWeighted(
- const CvArr* src1,
- double alpha,
- const CvArr* src2,
- double beta,
- double gamma,
- CvArr* dst
- );
在函数cvAddWeighted()中我们有两个源图像,分别是src1和src2。这些图像可以是任何类型的像素,只要它们属于同一类型即可。它们还可以有一个或三个通道(灰度或彩色),同样也要保持类型一致。结果图像dst,也必须同src1和src2是相同的像素类型。这些图像可能是不同尺寸,但是它们的ROI必须统一尺寸,否则OpenCV就会产生错误,参数alpha是src1的融合强度,beta是src2的融合强度,alpha融合公式如下:
可以通过设置α从0到1区间取值,β = 1 - α,γ为0,将前面公式转换为标准alpha融合方程。这就得出下式:
但是,在加权融合图像,以及目标图像的附加偏移参数γ方面, cvAddWeighted()提供了更大的灵活性。一般而言,你或许想让alpha和beta不小于0,并且两者之和不大于1,gamma的设置取决于像素所要调整到的平均或最大值。例3-14展示了alpha融合的用法。
例3-14:src2 中alpha融合ROI以(0,0)开始,src1 中ROI以(x,y)开始
- // alphablend <imageA> <image B> <x> <y> <width> <height>
- // <alpha> <beta>
- #include <cv.h>
- #include <highgui.h>
- int main(int argc, char** argv)
- {
- IplImage *src1, *src2;
- if( argc == 9 && ((src1=cvLoadImage(argv[1],1)) != 0
- )&&((src2=cvLoadImage(argv[2],1)) != 0 ))
- {
- int x = atoi(argv[3]);
- int y = atoi(argv[4]);
- int width = atoi(argv[5]);
- int height = atoi(argv[6]);
- double alpha = (double)atof(argv[7]);
- double beta = (double)atof(argv[8]);
- cvSetImage ROI(src1, cvRect(x,y,width,height));
- cvSetImageROI(src2, cvRect(0,0,width,height));
- cvAddWeighted(src1, alpha, src2, beta,0.0,src1);
- cvResetImageROI(src1);
- cvNamedWindow( "Alpha_blend", 1 );
- cvShowImage( "Alpha_blend", src1 );
- cvWaitKey();
- }
- return 0;
- }
【51~52】
例3-14中的代码用两个源图像:初始的(src1)和待融合的(src2)。它从矩形的ROI中读取src1,然后将同样大小的ROI应用到src2中,这一次设在原始位置,它从命令行读入alpha和beta的级别但是把gamma设为0。Alpha融合使用函数cvAddWeighted(),结果被放到src1并显示,例子输出如图3-4所示,一个小孩的脸同一个猫的脸和身体被融合到了一起,值得注意的是,代码采用相同的ROI,像图3-3的例子一样。这次我们使用了ROI作为目标融合区域。
(点击查看大图)图3-4:一个小孩的脸被alpha融合到一只猫的脸上 |
- void cvAnd(
- const CvArr* src1,
- const CvArr* src2,
- CvArr* dst,
- const CvArr* mask = NULL
- );
- void cvAndS(
- const CvArr* src1,
- CvScalar value,
- CvArr* dst,
- const CvArr* mask = NULL
- );
这两个函数在src1数组上做按位与运算,在cvAnd()中每个dst元素都是由相应的src1和src2两个元素进行位与运算得出的。在cvAndS()中,位与运算由常标量value得出。同一般函数一样,如果mask是非空,就只计算非0 mask元素所对应的dst元素。
尽管支持所有的数据类型,但是对于cvAnd()来说,src1和src2要保持相同的数据类型。如果元素都是浮点型的,则使用该浮点数的按位表示。【52】