当拍摄真实场景照片时,有时会出现光照不均匀情况:亮区域会出现过曝光,而暗区域会欠曝光,因此无法通过一次曝光获取到所有图像细节。所以可以应用多次不同曝光值下所拍摄的照片进行曝光融合,HDR就是一种常用到曝光融合算法的拍摄技术。
通过对多幅图的灰度图下的平均灰度的计算来确定该幅图像在最终生成图像中所占的权值,公式大致如下
W e i g h t = ( Σ ∣ g r a y − 128 ∣ / ∣ g r a y − 128 ∣ ) / Σ ( Σ ∣ g r a y − 128 ∣ / ∣ g r a y − 128 ∣ ) Weight=(Σ|gray-128|/|gray-128|)/Σ(Σ|gray-128|/|gray-128|) Weight=(Σ∣gray−128∣/∣gray−128∣)/Σ(Σ∣gray−128∣/∣gray−128∣)
看上去非常复杂,他的推导在此不再赘述,我将以代码形式展现,
//通过灰度均值获取权值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 fileimage[1] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0062.jpg", 1); // Read the fileimage[2] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0063.jpg", 1); // Read the fileimage[3] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0064.jpg", 1); // Read the fileimage[4] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0065.jpg", 1); // Read the fileimage[5] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0066.jpg", 1); // Read the fileimage[6] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0067.jpg", 1); // Read the fileimage[7] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0068.jpg", 1); // Read the fileimage[8] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0069.jpg", 1); // Read the fileimage[9] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0070.jpg", 1); // Read the fileimage[10] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0071.jpg", 1); // Read the fileimage[11] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0071.jpg", 1); // Read the fileimage[12] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0073.jpg", 1); // Read the fileimage[13] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0074.jpg", 1); // Read the fileimage[14] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0075.jpg", 1); // Read the fileimage[15] = imread("C:/Users/Chen/Desktop/OpenCV_test/OpenCV_test/OpenCV_test/memorial0076.jpg", 1); // Read the fileMat 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 windowreturn 0;
}
在写完了这一堆之后,我突然想到了一些事情,除了传统的RGB图像采用的R,G,B三个颜色通道来表示图像,这对于其色彩有着较好的表示,但是,对于曝光处理来说并不是最优解,如果应用HSV图像中的S(饱和度)和V(明度)来进行该算法的实现或许效果会更加优秀,这个坑等过几天有些事情(指调车)处理完了再填吧。哦对,还有一条走过的弯路,在最开始的时候,我曾挨个像素的进行融合,结果效果并不佳,我思考了一下,感觉应该是因为仅针对单个像素处理,无法顾及到整个图像的效果。
长达好几个星期的数字图像处理终于是结束了,作为一个没有考试且实用性极强的科目,我非常的喜欢,我也非常喜欢张老师的上课方式,这种搭配实验的上课方式,让学到的知识很快就得到了应用。也很感谢张老师在我处理智能车比赛中一些图像处理的问题上给予的帮助。
本文发布于:2024-02-03 03:29:10,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170690215348362.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |