alpha混合的数学原理与实现
玩davinci的人都知道,视频处理后端(视频图像显示)中的attribute层,是VIDEO1和OSD0的alpha混合,是framebuffer的驱动实现的这种效果。
unsigned char *data1, *data2, *data3;
int i, j, k;
double alpha;
IplImage *img1, *img2, *img3;
img1 = cvLoadImage("img1.jpg", CV_LOAD_IMAGE_COLOR);
img2 = cvLoadImage("img2.jpg", CV_LOAD_IMAGE_COLOR);
img3 = cvCreateImage(cvGetSize(img1), img1->depth, img1->nChannels);
cvNamedWindow("win1", 1);
cvNamedWindow("win2", 1);
cvNamedWindow("win3", 1);
// img process
data1 = (unsigned char *)img1->imageData;
data2 = (unsigned char *)img2->imageData;
data3 = (unsigned char *)img3->imageData;
alpha = 0.6;
for(i=0;i<img1->height;i++)
{
for(j=0;j<img1->width;j++)
{
for(k=0;k<img1->nChannels;k++)
{
data3[i*img1->widthStep+j*img1->nChannels+k] = (unsigned char)(alpha*data2[i*img1->widthStep+j*img1->nChannels+k] + \
(1-alpha)*data1[i*img1->widthStep+j*img1->nChannels+k]);
}
}
}
//show image and free image
cvShowImage("win1", img1);
cvShowImage("win2", img2);
cvShowImage("win3", img3);
cvWaitKey(0);
cvReleaseImage(&img1);
cvReleaseImage(&img2);
cvReleaseImage(&img3);
cvDestroyWindow("win1");
cvDestroyWindow("win2");
cvDestroyWindow("win3");
alpha混合技术,主要是用于实现半透明的效果, 假设一种不透明东西的颜色是A(即VIDEO1),另一种透明的东西的颜色是B(即OSD0),那么透过B去看A,看上去的颜色C(即attribute)就是B和A的混合颜色,可以用下面的式子来近似,设B物体的透明度为alpha(取值为0~1之间的浮点数,0为完全透明,1为完全不透明)[1]。
R(C)=alpha*R(B)+(1-alpha)*R(A)
G(C)=alpha*G(B)+(1-alpha)*G(A)
B(C)=alpha*B(B)+(1-alpha)*B(A)
alpha混合可以实现火光、烟雾、阴影、动态光源等等一切你可以想象的出来的半透明效果,具体思想参考[1]。
下面给出实现alpha混合的OpenCV代码,取alpha为0.4、0.6时,alpha混合效果如下图。
源代码:
IDE:vc6
- unsigned char *data1, *data2, *data3;
- int i, j, k;
- double alpha;
- IplImage *img1, *img2, *img3;
- img1 = cvLoadImage("img1.jpg", CV_LOAD_IMAGE_COLOR);
- img2 = cvLoadImage("img2.jpg", CV_LOAD_IMAGE_COLOR);
- img3 = cvCreateImage(cvGetSize(img1), img1->depth, img1->nChannels);
- cvNamedWindow("win1", 1);
- cvNamedWindow("win2", 1);
- cvNamedWindow("win3", 1);
- // img process
- data1 = (unsigned char *)img1->imageData;
- data2 = (unsigned char *)img2->imageData;
- data3 = (unsigned char *)img3->imageData;
- alpha = 0.6;
- for(i=0;i<img1->height;i++)
- {
- for(j=0;j<img1->width;j++)
- {
- for(k=0;k<img1->nChannels;k++)
- {
- data3[i*img1->widthStep+j*img1->nChannels+k] = (unsigned char)(alpha*data2[i*img1->widthStep+j*img1->nChannels+k] + \
- (1-alpha)*data1[i*img1->widthStep+j*img1->nChannels+k]);
- }
- }
- }
- //show image and free image
- cvShowImage("win1", img1);
- cvShowImage("win2", img2);
- cvShowImage("win3", img3);
- cvWaitKey(0);
- cvReleaseImage(&img1);
- cvReleaseImage(&img2);
- cvReleaseImage(&img3);
- cvDestroyWindow("win1");
- cvDestroyWindow("win2");
- cvDestroyWindow("win3");
参考:
[1] http://dev.gameres.com/Program/Visual/2D/AlphaQiantan.htm