这个只是一个简单的例子,还需要考虑前一帧和当前帧是否有位移,还需要se是否需要乘上hdr ratio(noise也会bust起来) 达到与ne的亮度保持一致(如果手晃动的话不至于一半暗一般亮),可以将se转成20bit的,再压缩成12bit的,
void hdr_fus()
{ // 读取长曝光和短曝光的图像
std::ifstream file_long("E:/test/hdr/long_2592x1944_12_0.raw", std::ios::binary);
std::ifstream file_short("E:/test/hdr/short_2592x1944_12_0.raw", std::ios::binary);
// 创建一个vector来存储像素值
int width = 2592;
int height = 1944;
std::vector<uint16_t> pixels_long(width * height);
std::vector<uint16_t> pixels_short(width * height);
file_long.read(reinterpret_cast<char*>(pixels_long.data()), pixels_long.size() * sizeof(uint16_t));
file_short.read(reinterpret_cast<char*>(pixels_short.data()), pixels_short.size() * sizeof(uint16_t));
// 创建cv::Mat对象
cv::Mat longExposure(height, width, CV_16UC1, pixels_long.data());
cv::Mat shortExposure(height, width, CV_16UC1, pixels_short.data());
// 创建一个空的HDR图像
cv::Mat hdrImage = cv::Mat::zeros(longExposure.size(), CV_16UC1);
// 在过曝的部分和物体移动的部分进行叠图
for (int y = 0; y < longExposure.rows; y++)
{
for (int x = 0; x < longExposure.cols; x++)
{
uint16_t longPixel = longExposure.at<uint16_t>(y, x);
uint16_t shortPixel = shortExposure.at<uint16_t>(y, x);
uint16_t smoothPixel;
// 如果长曝光的像素过曝(例如,亮度大于阈值),则使用短曝光的像素
// 或者如果像素在长曝光和短曝光之间有显著的差异(例如,差异大于阈值),则假定物体已移动,也使用短曝光的像素
// if (longPixel > 4095.0 || std::abs(longPixel - shortPixel) > 480)//少了一个hdr ratio
if (longPixel > 4040.0 ) {
hdrImage.at<uint16_t>(y, x) = shortPixel;
}
else {
hdrImage.at<uint16_t>(y, x) = longPixel;
}
if (longPixel< 4040&& longPixel > 3800) {
float distance = std::abs(longPixel - 3800.0f);
// 计算权重
float weight = std::min(distance / 240.0f, 1.0f);
// 计算加权平均值
uint16_t resultPixel = static_cast<uint16_t>(weight * shortPixel + (1.0f - weight) * longPixel);
hdrImage.at<uint16_t>(y, x) = resultPixel;
}
}
}
// 保存HDR图像
cv::Mat hdrImage8bit, longExposure_hdrImage8bit, shortExposure_hdrImage8bit;
cv::normalize(hdrImage, hdrImage8bit, 0, 255, cv::NORM_MINMAX, CV_8U);
cv::normalize(longExposure, longExposure_hdrImage8bit, 0, 255, cv::NORM_MINMAX, CV_8U);
cv::normalize(shortExposure, shortExposure_hdrImage8bit, 0, 255, cv::NORM_MINMAX, CV_8U);
}