计算图像帧的平均灰度值

来源:互联网 发布:lazada卖家数据分析 编辑:程序博客网 时间:2024/06/10 09:02


2016/7/15


在处理视频中,需要对视频流中的图像帧进行区分,分离出其中的亮暗帧图像。区分亮暗图像,是依据图像的平均灰度值来实现的。

 

我们知道,对于一幅灰度图像,每个像素点的灰度值可以通过指针来访问( i, j )处的灰度值

         (img->imageData+ i*img->widthStep)[j*img->nChannels+0]

当然,也可以通过cvGet2D()函数来获取该点的灰度值

         cvGet2D(img, i , j).val[0] 或者cvGetReal2D(img , i , j)

对于彩色图像,由于图像具有R/G/B三个通道,所以像素的颜色分量可以通过以下方式来访问:

蓝色通道

         (img->imageData+ i*img->widthStep)[j*img->nChannels+0]

绿色通道

         (img->imageData+ i*img->widthStep)[j*img->nChannels+1]

红色通道

         (img->imageData+ i*img->widthStep)[j*img->nChannels+2]

同理也可以通过函数来访问,如下所示:

蓝色通道

cvGet2D(img , i, j).val[0]

绿色通道

cvGet2D(img , i, j).val[1]

红色通道

cvGet2D(img , i, j).val[2]

一般取三个通道灰度值的平均值作为彩色三通道图像的灰度值

或者采用一种加权的浮点算法

Gray=R*0.299+G*0.587+B*0.114 

那么,对于求取整幅图像的平均灰度值,直接的方法就是遍历整幅图像的所有像素点,累加求取所有像素点的灰度值总和,平均灰度值为灰度值总和与像素点个数之商,步骤如下

1)  遍历待处理的源图像src的像素;

2)  对每个像素点的灰度值进行累加求和sum;

3)  计算图像的像素点总个数:n = src->width*src->height;

4)  求图像的平均灰度值:avg_value = sum/n 。


 

函数代码:

 

/***求一副图像的平均灰度值*****/

double g_avg_pixel(IplImage *src )

{

    if(src==NULL)

        return -1;

    double g_avg_pixel=0;

    IplImage* dst=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);

    cvCvtColor(src, dst, CV_RGB2GRAY );//彩色转换为灰度图像;

    int width=dst->width;

    int height = dst->height;

    for (introw=0;row<height;row+=1)

    {

        for (intcols=0;cols<width;cols+=1)

        {

g_avg_pixel+=cvGet2D(dst,row,cols).val[0];

        }

    }

    g_avg_pixel=g_avg_pixel/(width*height);

    cvReleaseImage(&dst);//注意该处释放内存,否则循环调用函数时会导致Out Of Memory.

    return g_avg_pixel;

}

 

当然,还有另一种方法,是利用先将彩色图像转为灰度图像,再利用cvAvg()函数进行的。

double get_avg_gray(IplImage *img) 

    IplImage*gray = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1); 

   cvCvtColor(img,gray,CV_RGB2GRAY); 

    CvScalarscalar = cvAvg(gray); 

   cvReleaseImage(&gray); 

    return scalar.val[0]; 

 

与get_avg_gray()函数对应的set_avg_gray(),我也顺手写了。

void set_avg_gray(IplImage *img,IplImage *out,doubleavg_gray) 

    double prev_avg_gray = get_avg_gray(img); 

   cvConvertScale(img,out,avg_gray/prev_avg_gray); 

}

 下图为两种方法处理一段视频流的运行结果,可见g_avg_pixel()函数和get_avg_gray()函数计算结果的差异并不明显


0 0
原创粉丝点击