Advertisement

实验三 曝光融合

阅读量:

实验三 曝光融合

3.1 任务简介

当真实场景照片拍摄时常见出现光照不均现象:明亮区域经受过曝而在阴暗区域则未能达到理想亮度因此无法在单次曝光中捕捉全面细节此时可采用多组不同曝光度的照片进行融合处理而HDR技术正是基于这种融合原理广泛应用于现代高动态范围成像系统

3.2 算法实现

通过计算多幅图像在灰度处理后的平均亮度值来确定其在合成图像中的权重分配,
Weight=(Σ\frac{|gray - 128|}{|\text{ }gray - 128\text{ }|})/\sum(\sum\frac{|gray - 128|}{|\text{ }gray - 128\text{ }|})
看起来相当复杂,
具体推导过程在此从略,
代码实现将在后续部分呈现

复制代码
     //通过灰度均值获取权值
    float weight[16];
    float sum=0;
    float sum2=0;
    float yu[16];
    for (i = 0; i < 16; i++)
    {
        yu[i] = mean_gray[i] - 128;
        if (yu[i] < 0)
        {
            yu[i] = - yu[i];
        }
        sum += yu[i]; 
    }
    for (i = 0; i < 16; i++)
    {
        sum2 += sum / yu[i];
    }
    for (i = 0; i < 16; i++)
    {
        weight[i] =( sum / yu[i] )/sum2;
        cout << "权值" << weight[i];
    }

在讨论了灰度之后,我想简单介绍一下我是如何获取灰度的。在OpenCV库中存在一个名为meanStdDev()的函数,它的功能是计算矩阵的平均值和标准偏差。由于本次实验使用的图像为彩色图像,因此会返回一个三通道的数组。将这三个通道的数据相加并求其平均即可得到灰度平均值。代码的具体实现我也已经准备好了,并将在下方进行展示。

复制代码
    	Scalar     mean;
    	Scalar     stddev;
    	float mean_gray[16];  //灰度均值
    	//获取灰度均值
    	for (i = 0; i < 16; i++)
    {
        meanStdDev(image[i], mean, stddev);  //分别获取图的均值与方差,在本算法中仅使用了均值
        mean_gray[i] = (mean[0] + mean[1] + mean[2])/3;
        cout << "<----mean_pxl------>" << mean_gray[i] << "<-------stddev_pxl------->" << stddev[0] << endl;
    }

整个代码结构大致如上所示,在处理图片数据时,我的方法较为简单;这个部分还有待进一步优化

复制代码
    ```cpp
    int main(int argc, char** argv)
    {
    int i=0;
    Mat image[16];//定义一个图像数组用于存放待处理图像
     image[0] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0061.jpg", 1); // Read the file
     image[1] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0062.jpg", 1); // Read the file
     image[2] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0063.jpg", 1); // Read the file
     image[3] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0064.jpg", 1); // Read the file
     image[4] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0065.jpg", 1); // Read the file
     image[5] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0066.jpg", 1); // Read the file
     image[6] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0067.jpg", 1); // Read the file
     image[7] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0068.jpg", 1); // Read the file
     image[8] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0069.jpg", 1); // Read the file
     image[9] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0070.jpg", 1); // Read the file
     image[10] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0071.jpg", 1); // Read the file
     image[11] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0071.jpg", 1); // Read the file
     image[12] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0073.jpg", 1); // Read the file
     image[13] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0074.jpg", 1); // Read the file
     image[14] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0075.jpg", 1); // Read the file
     image[15] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0076.jpg", 1); // Read the file
    Mat output;
    Scalar     mean;
    Scalar     stddev;
    float mean_gray[16];  //灰度均值
    //获取灰度均值
    for (i = 0; i < 16; i++)
    {
        meanStdDev(image[i], mean, stddev);  //分别获取图的均值与方差,在本算法中仅使用了均值
        mean_gray[i] = (mean[0] + mean[1] + mean[2])/3;
        cout << "<----mean_pxl------>" << mean_gray[i] << "<-------stddev_pxl------->" << stddev[0] << endl;
    }
    //通过灰度均值获取权值
    float weight[16];
    float sum=0;
    float sum2=0;
    float yu[16];
    for (i = 0; i < 16; i++)
    {
        yu[i] = mean_gray[i] - 128;
        if (yu[i] < 0)
        {
            yu[i] = - yu[i];
        }
        sum += yu[i]; 
    }
    for (i = 0; i < 16; i++)
    {
        sum2 += sum / yu[i];
    }
    for (i = 0; i < 16; i++)
    {
        weight[i] =( sum / yu[i] )/sum2;
        cout << "权值" << weight[i];
    }
    output =  image[0] * weight[0]+ image[1] * weight[1]+ image[2] * weight[2]+ image[3] * weight[3]+ image[4] * weight[4]+ image[5] * weight[5]+ image[6] * weight[6]+ image[7] * weight[7]+ image[8] * weight[8]+ image[9] * weight[9]+ image[10] * weight[10]+ image[11] * weight[11]+17;
    /*output = output + image[12] * weight[12] + image[13] * weight[13] + image[14] * weight[14] + image[15] * weight[15]+7;
    */
    imshow("结果", output);
    waitKey(0);   // Wait for a keystroke in the window
    return 0;
    }

在完成后我又想到一些事情值得注意的是传统的RGB图像采用R G B三个颜色通道来表示图像这一方法对于色彩的表现具有较好的效果但就曝光处理而言并不是最佳方案如果转而采用HSV图像中的饱和度S与明度V来进行该算法的实现可能会获得更好的效果这个坑暂时先搁置待后续有其他事情处理后再加以解决值得一提的是在最初的探索过程中我也曾尝试一种像素级的融合方式但最终效果却不尽如人意经过一番思考我认为这可能源于该方法仅针对单个像素进行处理无法兼顾全局视觉效果

3.3 效果演示

图1  融合前
图2 融合后

3.4 总结

经过数周时间后,数字图像处理终于告一段落.这门课程既没有考试要求,又具有很强的实际应用价值.我对这门课程尤其喜爱,同时也非常赞赏张老师独特的教学风格.通过结合实验的方式教授,所学知识很快就能得到实践运用.同时,我也非常感谢张老师在指导我在智能车比赛中解决图像处理相关问题时给予的帮助和支持.

全部评论 (0)

还没有任何评论哟~