首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将拜耳编码(RGB)和16位深度的原始图像转换为RGB:最终图像太暗,有绿色的投射(Rust)。

将拜耳编码(RGB)和16位深度的原始图像转换为RGB:最终图像太暗,有绿色的投射(Rust)。
EN

Stack Overflow用户
提问于 2022-06-04 11:58:44
回答 1查看 742关注 0票数 1

我使用一个Rust库来解析原始的ARW图像(索尼原始格式)。我得到了一个16位像素的原始缓冲区,它给出了CFA (颜色滤波器阵列)(即RGGB),数据缓冲区包含拜耳编码中的高度*宽度像素。每个像素被存储为16位(然而,我认为相机只使用每一个像素的16位中的12或14位)。

我正在使用拜耳库进行解禁。目前,我的最后一张照片太暗了,在人物画过程之后有一个绿色的造型。我猜错误在于,在将数据传递给拜耳库之前,我试图通过除以u16::max并将其与u8::max相乘,将每个16位值转换为8位。然而,我不知道这是否是正确的方法。

我想我需要在解析原始文件和将它传递给拜耳库之间执行额外的步骤。请问我有什么建议吗?

我可以确保至少有一些解禁的工作。下面是结果图像的屏幕截图:

当前代码

我使用的库是拉瓦装载机拜耳

代码语言:javascript
复制
let decoded_raw = rawloader::decode_file(path).unwrap();
let decoded_image_u16 = match &decoded_raw.data {
    RawImageData::Integer(data) => data,
    RawImageData::Float(_) => panic!("not supported yet"),
};

// u16 to u8 (this is probably wrong)
let mut decoded_image_u8 = decoded_image_u16
    .iter()
    .map(|val| {
        // todo find out how to interpret the u16!
        let val_f32 = *val as f32;
        let u16_max_f32 = u16::MAX as f32;
        let u8_max_f32 = u8::MAX as f32;
        (val_f32 / u16_max_f32 * u8_max_f32) as u8
    })
    .collect::<Vec<u8>>();

// prepare final RGB buffer
let bytes_per_pixel = 3; // RGB
let mut demosaic_buf = vec![0; bytes_per_pixel * decoded_raw.width * decoded_raw.height];
let mut dst = bayer::RasterMut::new(
    decoded_raw.width,
    decoded_raw.height,
    bayer::RasterDepth::Depth8,
    &mut demosaic_buf,
);

// DEMOSAIC
// adapter so that `bayer::run_demosaic` can read from the Vec
let mut decoded_image_u8 = ReadableByteSlice::new(decoded_image_u8.as_slice());

bayer::run_demosaic(
    &mut decoded_image_u8,
    bayer::BayerDepth::Depth8,
    // RGGB is definitely right for my AWR file
    bayer::CFA::RGGB,
    bayer::Demosaic::Linear,
    &mut dst,
)
.unwrap();
EN

回答 1

Stack Overflow用户

发布于 2022-06-04 13:00:27

我不确定这是否与实际问题有关,但您的转换太过分了。

若要将u16的全部范围转换为u8的全部范围,请使用:

代码语言:javascript
复制
(x >> 8) as u8
代码语言:javascript
复制
fn main() {
    let convert = |x: u16| (x >> 8) as u8;

    println!("{} -> {}", 0, convert(0));
    println!("{} -> {}", 30000, convert(30000));
    println!("{} -> {}", u16::MAX, convert(u16::MAX));
}
代码语言:javascript
复制
0 -> 0
30000 -> 117
65535 -> 255

如果你发布输入图像,我可能会进一步帮助你,但如果不能重现你的问题,我认为这里不会有太多的问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72499553

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档