博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OpenCV多曝光合成算法之熵值最大块合成
阅读量:3905 次
发布时间:2019-05-23

本文共 3452 字,大约阅读时间需要 11 分钟。

OpenCV多曝光合成算法

本文使用多曝光对应区块内的熵值大小来分配不同大小的权重,最后线性合成为新区块,从而实现使得曝光合成图片具备最多的LDR细节,代替由于硬件或者软件限制而无法实现的HDR效果。

#include 
#include
using namespace cv;using namespace std;#define BLOCK 50//求熵 函数float entropy(Mat m){
float sum = 0; float histogram[3][256] = {
0};//3个通道,每个通道256个像素级别。 int one; int n = m.rows * m.cols; for (int k = 0; k < 3; k++) {
for (int i = 0; i < m.rows; i++) {
for (int j = 0; j < m.cols; j++) {
one = int (m.at
(i, j)[k]); histogram[k][one]++; } } } //开始计算图像熵 for (int i = 0; i < 3; i++) {
for (int j = 0; j < 256; j++) {
histogram[i][j] /= n; if (histogram[i][j] != 0)sum += (-histogram[i][j]) * log(histogram[i][j]); } } return sum;}//选取熵最大的图像块最大的权重输出Mat entropy_max(Mat a,Mat b,Mat c){
float ans_a = entropy(a),ans_b = entropy(b), ans_c = entropy(c); if ((ans_a > ans_b && ans_a > ans_c)) {
if (ans_b>ans_c)return 0.6 * a + 0.3 * b + 0.1 * c; else return 0.6 * a + 0.3 * c + 0.1 * b; } if ((ans_b > ans_a && ans_b > ans_c)) {
if (ans_a > ans_c)return 0.6 * b + 0.3 * a + 0.1 * c; else return 0.6 * b + 0.3 * c + 0.1 * a; } if ((ans_c > ans_b && ans_c > ans_a)) {
if (ans_a > ans_b)return 0.6 * c + 0.3 * a + 0.1 * b; else return 0.6 * c + 0.3 * b + 0.1 * a; }}//融合函数Mat fusion(Mat src_OE,Mat src_UE, Mat src_ME,int block){
//创建一个Mat类型out_ROI Mat out_ROI_ue,out_ROI_oe, out_ROI_me; //输出暂存块。 out_ROI_ue = Mat(block, block, CV_8UC3); out_ROI_oe = Mat(block, block, CV_8UC3); out_ROI_me = Mat(block, block, CV_8UC3); Mat out_ROI;//计算出的熵比较高的那一块 out_ROI = Mat(block, block, CV_8UC3); Mat out;//创建对象 out = src_ME;//输出对象 //创建每次循环的处理区域work_ROI,并初始化坐标极其宽度高度 Rect work_ROI; work_ROI.x = 0;//矩形左上角横坐标 work_ROI.y = 0;//矩形左上角纵坐标 work_ROI.width = block;//矩形宽为block work_ROI.height = block;//矩形高为block //原图像ROI位置以及大小Rect类型储存 for (int j = 0; j < src_OE.cols / block; j++)//外层循环循环原图列数/block 次 {
for (int i = 0; i < src_OE.rows / block; i++) //内层循环原图行数/block 次 {
//rect_ROI坐标转换到下一个矩形区块。 work_ROI.x = block * i;//工作区域向后移动block个像素 work_ROI.y = block * j;//工作区域向后移动block个像素 //比较三张图的熵的最大值 out_ROI_oe = src_OE(work_ROI); out_ROI_ue = src_UE(work_ROI); out_ROI_me = src_ME(work_ROI); out_ROI = entropy_max(out_ROI_ue, out_ROI_oe,out_ROI_me);//把熵最大的这一块赋给out_ROI //把这一块填充到out的这一个部分里面 out_ROI.copyTo(out(work_ROI)); } } return out;}int main(){
Mat src_OE = imread("C:\\Users\\hl\\Desktop\\oe2.jpg", IMREAD_COLOR); Mat src_UE = imread("C:\\Users\\hl\\Desktop\\ue2.jpg", IMREAD_COLOR); Mat src_ME = imread("C:\\Users\\hl\\Desktop\\me2.jpg", IMREAD_COLOR); //Mat src = imread("C:\\Users\\hl\\Desktop\\CESHI2.jpg", IMREAD_COLOR); imshow("过曝光",src_OE); imshow("欠曝光",src_UE); imshow("正常曝光",src_ME); Mat oe, ue, me;// ceshi; cvtColor(src_OE, oe, COLOR_BGR2Lab); cvtColor(src_OE, ue, COLOR_BGR2Lab); cvtColor(src_OE, me, COLOR_BGR2Lab); //cvtColor(src, ceshi, COLOR_BGR2Lab); //熵最大融合 Mat out; out = fusion(src_OE, src_UE, src_ME,BLOCK); imshow("曝光融合后", out); //cvtColor(out, ceshi , COLOR_BGR2Lab); //观察总熵值 cout << "过曝总熵:" << entropy(oe) << endl; cout << "欠曝总熵:" << entropy(ue) << endl; cout << "正常曝光总熵:" << entropy(me) << endl; cout << "曝光合成总熵:" << entropy(out) << endl; //cout << "测试熵:" << entropy(ceshi) << endl; waitKey(); return 0;

静态多曝光图片

算法效果如下:
不同BLOCK的效果
左上:block大小为2525个像素,熵值为15.1996
右上:block大小为20
20个像素,熵值为15.1069
左下:block大小为100100个像素,熵值为15.3519
右上:block大小为250
250个像素,熵值为15.5222

虽说肉眼可见最多细节信息,但是这个引发的块状效应依然无法容忍,之后会持续更新对于该算法的改进。敬请期待。

转载地址:http://aamen.baihongyu.com/

你可能感兴趣的文章
[老老实实学WCF] 第四篇 初探通信--ChannelFactory
查看>>
ASP.NET 中的 Async/Await 简介
查看>>
解决Chrome中调试JS提示“Uncaught TypeError: Cannot use 'in' operator to search for”错误信息问题
查看>>
阿里巴巴java规范 第一版
查看>>
USB通信记事
查看>>
Android 编译(1)——Android编译步骤梳理
查看>>
编译器配置(1)——ARMv7,ARMv8(AArch64) 浮点配置等相关知识
查看>>
RK3399 OV13850摄像头配置
查看>>
Android 编译(2)——jack-server相关问题
查看>>
网络服务(2)——以太网配置IPV4和IPV6
查看>>
网络服务(3)——以太网phy的识别加载(RK3399)
查看>>
网络服务(5)——usb网卡名称修改(RK3399 Ubuntu)
查看>>
行业观察与理解-互联网巨幕下各行业的现状和发展
查看>>
数据结构与算法大全
查看>>
稳定排序和不稳定排序
查看>>
句柄泄露与CloseHandle()
查看>>
一些笔记
查看>>
SVN的安装和使用
查看>>
APP测试点分析
查看>>
JDK安装过程中出现“javac不是内部或外部命令”问题的解决
查看>>