美文网首页
raw域上的去噪

raw域上的去噪

作者: 大梦一场三十一 | 来源:发表于2021-04-30 01:20 被阅读0次

    一、基本概念

    1. raw域上的去噪会有一个好处,噪声形态没有被其他模块给破坏。具体的分析可以查看为什么在raw域降噪?

    二、 一个简单的raw域去噪方法

    1. CN111784603A 上的去早方法
    1. 获取y亮度值的图,YR,YGR,YGB,YB
        1.1 中心值为R时,邻域3*3的像素中,Y=(4×R+2×∑G+∑B)/16
        1.2 中心值为B时,Y=(4×B+2×∑G+∑R)/16
        1.3 中心值为G时,Y=(4×G0+2×∑R+2×∑B)/8
    2. 获取色度图,分别为R,GR,GB,B
    3. 分别以亮度图为引导图,对于色度图来进行引导滤波来去除亮度上的噪声
        3.1 在亮度图的9*9的区域中,对于以当前像素为中心的大小为3×3的匹配窗口进行匹配,搜索,按照绝对误差和(SAD算法)进行计算。即计算出差值的绝对值之和,不大于预设的亮度阈值,则为相似。
        3.2 将亮度图所有相似的点进行累加取平均,获得初次去噪的亮度子图
        3.3 将亮度图所有相似的点对应的色度图中的点进行累加取平均,获得初次去噪的色度子图
    4. 将4张去噪色度图和4张去噪亮度图进行下采样获得第二色度图和亮度图
    5. 将第二色度图和亮度图进行联合滤波
        5.1 将第二亮度图进行SAD匹配
        5.2 将第二色度图进行SAD匹配
        5.3 如果亮度的差值的绝对值之和小于亮度阈值且色度的差值的绝对值之和小于色度阈值,则为相似。
        5.4 将色度图上所有相似的点累加取平均,则可以获取当前色度图的去噪图。用来去除色度的噪声。
    6. 通过上采样或者与采样前一样大的图,例如双线性插值、双三次插值、Cubic插值算法
    (比较奇怪的是为什么要上下采样,加快速度吗?但是我看到了比较奇怪的条纹)
    7. 应用上采样的二次去噪色度子图、初次去噪色度子图以及初始图像中各像素的色度值按照一定的权重进行融合计算,获取各像素的输出色度值。例如:
    Pout=w2×Pfilt2+(1-w2)×(w1×Pfilt1+(1-w1)×Pori) 
    其中,Pout为像素的输出色度值,w1为初次去噪色度子图的权重,w2为二次去噪色度子图的权重,Pfilt1为初次去噪色度子图中该像素的色度值,Pfilt2为经过上采样的二次去噪色度子图中该像素的色度值,Pori为初始图像中该像素的色度值。
    8. 恢复bayer的图。
    

    其中上面的3.1步其实是计算时间消耗最长的,可以参看nlm的积分法进行加速(待实现,现在300w像素要跑20s)。目前是绝对差之和,即相当于nlm中使用了均值的方式来替代高斯权重。

    可以调节搜索框,特征图半径,相似度阈值来确定过滤的效果,通过 w1,w2来保证保留的噪声

    void xxx_cfa_lianyong_run(void* handle)
    {
        if (NULL == handle)
        {
            printf("xxx_dpc_chen_run handle is null! \n");
            return;
        }
        xxx_isp_handle* isp_handle = (xxx_isp_handle*)handle;
        u16 Width = isp_handle->raw_handle.raw_wide;
        u16 Height = isp_handle->raw_handle.raw_high;
        u16 Width_half = (u16)floor(Width / 2);
        u16 Height_half = (u16)floor(Height / 2);
        u16 w1 = 60; // 第一次去噪加回的权重
        u16 w2 = 10; // 第二次去噪加回的权重
    
        const u8 Green = 1 - ((isp_handle->demosaic_handle.red_x + \
            isp_handle->demosaic_handle.red_y) & 1);
        u16* first_data = isp_handle->raw_handle.data;
        u16* img_r, * img_gr, * img_gb, * img_b, * y_data;
        u16* y_r, *y_gr, *y_gb, *y_b;
        u16* data;
        u16* img_r_down, * img_gr_down, * img_gb_down, * img_b_down;
        u16* y_r_down, * y_gr_down, * y_gb_down, * y_b_down;
        u16* data_down;
        data = (u16*)malloc(Width * Height * sizeof(u16));
        img_r = (u16*)malloc(Width_half * Height_half * sizeof(u16));
        img_gr = (u16*)malloc(Width_half * Height_half * sizeof(u16));
        img_gb = (u16*)malloc(Width_half * Height_half * sizeof(u16));
        img_b = (u16*)malloc(Width_half * Height_half * sizeof(u16));
        y_r = (u16*)malloc(Width_half * Height_half * sizeof(u16));
        y_gr = (u16*)malloc(Width_half * Height_half * sizeof(u16));
        y_gb = (u16*)malloc(Width_half * Height_half * sizeof(u16));
        y_b = (u16*)malloc(Width_half * Height_half * sizeof(u16));
        if (img_r == NULL || img_gr == NULL || img_gb == NULL || img_b == NULL) return;
        if (y_r == NULL || y_gr == NULL || y_gb == NULL || y_b == NULL) return;
        if (data == NULL) return;
        memcpy(data,first_data, Width * Height * sizeof(u16));
        memset(img_r, 0, Width_half * Height_half * sizeof(u16));
        memset(img_gr, 0, Width_half * Height_half * sizeof(u16));
        memset(img_gb, 0, Width_half * Height_half * sizeof(u16));
        memset(img_b, 0, Width_half * Height_half * sizeof(u16));
        memset(y_r, 0, Width_half * Height_half * sizeof(u16));
        memset(y_gr, 0, Width_half * Height_half * sizeof(u16));
        memset(y_gb, 0, Width_half * Height_half * sizeof(u16));
        memset(y_b, 0, Width_half * Height_half * sizeof(u16));
    
        y_data = (u16*)malloc(Width * Height * sizeof(u16));// 全部按16位读出来
        if (y_data == NULL) return;
        memset(y_data, 0, Width * Height * sizeof(u16));
    
        // 定义二次下采样的内存
        u16 up_down_num = 2;
        u16 Width_down = (u16)floor(Width_half / up_down_num);
        u16 Height_down = (u16)floor(Height_half / up_down_num);
    
        data_down = (u16*)malloc(Width * Height * sizeof(u16));
        img_r_down = (u16*)malloc(Width_down * Height_down * sizeof(u16));
        img_gr_down = (u16*)malloc(Width_down * Height_down * sizeof(u16));
        img_gb_down = (u16*)malloc(Width_down * Height_down * sizeof(u16));
        img_b_down = (u16*)malloc(Width_down * Height_down * sizeof(u16));
        y_r_down = (u16*)malloc(Width_down * Height_down * sizeof(u16));
        y_gr_down = (u16*)malloc(Width_down * Height_down * sizeof(u16));
        y_gb_down = (u16*)malloc(Width_down * Height_down * sizeof(u16));
        y_b_down = (u16*)malloc(Width_down * Height_down * sizeof(u16));
        if (img_r_down == NULL || img_gr_down == NULL || img_gb_down == NULL || img_b_down == NULL) return;
        if (y_r_down == NULL || y_gr_down == NULL || y_gb_down == NULL || y_b_down == NULL) return;
        if (data_down == NULL) return;
        memcpy(data_down, first_data, Width * Height * sizeof(u16));
        memset(img_r_down, 0, Width_down * Height_down * sizeof(u16));
        memset(img_gr_down, 0, Width_down * Height_down * sizeof(u16));
        memset(img_gb_down, 0, Width_down * Height_down * sizeof(u16));
        memset(img_b_down, 0, Width_down * Height_down * sizeof(u16));
        memset(y_r_down, 0, Width_down * Height_down * sizeof(u16));
        memset(y_gr_down, 0, Width_down * Height_down * sizeof(u16));
        memset(y_gb_down, 0, Width_down * Height_down * sizeof(u16));
        memset(y_b_down, 0, Width_down * Height_down * sizeof(u16));
    
        u16 x, y, i, j;
        int ii, jj;
        u16 temp_y;
        u16 search_win = 4;// 搜索区域的半径
        u16 win = 1; // 取特征图的半径
        u16 sad_thresh = 100; // 绝对差小于当前值时记为相似
        u16 search_left, search_right, search_top, search_bottom;
        u16 sim_hist_r, sad_r, sad_r_chroma;
        u32 sim_sum_r, sim_sum_chroma_r;
        u16 sim_hist_gr, sad_gr, sad_gr_chroma;
        u32 sim_sum_gr, sim_sum_chroma_gr;
        u16 sim_hist_gb, sad_gb, sad_gb_chroma;
        u32 sim_sum_gb, sim_sum_chroma_gb;
        u16 sim_hist_b, sad_b, sad_b_chroma;
        u32 sim_sum_b, sim_sum_chroma_b;
        // 获取亮度图
        for (y = 0; y < Height; y++)
        {
            for (x = 0; x < Width; x++)
            {
                if (0 == y)
                {
                    if (0 == x)
                    {
                        temp_y = (data[y * Width + x] + data[y * Width + x + 1] + \
                            data[(y + 1) * Width + x] + data[(y + 1) * Width + x + 1]) >> 2;
                    }
                    else if (x < Width - 1)
                    {
                        if (((x + y) & 1) == Green)
                        {
                            temp_y = ((data[y * Width + x - 1] + data[y * Width + x + 1]) + \
                                data[(y + 1) * Width + x] * 2 + data[y * Width + x] * 4) >> 3;
                        }
                        else
                        {
                            temp_y = (data[y * Width + x] * 4 + (data[(y + 1) * Width + x - 1] + \
                                data[(y + 1) * Width + x + 1]) * 2 + (data[y * Width + x - 1] + \
                                    data[y * Width + x + 1] + data[(y + 1) * Width + x]) / 3 * 8) >> 4;
                        }
                    }
                    else
                    {
                        temp_y = (data[y * Width + x] + data[y * Width + x - 1] + \
                            data[(y + 1) * Width + x] + data[(y + 1) * Width + x - 1]) >> 2;
                    }
                }
                else if (y < Height - 1)
                {
                    if (x == 0)
                    {
                        if (((x + y) & 1) == Green)
                        {
                            temp_y = ((data[(y - 1) * Width + x] + data[(y + 1) * Width + x]) + \
                                data[y * Width + x + 1] * 2 + data[y * Width + x] * 4) >> 3;
                        }
                        else
                        {
                            temp_y = (data[y * Width + x] * 4 + (data[(y + 1) * Width + x - 1] + \
                                data[(y - 1) * Width + x - 1]) * 2 + (data[(y - 1) * Width + x] + \
                                    data[y * Width + x + 1] + data[(y + 1) * Width + x]) / 3 * 8) >> 4;
                        }
                    }
                    else if (x < Width - 1)
                    {
                        if (((x + y) & 1) == Green)
                        {
                            temp_y = ((data[(y - 1) * Width + x] + data[(y + 1) * Width + x]) + \
                                data[y * Width + x + 1] + data[y * Width + x - 1] + data[y * Width + x] * 4) >> 3;
                        }
                        else
                        {
                            temp_y = (data[y * Width + x] * 4 + data[(y + 1) * Width + x - 1] + \
                                data[(y - 1) * Width + x - 1] + data[(y + 1) * Width + x + 1] + \
                                data[(y - 1) * Width + x + 1] + (data[(y - 1) * Width + x] + \
                                    data[y * Width + x + 1] + data[(y + 1) * Width + x] + \
                                    data[y * Width + x - 1]) * 2) >> 4;
                        }
                    }
                    else
                    {
                        if (((x + y) & 1) == Green)
                        {
                            temp_y = ((data[(y - 1) * Width + x] + data[(y + 1) * Width + x]) + \
                                data[y * Width + x - 1] * 2 + data[y * Width + x] * 4) >> 3;
                        }
                        else
                        {
                            temp_y = (data[y * Width + x] * 4 + (data[(y + 1) * Width + x - 1] + \
                                data[(y - 1) * Width + x - 1]) * 2 + (data[(y - 1) * Width + x] + \
                                    data[y * Width + x - 1] + data[(y + 1) * Width + x]) / 3 * 8) >> 4;
                        }
                    }
                }
                else
                {
                    if (x == 0)
                    {
                        temp_y = (data[y * Width + x] + data[y * Width + x + 1] + \
                            data[(y - 1) * Width + x] + data[(y - 1) * Width + x + 1]) >> 2;
                    }
                    else if (x < Width - 1)
                    {
                        if (((x + y) & 1) == Green)
                        {
                            temp_y = ((data[y * Width + x - 1] + data[y * Width + x + 1]) + \
                                data[(y - 1) * Width + x] * 2 + data[y * Width + x] * 4) >> 3;
                        }
                        else
                        {
                            temp_y = (data[y * Width + x] * 4 + (data[(y - 1) * Width + x - 1] + \
                                data[(y - 1) * Width + x + 1]) * 2 + (data[y * Width + x - 1] + \
                                    data[y * Width + x + 1] + data[(y - 1) * Width + x]) / 3 * 8) >> 4;
                        }
                    }
                    else
                    {
                        temp_y = (data[y * Width + x] + data[y * Width + x - 1] + \
                            data[(y - 1) * Width + x] + data[(y - 1) * Width + x - 1]) >> 2;
                    }
                }
                // y_data[y * Width + x] = temp_y;
                *(y_data + y * Width + x) = temp_y;
            }
        }
        //设置色度图
        for (y = 0; y < Height_half; y++)
        {
            for (x = 0; x < Width_half; x++)
            {
                *(img_r + y * Width_half + x) = data[2 * y * Width + 2 * x];
               //  printf("%d,%d \n", *(img_r + y * Width_half + x), data[2 * y * Width + 2 * x]);
                *(img_gr + y * Width_half + x) = data[2 * y * Width + 2 * x + 1];
                *(img_gb + y * Width_half + x) = data[(2 * y +1) * Width + 2 * x];
                *(img_b + y * Width_half + x) = data[(2 * y + 1) * Width + 2 * x + 1];
                *(y_r + y * Width_half + x) = y_data[2 * y * Width + 2 * x];
                *(y_gr + y * Width_half + x) = y_data[2 * y * Width + 2 * x + 1];
                *(y_gb + y * Width_half + x) = y_data[(2 * y + 1) * Width + 2 * x];
                *(y_b + y * Width_half + x) = y_data[(2 * y + 1) * Width + 2 * x + 1];
            }
        }
    
        // 已亮度图对色度图进行引导滤波,去除亮度上的噪声
        for (y = 0; y < Height_half; y++)
        {
            for (x = 0; x < Width_half; x++)
            {
                search_left = max(x - search_win, 0);
                search_right = min(x + search_win , Width_half - 1);
                search_top = max(y - search_win , 0);
                search_bottom = min(y + search_win , Height_half - 1);
                sim_hist_r = sim_sum_r = sim_sum_chroma_r = 0;
                sim_hist_gr = sim_sum_gr = sim_sum_chroma_gr = 0;
                sim_hist_gb = sim_sum_gb = sim_sum_chroma_gb = 0;
                sim_hist_b = sim_sum_b = sim_sum_chroma_b = 0;
                for (i = search_left; i <= search_right; i++)
                {
                    for (j = search_top; j <= search_bottom; j++)
                    {
                        sad_r = sad_gr = sad_gb = sad_b = 0;
                        for (ii = -win; ii <= win; ii++)
                        {
                            for (jj = -win; jj <= win; jj++)
                            {
                                if ((y + jj) < 0 || (y + jj) >= Height_half || (x + ii) < 0 || (x + ii) >= Width_half || \
                                    (j + jj) < 0 || (j + jj) >= Height_half || (i + ii) < 0 || (i + ii) >= Width_half)
                                {
                                    continue;
                                }
                                sad_r += abs(y_r[(y + jj) * Width_half + x + ii] - y_r[(j + jj) * Width_half + i + ii]);
                                sad_gr += abs(y_gr[(y + jj) * Width_half + x + ii] - y_gr[(j + jj) * Width_half + i + ii]);
                                sad_gb += abs(y_gb[(y + jj) * Width_half + x + ii] - y_gb[(j + jj) * Width_half + i + ii]);
                                sad_b += abs(y_b[(y + jj) * Width_half + x + ii] - y_b[(j + jj) * Width_half + i + ii]);
    
                            }
                        }
                        if (sad_r < sad_thresh)
                        {
                            sim_hist_r++;
                            sim_sum_r += y_r[j * Width_half + i];
                            sim_sum_chroma_r += img_r[j * Width_half + i];
                        }
                        if (sad_gr < sad_thresh)
                        {
                            sim_hist_gr++;
                            sim_sum_gr += y_gr[j * Width_half + i];
                            sim_sum_chroma_gr += img_gr[j * Width_half + i];
                        }
                        if (sad_gb < sad_thresh)
                        {
                            sim_hist_gb++;
                            sim_sum_gb += y_gb[j * Width_half + i];
                            sim_sum_chroma_gb += img_gb[j * Width_half + i];
                        }
                        if (sad_b < sad_thresh)
                        {
                            sim_hist_b++;
                            sim_sum_b += y_b[j * Width_half + i];
                            sim_sum_chroma_b += img_b[j * Width_half + i];
                        }
                    }
                }      
                *(y_r + y * Width_half + x) = sim_sum_r / sim_hist_r;
                *(img_r + y * Width_half + x) = sim_sum_chroma_r / sim_hist_r;
                *(y_gr + y * Width_half + x) = sim_sum_gr / sim_hist_gr;
                *(img_gr + y * Width_half + x) = sim_sum_chroma_gr / sim_hist_gr;
                *(y_gb + y * Width_half + x) = sim_sum_gb / sim_hist_gb;
                *(img_gb + y * Width_half + x) = sim_sum_chroma_gb / sim_hist_gb;
                *(y_b + y * Width_half + x) = sim_sum_b / sim_hist_b;
                *(img_b + y * Width_half + x) = sim_sum_chroma_b / sim_hist_b;
            }
        }
        //叠回第一次去噪图
        for (y = 0; y < Height_half; y++)
        {
            for (x = 0; x < Width_half; x++)
            {
                // printf("%d,%d \n", *(img_r + y * Width_half + x), data[2 * y * Width + 2 * x]);
                data[2 * y * Width + 2 * x] = *(img_r + y * Width_half + x);
                // printf("%d,%d \n", *(img_r + y * Width_half + x), data[2 * y * Width + 2 * x]);
                data[2 * y * Width + 2 * x + 1] = *(img_gr + y * Width_half + x);
                data[(2 * y + 1) * Width + 2 * x] = *(img_gb + y * Width_half + x);
                data[(2 * y + 1) * Width + 2 * x + 1] = *(img_b + y * Width_half + x);
            }
        }
        // 下采样 取4个象限的的均值
        for (y = 0; y < Height_down; y++)
        {
            for (x = 0; x < Width_down; x++)
            {
                *(img_r_down + y * Width_down + x) = (img_r[2 * y * Width_half + 2 * x] + img_r[2 * y * Width_half + 2 * x + 1] + \
                    img_r[(2 * y + 1) * Width_half + 2 * x] + img_r[(2 * y + 1) * Width_half + 2 * x + 1]) >> 2;
                //  printf("%d,%d \n", *(img_r + y * Width_half + x), data[2 * y * Width + 2 * x]);
                *(img_gr_down + y * Width_down + x) = (img_gr[2 * y * Width_half + 2 * x] + img_gr[2 * y * Width_half + 2 * x + 1] + \
                    img_gr[(2 * y + 1) * Width_half + 2 * x] + img_gr[(2 * y + 1) * Width_half + 2 * x + 1]) >> 2;
                *(img_gb_down + y * Width_down + x) = (img_gb[2 * y * Width_half + 2 * x] + img_gb[2 * y * Width_half + 2 * x + 1] + \
                    img_gb[(2 * y + 1) * Width_half + 2 * x] + img_gb[(2 * y + 1) * Width_half + 2 * x + 1]) >> 2;
                *(img_b_down + y * Width_down + x) = (img_b[2 * y * Width_half + 2 * x] + img_b[2 * y * Width_half + 2 * x + 1] + \
                    img_b[(2 * y + 1) * Width_half + 2 * x] + img_b[(2 * y + 1) * Width_half + 2 * x + 1]) >> 2;
                *(y_r_down + y * Width_down + x) = (y_r[2 * y * Width_half + 2 * x] + y_r[2 * y * Width_half + 2 * x + 1] + \
                    y_r[(2 * y + 1) * Width_half + 2 * x] + y_r[(2 * y + 1) * Width_half + 2 * x + 1]) >> 2;
                *(y_gr_down + y * Width_down + x) = (y_gr[2 * y * Width_half + 2 * x] + y_gr[2 * y * Width_half + 2 * x + 1] + \
                    y_gr[(2 * y + 1) * Width_half + 2 * x] + y_gr[(2 * y + 1) * Width_half + 2 * x + 1]) >> 2;
                *(y_gb_down + y * Width_down + x) = (y_gb[2 * y * Width_half + 2 * x] + y_gb[2 * y * Width_half + 2 * x + 1] + \
                    y_gb[(2 * y + 1) * Width_half + 2 * x] + y_gb[(2 * y + 1) * Width_half + 2 * x + 1]) >> 2;
                *(y_b_down + y * Width_down + x) = (y_b[2 * y * Width_half + 2 * x] + y_b[2 * y * Width_half + 2 * x + 1] + \
                    y_b[(2 * y + 1) * Width_half + 2 * x] + y_b[(2 * y + 1) * Width_half + 2 * x + 1]) >> 2;
            }
        }
        free(y_r);
        free(y_gr);
        free(y_gb);
        free(y_b);
        // 进行第二次滤波
        for (y = 0; y < Height_down; y++)
        {
            for (x = 0; x < Width_down; x++)
            {
                search_left = max(x - search_win, 0);
                search_right = min(x + search_win, Width_down - 1);
                search_top = max(y - search_win, 0);
                search_bottom = min(y + search_win, Height_down - 1);
                sim_hist_r = sim_sum_r = sim_sum_chroma_r = 0;
                sim_hist_gr = sim_sum_gr = sim_sum_chroma_gr = 0;
                sim_hist_gb = sim_sum_gb = sim_sum_chroma_gb = 0;
                sim_hist_b = sim_sum_b = sim_sum_chroma_b = 0;
                for (i = search_left; i <= search_right; i++)
                {
                    for (j = search_top; j <= search_bottom; j++)
                    {
                        sad_r = sad_gr = sad_gb = sad_b = 0;
                        sad_r_chroma = sad_gr_chroma = sad_gb_chroma = sad_b_chroma = 0;
                        for (ii = -win; ii <= win; ii++)
                        {
                            for (jj = -win; jj <= win; jj++)
                            {
                                if ((y + jj) < 0 || (y + jj) >= Height_down || (x + ii) < 0 || (x + ii) >= Width_down || \
                                    (j + jj) < 0 || (j + jj) >= Height_down || (i + ii) < 0 || (i + ii) >= Width_down)
                                {
                                    continue;
                                }
                                sad_r += abs(y_r_down[(y + jj) * Width_down + x + ii] - y_r_down[(j + jj) * Width_down + i + ii]);
                                sad_gr += abs(y_gr_down[(y + jj) * Width_down + x + ii] - y_gr_down[(j + jj) * Width_down + i + ii]);
                                sad_gb += abs(y_gb_down[(y + jj) * Width_down + x + ii] - y_gb_down[(j + jj) * Width_down + i + ii]);
                                sad_b += abs(y_b_down[(y + jj) * Width_down + x + ii] - y_b_down[(j + jj) * Width_down + i + ii]);
                                sad_r_chroma += abs(img_r_down[(y + jj) * Width_down + x + ii] - img_r_down[(j + jj) * Width_down + i + ii]);
                                sad_gr_chroma += abs(img_gr_down[(y + jj) * Width_down + x + ii] - img_gr_down[(j + jj) * Width_down + i + ii]);
                                sad_gb_chroma += abs(img_gb_down[(y + jj) * Width_down + x + ii] - img_gb_down[(j + jj) * Width_down + i + ii]);
                                sad_b_chroma += abs(img_b_down[(y + jj) * Width_down + x + ii] - img_b_down[(j + jj) * Width_down + i + ii]);
    
                            }
                        }
                        if (sad_r < sad_thresh && sad_r_chroma < sad_thresh)
                        {
                            sim_hist_r++;
                            sim_sum_chroma_r += img_r_down[j * Width_down + i];
                        }
                        if (sad_gr < sad_thresh && sad_gr_chroma < sad_thresh)
                        {
                            sim_hist_gr++;
                            sim_sum_chroma_gr += img_gr_down[j * Width_down + i];
                        }
                        if (sad_gb < sad_thresh && sad_gb_chroma < sad_thresh)
                        {
                            sim_hist_gb++;
                            sim_sum_chroma_gb += img_gb_down[j * Width_down + i];
                        }
                        if (sad_b < sad_thresh && sad_b_chroma < sad_thresh)
                        {
                            sim_hist_b++;
                            sim_sum_chroma_b += img_b_down[j * Width_down + i];
                        }
                    }
                }
                *(img_r_down + y * Width_down + x) = sim_sum_chroma_r / sim_hist_r;
                *(img_gr_down + y * Width_down + x) = sim_sum_chroma_gr / sim_hist_gr;
                *(img_gb_down + y * Width_down + x) = sim_sum_chroma_gb / sim_hist_gb;
                *(img_b_down + y * Width_down + x) = sim_sum_chroma_b / sim_hist_b;
            }
        }
        free(y_r_down);
        free(y_gr_down);
        free(y_gb_down);
        free(y_b_down);
        // 上采样 向右插
    #if 1
        for (y = 0; y < Height_down; y += 2)
        {
            for (x = 0; x < Width_down - 1; x++)
            {
                *(img_r + 2 * y * Width_half + 2 * x) = *(img_r_down + y * Width_down + x);
                *(img_r + 2 * y * Width_half + 2 * x + 1) = (*(img_r_down + y * Width_down + x) + *(img_r_down + y * Width_down + x + 1)) >> 1;
                *(img_gr + 2 * y * Width_half + 2 * x) = *(img_gr_down + y * Width_down + x);
                *(img_gr + 2 * y * Width_half + 2 * x + 1) = (*(img_gr_down + y * Width_down + x) + *(img_gr_down + y * Width_down + x + 1)) >> 1;
                *(img_gb + 2 * y * Width_half + 2 * x) = *(img_gb_down + y * Width_down + x);
                *(img_gb + 2 * y * Width_half + 2 * x + 1) = (*(img_gb_down + y * Width_down + x) + *(img_gb_down + y * Width_down + x + 1)) >> 1;
                *(img_b + 2 * y * Width_half + 2 * x) = *(img_b_down + y * Width_down + x);
                *(img_b + 2 * y * Width_half + 2 * x + 1) = (*(img_b_down + y * Width_down + x) + *(img_b_down + y * Width_down + x + 1)) >> 1;
            }
            *(img_r + 2 * y * Width_half + 2 * (Width_down - 1)) = *(img_r_down + y * Width_down + Width_down - 1);
            *(img_r + 2 * y * Width_half + 2 * (Width_down - 1) + 1) = *(img_r_down + y * Width_down + Width_down - 1);
            *(img_gr + 2 * y * Width_half + 2 * (Width_down - 1)) = *(img_gr_down + y * Width_down + Width_down - 1);
            *(img_gr + 2 * y * Width_half + 2 * (Width_down - 1) + 1) = *(img_gr_down + y * Width_down + Width_down - 1);
            *(img_gb + 2 * y * Width_half + 2 * (Width_down - 1)) = *(img_gb_down + y * Width_down + Width_down - 1);
            *(img_gb + 2 * y * Width_half + 2 * (Width_down - 1) + 1) = *(img_gb_down + y * Width_down + Width_down - 1);
            *(img_b + 2 * y * Width_half + 2 * (Width_down - 1)) = *(img_b_down + y * Width_down + Width_down - 1);
            *(img_b + 2 * y * Width_half + 2 * (Width_down - 1) + 1) = *(img_b_down + y * Width_down + Width_down - 1);
        }
        free(img_r_down);
        free(img_gr_down);
        free(img_gb_down);
        free(img_b_down);
    #endif
    #if 1
        for (x = 0; x < Width_half; x++)
        {
            for (y = 0; y < Height_down - 1; y += 2)
            {
                *(img_r + (2 * y + 1) * Width_half + x) = (*(img_r + (2 * y) * Width_half + x) + *(img_r + (2 * y + 2) * Width_half + x)) >> 1;
                *(img_gr + (2 * y + 1) * Width_half + x) = (*(img_gr + (2 * y) * Width_half + x) + *(img_gr + (2 * y + 2) * Width_half + x)) >> 1;
                *(img_gb + (2 * y + 1) * Width_half + x) = (*(img_gb + (2 * y) * Width_half + x) + *(img_gb + (2 * y + 2) * Width_half + x)) >> 1;
                *(img_b + (2 * y + 1) * Width_half + x) = (*(img_b + (2 * y) * Width_half + x) + *(img_b + (2 * y + 2) * Width_half + x)) >> 1;
            }
            *(img_r + (2 * (Height_down - 1) + 1) * Width_half + x) = *(img_r + (2 * (Height_down - 1)) * Width_half + x);
            *(img_gr + (2 * (Height_down - 1) + 1) * Width_half + x) = *(img_gr + (2 * (Height_down - 1)) * Width_half + x);
            *(img_gb + (2 * (Height_down - 1) + 1) * Width_half + x) = *(img_gb + (2 * (Height_down - 1)) * Width_half + x);
            *(img_b + (2 * (Height_down - 1) + 1) * Width_half + x) = *(img_b + (2 * (Height_down - 1)) * Width_half + x);
        }
    #endif
        //叠回第二次去噪图
        for (y = 0; y < Height_half; y++)
        {
            for (x = 0; x < Width_half; x++)
            {
                // printf("%d,%d \n", *(img_r + y * Width_half + x), data[2 * y * Width + 2 * x]);
                data_down[2 * y * Width + 2 * x] = *(img_r + y * Width_half + x);
                // printf("%d,%d \n", *(img_r + y * Width_half + x), data[2 * y * Width + 2 * x]);
                data_down[2 * y * Width + 2 * x + 1] = *(img_gr + y * Width_half + x);
                data_down[(2 * y + 1) * Width + 2 * x] = *(img_gb + y * Width_half + x);
                data_down[(2 * y + 1) * Width + 2 * x + 1] = *(img_b + y * Width_half + x);
            }
        }
        free(img_r);
        free(img_gr);
        free(img_gb);
        free(img_b);
        if ((w1 + w2) > 100)
        {
            printf("w1 + w2 > 100!\n");
            return;
        }
        // 叠回原图
        for (y = 0; y < Height_half; y++)
        {
            for (x = 0; x < Width_half; x++)
            {
                first_data[y * Width + x] = (u16)(((u32)*(data + y * Width + x)* w1 + *(data_down + y * Width + x) * w2 + \
                    *(first_data + y * Width + x) * (100 - w1 - w2)) / 100);
            }
        }
        // memcpy(first_data, data_down, Width* Height * sizeof(u16));
        free(y_data);
        free(data);
        free(data_down);
    }
    

    相关文章

      网友评论

          本文标题:raw域上的去噪

          本文链接:https://www.haomeiwen.com/subject/esejrltx.html