• ISP shading和 双线性插值代码


    在这里插入图片描述在这里插入图片描述

    import math
    import os
    
    import numpy as np
    import cv2
    from colour_demosaicing import demosaicing_CFA_Bayer_bilinear
    from matplotlib import pyplot as plt
    
    
    def black_sub(filename, height=800, width=800):
        raw_image = np.fromfile(filename, dtype=np.uint16)
        print(len(raw_image))
        raw_image = raw_image.reshape([height, width])
    
        # raw_image =raw_image>>6
        print('raw20x20 :\n', raw_image[20:30, 20:30])
        # black level
        black_level = 16
        white_level = 1023
        normalized_image = raw_image.astype(np.float32) - black_level
        # if some values were smaller than black level
        normalized_image[normalized_image < 0] = 0
        normalized_image = normalized_image / (white_level - black_level)
    
        print(normalized_image.min(), normalized_image.max())
        # plt.figure()
        # plt.imshow(normalized_image, cmap='gray')
        # plt.show()
        # demosciac
        # rgb = demosaicing_CFA_Bayer_Menon2007(normalized_image, "BGGR")
        rgb = demosaicing_CFA_Bayer_bilinear(normalized_image, "RGGB")
        rgb_save = rgb * 255
        rgb_save = np.clip(rgb_save, 0, 255)
        rgb_save = rgb_save.astype(np.uint8)
        cv2.imwrite(filename[:-4] + '_raw.png', rgb_save[..., ::-1])
    
        return normalized_image
    
    def bilinear_interp2(data, new_h, new_w):
        """
        与opencv的resize bilinear 函数一致
        :param data:
        :param new_h:
        :param new_w:
        :return:
        """
    
        h, w = data.shape
        out = np.zeros((new_h, new_w), dtype=np.float32)
        for i in range(new_h):
            for j in range(new_w):
                hv = (i+0.5)*h/new_h-0.5
                wv = (j+0.5)*w/new_w-0.5
                hh = math.floor(hv)
                ww = math.floor(wv)
                u = hv-hh
                v = wv-ww
    
                if hh < 0:
                    hh = 0
                    u = 0
                if hh >= h - 1:
                    hh = h - 2
                    u = 1.0
    
                if ww < 0:
                    ww = 0
                    v = 0
                if ww >= w - 1:
                    ww = w - 2
                    v = 1.0
    
                    #print(hh, ww)
                out[i, j] = (1-u)*(1-v)*data[hh, ww]+u*(1-v)*data[hh+1, ww]+(1-u)*v*data[hh, ww+1]+u*v*data[hh+1, ww+1]
        return out
    
    def bilinear_interp1(data, new_h, new_w):
    
        h, w = data.shape
        out = np.zeros((new_h, new_w), dtype=np.float32)
    
        # u_save = []
        for i in range(new_h):
            for j in range(new_w):
                hv = (i+0.5)*(h-1)/(new_h-1)-0.5
                wv = (j+0.5)*(w-1)/(new_w-1)-0.5
                hh = math.floor(hv)
                ww = math.floor(wv)
                u = hv-hh
                v = wv-ww
                #print(hh, ww)
                # u_save.append(u)
                out[i, j] = (1-u)*(1-v)*data[hh, ww]+u*(1-v)*data[hh+1, ww]+(1-u)*v*data[hh, ww+1]+u*v*data[hh+1, ww+1]
        # u_save = np.array(u_save)
        # np.savetxt('u1.txt', u_save.reshape([new_h, new_w]))
        return out
    
    
    def bilinear_interp(data, new_h, new_w):
        """
        :param data: origin data
        :param new_h: the height of dst
        :param new_w: the width of dst
        :return:
        """
        h, w = data.shape   # the height and width of origin data
        y = np.arange(new_h)
        x = np.arange(new_w)
        jj, ii = np.meshgrid(x, y)
    
        hv = (ii + 0.5) * (h - 1) / (new_h - 1) - 0.5
        wv = (jj + 0.5) * (w - 1) / (new_w - 1) - 0.5
    
        hh = np.floor(hv).astype(np.int32)
        ww = np.floor(wv).astype(np.int32)
        u = hv - hh
        v = wv - ww
        # np.savetxt('u0.txt', u.reshape([new_h, new_w]))
        # data = data.reshape(-1)
        # hh = hh.reshape(-1).astype(np.int)
        # ww = hh.reshape(-1).astype(np.int)
        # u = u.reshape(-1)
        # v = v.reshape(-1)
    
        w00 = (1-u)*(1-v)
        w01 = u * (1-v)
        w10 = (1-u) * v
        w11 = u*v
        out = w00 * data[hh, ww] + w10 * data[hh, ww + 1] + w01 * data[(hh + 1) ,ww] + w11 * data[hh + 1 , ww + 1]
    
    
        # out= (1 - u) * (1 - v) * data[hh, ww] + u * (1 - v) * data[hh + 1, ww] + (1 - u) * v * data[
        #     hh, ww + 1] + u * v * data[hh + 1, ww + 1]
        return out.reshape([new_h, new_w])
    
    def bilinear_interp3(data, new_h, new_w):
        """
        :param data: origin data
        :param new_h: the height of dst
        :param new_w: the width of dst
        :return:
        """
        h, w = data.shape   # the height and width of origin data
        y = np.arange(new_h)
        x = np.arange(new_w)
        jj, ii = np.meshgrid(x, y)
    
        hv = (ii + 0.5) * h/new_h - 0.5
        wv = (jj + 0.5) * w/new_w - 0.5
    
        hh = np.floor(hv).astype(np.int32)
        ww = np.floor(wv).astype(np.int32)
        u = hv - hh
        v = wv - ww
    
    
        u[hh < 0] = 0
        hh[hh < 0] = 0
        u[hh >= h - 1] = 1.0
        hh[hh >= h - 1] = h - 2
    
        v[ww < 0] = 0
        ww[ww < 0] = 0
        v[ww >= w - 1] = 1.0
        ww[ww >= w - 1] = w - 2
    
        # np.savetxt('u0.txt', u.reshape([new_h, new_w]))
        # data = data.reshape(-1)
        # hh = hh.reshape(-1).astype(np.int)
        # ww = hh.reshape(-1).astype(np.int)
        # u = u.reshape(-1)
        # v = v.reshape(-1)
    
        w00 = (1-u)*(1-v)
        w01 = u * (1-v)
        w10 = (1-u) * v
        w11 = u*v
        out = w00 * data[hh, ww] + w10 * data[hh, ww + 1] + w01 * data[(hh + 1) ,ww] + w11 * data[hh + 1 , ww + 1]
        # fpga中可以通过查找表来实现
        # 在初始尺寸以及目标尺寸确定之后(h,w,new_h,new_w), w00,w01,w10,w11这四个变量对于任何图像都是一致的和确定的。
        # hh, ww对于任何图像也是一致的和确定的
        # 因此首先保存下来,然后通过查找来实现
    
    
        return out.reshape([new_h, new_w])
    
    
    
    
    
    
    if __name__ == "__main__":
    
        interpolation = 'bilinear'  # cubic, area, nearest
        table_h = 40
        table_w = 40
        if interpolation == 'bilinear':
            inter = cv2.INTER_LINEAR
        elif interpolation == 'nearest':
            inter = cv2.INTER_NEAREST
        elif interpolation == 'cubic':
            inter = cv2.INTER_CUBIC
        elif interpolation == 'area':
            inter = cv2.INTER_AREA
        else:
            print('error input !')
        height = 800
        width = 800
        new_h = 400
        new_w = 400
    
        dir = r'D:\code\interp\image'
        files = os.listdir(dir)
        for file in files:
            if file.endswith('.raw'):
                filename = os.path.join(dir, file)
                normalized_image = black_sub(filename)
    
                run_pipe_shading = 1
                if run_pipe_shading:
                    # shading
                    # r_gain = np.loadtxt(r'D:\dataset\calib\shading\gains_mean_r.txt', dtype=np.float32)
                    # g_gain = np.loadtxt(r'D:\dataset\calib\shading\gains_mean_g.txt', dtype=np.float32)
                    # b_gain = np.loadtxt(r'D:\dataset\calib\shading\gains_mean_b.txt', dtype=np.float32)
    
                    r_gain = np.loadtxt(r'D:\code\interp\gains_mean_r.txt', dtype=np.float32)
                    g_gain = np.loadtxt(r'D:\code\interp\gains_mean_g.txt', dtype=np.float32)
                    b_gain = np.loadtxt(r'D:\code\interp\gains_mean_b.txt', dtype=np.float32)
                    # valid_table
    
                    r_gain = cv2.resize(r_gain, (table_h, table_w), interpolation=cv2.INTER_LINEAR)
                    g_gain = cv2.resize(g_gain, (table_h, table_w), interpolation=cv2.INTER_LINEAR)
                    b_gain = cv2.resize(b_gain, (table_h, table_w), interpolation=cv2.INTER_LINEAR)
    
                    np.savetxt(r'D:\code\interp\gains_mean_r' + interpolation + str(table_w) + '.txt', r_gain, fmt='%.7f')
                    np.savetxt(r'D:\code\interp\gains_mean_g' + interpolation + str(table_w) + '.txt', g_gain, fmt='%.7f')
                    np.savetxt(r'D:\code\interp\gains_mean_b' + interpolation + str(table_w) + '.txt', b_gain, fmt='%.7f')
    
                    # r_gain = cv2.resize(r_gain, (height // 2, width // 2), interpolation=inter)
                    # g_gain = cv2.resize(g_gain, (height // 2, width // 2), interpolation=inter)
                    # b_gain = cv2.resize(b_gain, (height // 2, width // 2), interpolation=inter)
    
                    r_gain = bilinear_interp3(r_gain, new_h, new_w)
                    g_gain = bilinear_interp3(g_gain, new_h, new_w)
                    b_gain = bilinear_interp3(b_gain, new_h, new_w)
    
                    normalized_image[0::2, 0::2] *= r_gain
                    normalized_image[1::2, 1::2] *= g_gain
                    normalized_image[0::2, 1::2] *= g_gain
                    normalized_image[1::2, 0::2] *= b_gain
    
                    rgb = demosaicing_CFA_Bayer_bilinear(normalized_image, "RGGB")
                    # brigtness_aline = 1
                    # if brigtness_aline:
                    #     rgb *= 2.7
    
                    rgb_save = rgb * 255
                    rgb_save = np.clip(rgb_save, 0, 255)
                    rgb_save = rgb_save.astype(np.uint8)
                    cv2.imwrite(filename[:-4] + 'z3_raw_shading_' + interpolation + str(table_w) + '.png',
                                rgb_save[..., ::-1])
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    1. c++版本code , 和opencv resize基本一致,因为有数据转换,所以有精度损失
      https://blog.csdn.net/hddryjv/article/details/83791042?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-83791042-blog-106761993.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-83791042-blog-106761993.pc_relevant_default&utm_relevant_index=2
      OpenCV中resize函数五种插值算法的实现过程
    #include <iostream>
    #include <opencv2/opencv.hpp>
    
    using namespace cv;
    //typedef unsigned char uchar;
    
    
    int bilinear_interp(Mat matSrc, Mat matDst1, Mat matDst2, float scale_x, float scale_y) {
        uchar* dataDst = matDst1.data; 
        int stepDst = matDst1.step; 
        uchar* dataSrc = matSrc.data; 
        int stepSrc = matSrc.step; 
        int iWidthSrc = matSrc.cols; 
        int iHiehgtSrc = matSrc.rows; 
    
        for (int j = 0; j < matDst1.rows; ++j) 
        { 
            float fy = (float)((j + 0.5) * scale_y - 0.5);  
            int sy = cvFloor(fy);  
            fy -= sy;  
            //sy = std::min(sy, iHiehgtSrc - 2);  
            //sy = std::max(0, sy);
            
            if (sy < 0)
            {
                fy = 0, sy = 0;
            }
            if (sy >= iHiehgtSrc - 1)
            {
                fy = 1.0, sy = iHiehgtSrc - 2;
            }
            
    
            short cbufy[2];  
            cbufy[0] = cv::saturate_cast<short>((1.f - fy) * 2048);  
            cbufy[1] = 2048 - cbufy[0];  
            for (int i = 0; i < matDst1.cols; ++i) 
            {
                float fx = (float)((i + 0.5) * scale_x - 0.5);   
                int sx = cvFloor(fx);   
                fx -= sx;   
                
                if (sx < 0) 
                { 
                    fx = 0, sx = 0; 
                }   
                if (sx >= iWidthSrc - 1) 
                { 
                    fx = 1.0, sx = iWidthSrc - 2; 
                }   
                
                short cbufx[2];   
                cbufx[0] = cv::saturate_cast<short>((1.f - fx) * 2048);   
                cbufx[1] = 2048 - cbufx[0];
    
                for (int k = 0; k < matSrc.channels(); ++k) 
                { 
                    *(dataDst + j * stepDst + 3 * i + k) = (*(dataSrc + sy * stepSrc + 3 * sx + k) * cbufx[0] * cbufy[0] + 
                                                            *(dataSrc + (sy + 1) * stepSrc + 3 * sx + k) * cbufx[0] * cbufy[1] + 
                                                            *(dataSrc + sy * stepSrc + 3 * (sx + 1) + k) * cbufx[1] * cbufy[0] + 
                                                            *(dataSrc + (sy + 1) * stepSrc + 3 * (sx + 1) + k) * cbufx[1] * cbufy[1]) >> 22;
                } 
            } 
        } 
        cv::imwrite("linear_12.jpg", matDst1); 
        
        cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 1); 
        cv::imwrite("linear_2.jpg", matDst2);
        return 1;
    }
    int main()
    {
        std::cout << "Hello World!\n";
    
        Mat img;  //
        img = imread("D:\\dataset\\\ccm\\2022-06-21-15-08-20_raw_gamma3.png");
        int width = img.cols;
        int height = img.rows;
    
        if (img.empty())  // 判断是否导入图片
        {
            std::cout << "请确认图片正确位置!" << std::endl;
            return -1;  // 返回-1
        }
        namedWindow("test", WINDOW_NORMAL);  // 创建一个常规窗口
    
        imshow("test", img);  // 展示图片
        waitKey(0);  // 获取键盘按键响应
    
    
        int dstHeight = height * 2;
        int dstWidth = width * 2;
    
        Mat img2(dstHeight, dstWidth, CV_8UC3), img3(dstHeight, dstWidth, CV_8UC3);
       
    
        float scale_x = 0.5;
        float scale_y = 0.5;
        bilinear_interp(img, img2, img3, scale_x, scale_y);
            
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
  • 相关阅读:
    《JAVA设计模式系列》解释器模式
    飞利浦zigbee智能灯泡的软硬件设计
    654. 最大二叉树(单调栈)
    AndroidStudio离线打包配置汇总
    五丰黎红引领新营销模式:布局一物一码数字化营销,提高调味品销量和复购率
    蓝桥杯[OJ 3791]—珠宝的最大交替和—CPP-贪心
    Spring Cloud | 实现Eureka Server 高可用服务注册中心全套解决方案
    ssm+共享图书管理系统 毕业设计-附源码151121
    Spring Boot单元测试
    Python+selenium自动化测试
  • 原文地址:https://blog.csdn.net/tywwwww/article/details/125487385