RAW数据转换成RGB数据

发布于:2025-06-18 ⋅ 阅读:(19) ⋅ 点赞:(0)

说明:RAW数据转换成RGB数据是通过插值得到的

RAW数据的形式多种,以RGGB为例:

 上图RAW图中,每个像素点只有一种颜色信息,但是RGB的图像中,每个像素应该有3种色彩信息,因此要进行插值处理。如何插值呢?我们可以便利每个像素点,在该像素点上获取其他两种颜色信息就可以得到一个像素的GRB颜色信息。

  1. Bayer 模式识别

    • 通过行列坐标 (y % 2) 和 (x % 2) 判断当前像素类型

    • 不同位置使用不同插值策略

  2. 插值方法

    • R 像素位置

      • R:直接使用当前值

      • G:取左右相邻G的平均

      • B:取四个对角线B的平均

    • B 像素位置

      • R:取四个对角线R的平均

      • G:取上下左右G的平均

      • B:直接使用当前值

    • G 像素位置

      • 在R行:R取左右平均,B取上下平均

      • 在B行:R取上下平均,B取左右平均

代码展示

 

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

// 简单的双线性插值去马赛克
void demosaic_bilinear(uint16_t* raw, uint8_t* rgb, int width, int height) {
    // 遍历所有像素(跳过边缘)
    for (int y = 1; y < height - 1; y++) {
        for (int x = 1; x < width - 1; x++) {
            int idx = y * width + x;
            int r, g, b;
            
            // 根据 Bayer 位置决定插值方式(假设 RGGB 模式)
            if ((y % 2) == 0) {    // 偶数行
                if ((x % 2) == 0) { // 偶数列 → R 像素
                    r = raw[idx];
                    g = (raw[idx - 1] + raw[idx + 1] + raw[idx - width] + raw[idx + width]) / 4;
                    b = (raw[idx - width - 1] + raw[idx - width + 1] + raw[idx + width - 1] + raw[idx + width + 1]) / 4;
                } else {            // 奇数列 → G 像素(在 R 行)
                    r = (raw[idx - 1] + raw[idx + 1]) / 2;
                    g = raw[idx];
                    b = (raw[idx - width] + raw[idx + width]) / 2;
                }
            } else {              // 奇数行
                if ((x % 2) == 0) { // 偶数列 → G 像素(在 B 行)
                    r = (raw[idx - width] + raw[idx + width]) / 2;
                    g = raw[idx];
                    b = (raw[idx - 1] + raw[idx + 1]) / 2;
                } else {            // 奇数列 → B 像素
                    r = (raw[idx - width - 1] + raw[idx - width + 1] + raw[idx + width - 1] + raw[idx + width + 1]) / 4;
                    g = (raw[idx - 1] + raw[idx + 1] + raw[idx - width] + raw[idx + width]) / 4;
                    b = raw[idx];
                }
            }
            
            // 写入 RGB 数据(假设8位输出)
            int rgb_idx = (y * width + x) * 3;
            rgb[rgb_idx] = (uint8_t)(r > 255 ? 255 : r);     // R
            rgb[rgb_idx + 1] = (uint8_t)(g > 255 ? 255 : g); // G
            rgb[rgb_idx + 2] = (uint8_t)(b > 255 ? 255 : b); // B
        }
    }
}

// 使用示例
int main() {
    // 假设 RAW 数据是 16-bit (实际位深度取决于传感器)
    int width = 640;
    int height = 480;
    
    // 分配内存
    uint16_t* raw_data = malloc(width * height * sizeof(uint16_t));
    uint8_t* rgb_data = malloc(width * height * 3 * sizeof(uint8_t));
    
    // 这里应填充真实的 RAW 数据(从文件或传感器读取)
    // ...
    
    // 执行转换
    demosaic_bilinear(raw_data, rgb_data, width, height);
    
    // 现在 rgb_data 包含 RGB888 格式的图像数据
    // 可保存为 BMP/PPM 等格式或显示
    
    free(raw_data);
    free(rgb_data);
    return 0;
}
  • 传感器RAW通常是10-14位,需缩放为8位RGB


网站公告

今日签到

点亮在社区的每一天
去签到