Navigation

    OpenASIC
    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    1. Home
    2. xiaowanwei
    X
    • Continue chat with xiaowanwei
    • Start new chat with xiaowanwei
    • Flag Profile
    • Block User
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups
    Save
    Saving

    xiaowanwei

    @xiaowanwei

    0
    Reputation
    5
    Posts
    1464
    Profile views
    0
    Followers
    0
    Following
    Joined Last Online

    xiaowanwei Follow

    Posts made by xiaowanwei

    • RE: xk-ISP code manuals

      AWB

      parameters

      typedef struct {
          bool m_nEb;
          uint15 r_gain;
          uint15 g_gain;
          uint15 b_gain;
          uint5 coeff;
      }awb_register;
      
      1. m_nEb

      awb module enable

      1. r_gain, g_gain, b_gain

      the output of r,g,b gain values

      1. coeff

      mean coefficient

      code manual

      code

      calculate the pixel sum for the r, g, b channel according to the bayerpattern

       uint2  bayerPattern = (((y & 1) << 1) + (x & 1))^top_reg.imgPattern;
      
       if (bayerPattern == 0)
       {
           r_total = r_total + src_t;
       }
       else if (bayerPattern == 1)
       {
           g_total = g_total + src_t;
       }
       else if (bayerPattern == 2)
       {
           g_total = g_total + src_t;
       }
       else
       {
           b_total = b_total + src_t;
       }
      

      calculate the pixel average for the r, g, b channel

      r_avg = (r_total * awb_reg.coeff) >> 19;
      g_avg = (g_total * awb_reg.coeff) >> 20;
      b_avg = (b_total * awb_reg.coeff) >> 19;
      

      calculate the r_gain, g_gain, b_gain

      awb_reg.r_gain = 16384 * g_avg / r_avg;
      awb_reg.g_gain = 16384;
      awb_reg.b_gain = 16384 * g_avg / b_avg;
      
      posted in xkISP
      X
      xiaowanwei
    • RE: xk-ISP code manuals

      dpc

      parameters

      typedef struct
      {
          bool     eb;
          uint11   th_w;
          uint11   th_b;
      }dpc_register;
      
      1. eb

      dpc module enable

      1. th_w

      hightlighted pixel threshold

      1. th_b

      dim pixel threshold

      code manual

      algorithm

      The pinto algorithm is used for processing. The pinto algorithm is based on the fact that a dead pixel is an extremely bright or dark pixel in its neighborhood, and the pixel value is the largest (smallest) value in the neighborhood. If the difference between the central pixel value and the surrounding pixel values is all positive or all negative, the point is a dead pixel which is replaced by the median value of the surrounding pixels; if the difference is both positive and negative, the point is considered normal and is not processed by the pinto algorithm. The templates of the R, G and B channels are selected separately for filtering.

      code

      dpc_loop_out:for(uint13 row = 0; row < top_reg.frameHeight; row++){
              dpc_loop_in:for(uint13 col = 0; col < top_reg.frameWidth; col++){
                  srcData = src.read();
                  if(dpc_reg.eb == 1){
                      rawWin_loop:for(uint3 i = 0; i < 5; i++){
                          rawWindow[i][0] = rawWindow[i][1];
                          rawWindow[i][1] = rawWindow[i][2];
                          rawWindow[i][2] = rawWindow[i][3];
                          rawWindow[i][3] = rawWindow[i][4];
                      }
      
                      rawWindow_read:for(uint3 i = 0; i < 4; i++){
                          rawWindow[i][4] = lineBuffer[i][col];
      
                      }
      
                      rawWindow[4][4] = srcData;
      
                      line_write:for(uint3 i = 0; i < 4; i++){
                          lineBuffer[i][col] = rawWindow[i+1][4];
      
                      }
      
                      if((row > 3)&&(col > 3)){
                          uint2 bayerPattern = (((row & 1) << 1) + (col & 1))^top_reg.imgPattern;
                          pixel = rawWindow[2][2];
                          
                          if(bayerPattern == 0 || bayerPattern == 3){
                              arr_ori[0] = rawWindow[0][0];
                              arr_ori[1] = rawWindow[0][2];
                              arr_ori[2] = rawWindow[0][4];
                              arr_ori[3] = rawWindow[2][0];
                              arr_ori[4] = rawWindow[2][4];
                              arr_ori[5] = rawWindow[4][0];
                              arr_ori[6] = rawWindow[4][2];
                              arr_ori[7] = rawWindow[4][4];
      
                              flag = defectPixelDetection(arr_ori, pixel, th_w, th_b);
                              if(flag == 1){
                                  dstData = medianFilter(arr_ori, arr_sort);
                              }
                              else{
                                  dstData = pixel;
                              }
                          }
                          else{
                              arr_ori[0] = rawWindow[0][2];
                              arr_ori[1] = rawWindow[1][1];
                              arr_ori[2] = rawWindow[1][3];
                              arr_ori[3] = rawWindow[2][0];
                              arr_ori[4] = rawWindow[2][4];
                              arr_ori[5] = rawWindow[3][1];
                              arr_ori[6] = rawWindow[3][3];
                              arr_ori[7] = rawWindow[4][2];
      
                              flag = defectPixelDetection(arr_ori, pixel, th_w, th_b);
                              if(flag == 1){
                                  dstData = medianFilter(arr_ori, arr_sort);
                              }
                              else{
                                  dstData = pixel;
                              }
                          }
                      }
                      else{
                          dstData = 0;
                      }
                  }
                  else
                  {
                      dstData = srcData;
                  }
                  if((row > 2) || ((row==2) && (col > 1))){
                      
                      dst.write(dstData);
                  }
              }
          }
      

      If dpc_reg.eb = 1 get the 5x5 windows to evaluate if the centre point is a dead pixel.

      rawWin_loop:for(uint3 i = 0; i < 5; i++){
        rawWindow[i][0] = rawWindow[i][1];
        rawWindow[i][1] = rawWindow[i][2];
        rawWindow[i][2] = rawWindow[i][3];
        rawWindow[i][3] = rawWindow[i][4];
      }
      
      rawWindow_read:for(uint3 i = 0; i < 4; i++){
        rawWindow[i][4] = lineBuffer[i][col];
      
      }
      
      rawWindow[4][4] = srcData;
      
      line_write:for(uint3 i = 0; i < 4; i++){
        lineBuffer[i][col] = rawWindow[i+1][4];
      
      }
      

      Dead pixel detection. Get the difference between center pixel and surrounding pixel, if the difference bigger than th_w, the center pixel is a hightlighted pixel, and if the difference smaller than th_b, the center pixel is a dim pixel. These two cases return 1, the center pixel is a dead pixel.

      bool defectPixelDetection(uint12 arr_ori[8], uint12 pixel, uint11 th_w, uint11 th_b){
          int12 th_1 = th_w;
          int12 th_2 = -th_b;
      
          int13 diff_0;
          int13 diff_1;
          int13 diff_2;
          int13 diff_3;
          int13 diff_4;
          int13 diff_5;
          int13 diff_6;
          int13 diff_7;
      
          bool rst;
      
          diff_0 = arr_ori[0] - pixel;
          diff_1 = arr_ori[1] - pixel;
          diff_2 = arr_ori[2] - pixel;
          diff_3 = arr_ori[3] - pixel;
          diff_4 = arr_ori[4] - pixel;
          diff_5 = arr_ori[5] - pixel;
          diff_6 = arr_ori[6] - pixel;
          diff_7 = arr_ori[7] - pixel;
      
          if (diff_0 < th_2 && diff_1 < th_2 && diff_2 < th_2 && diff_3 < th_2 && diff_4 < th_2 && diff_5 < th_2 && diff_6 < th_2 && diff_7 < th_2) {
              rst = 1; //defect pixel, black defect pixl
          }
          else if(diff_0 > th_1 && diff_1 > th_1 && diff_2 > th_1 && diff_3 > th_1 && diff_4 > th_1 && diff_5 > th_1 && diff_6 > th_1 && diff_7 > th_1)
          {
              rst = 1; //defect pixel, white defect pixel
          }
          else
          {
              rst = 0; //right pixel
          }
      
          return rst;
      }
      

      Median filter. The median filter first selects an i, does not sort for the time being for the corresponding value of j greater than i, makes a sort from smallest to largest for the corresponding value of j less than or equal to i, i traverses all the numbers, can get the original eight numbers from smallest to largest arrangement, finally takes the average of arr_sort[3] and arrsort[4] to get the median.

      uint12 medianFilter(uint12 arr_ori[8], uint12 arr_sort[8]){
          uint12 item;
          uint12 t; //tmp value
          uint13 result;
          MF_outer:for (int6 i = 0; i < 8; i++)
          {
              item = arr_ori[i];
      
              MF_inter:for (int6 j = 7; j >= 0; j--) {
                  if (j > i) {
                      t = arr_sort[j];
                  }
                  else if (j > 0 && arr_sort[j - 1] > item)
                  {
                      t = arr_sort[j - 1];
                  }
                  else
                  {
                      t = item;
                      if (j > 0)
                          item = arr_sort[j - 1];
                  }
                  arr_sort[j] = t;
              }
      
          }
      
          result = (arr_sort[3] + arr_sort[4]) >> 1;
          return result;
      }
      

      Finally the dead pixels are replaced by the median value and the good pixels are left unprocessed to obtain the output

      posted in xkISP
      X
      xiaowanwei
    • RE: xk-ISP code manuals

      dgain

      parameter

      typedef struct{
          bool    m_nEb;
          uint9   m_nBlcR;
          uint9   m_nBlcGr;
          uint9   m_nBlcGb;
          uint9   m_nBlcB;
          uint20  m_nR;
          uint20  m_nGr;
          uint20  m_nGb;
          uint20  m_nB;
      } dgain_register;
      
      1. m_nEb

        dgain module enable

      2. m_nBlcR, m_nBlcGr, m_nBlcGb, m_nBlcB

        R, Gr, Gb, B channel black level correction values

      3. m_nR, m_nGr, m_nGb, m_nB
        Bayer array R, Gr, Gb,B channel gain values

      dgain code manual

      src_t = src.read get the input values of input pixels. if the m_nEb == 1, calculate the bayerPattern, for example, if the top_reg.imgPattern = 0, so, bayerPattern = 0, channel is r channel; bayerPattern = 1, channel is gr channel; bayerPattern = 10, channel is gb channel; bayerPattern = 11, channel is b channel. Choose the gain_w channel and blc_w channel according to the bayerPattern, the code is shown below:

      if (bayerPattern == 0) {
          blc_w = dgain_reg.m_nBlcR;
          gain_w = dgain_reg.m_nR;
      } else if (bayerPattern == 1) {
          blc_w = dgain_reg.m_nBlcGr;
          gain_w = dgain_reg.m_nGr;
      } else if (bayerPattern == 2) {
          blc_w = dgain_reg.m_nBlcGb;
          gain_w = dgain_reg.m_nGb;
      } else {
          blc_w = dgain_reg.m_nBlcB;
          gain_w = dgain_reg.m_nB;
      }
      

      Finally the output pixel values are calculated from the input values, gain values and black level correction values.
      the code is shown below:

      dst_tmp = (src_t - blc_w) * gain_w + GAIN_HALF_VALUE;
      dst_val = (dst_tmp >> GAIN_BITS) + top_reg.blc;
      dst_t = dgain_clip(dst_val,0,4095);
      

      if m_nEb = 0, directly output of input pixel values

      posted in xkISP
      X
      xiaowanwei
    • xk-ISP code manuals

      tpg.md

      parameters

      typedef struct{
          bool    m_bTPG_en;
          uint13  m_nWidth;
          uint13  m_nHeight;
          uint2   m_nCFAPattern;
          bool    m_bRollingEnable;
          bool    m_bSensor_timing_en;
          uint12  m_nVBlank_num;
          uint12  m_nHBlank_num;
          uint8   m_valid_blank; 
          uint3   m_nID;
      } tpg_register;
      
      1. m_bTPG_en

        tpg module enable

      2. m_nWidth

        Parameter to be added

      3. m_nHeight

        Parameters to be added

      4. m_nCFAPattern

        CFA pattern ({0, 1, 2, 3} map to {rggb, grgb, bggr})

      5. m_bRollingEnable

        Parameters to be added

      6. m_bSensor_timeing_en

        Parameters to be added

      7. m_nVBlank_num

        Parameters to be added

      8. m_nHBlank_num

        Parameters to be added

      9. m_valid_blank

        Parameters to be added

      10. m_nID

        Initial colour block ID

      code manual

      algorithm flow

          tpg_row: for(uint13 i = 0; i < top_reg.frameHeight; i++){
              cnt = 0;
              BlockID = 0;
              tpg_col: for(uint13 j = 0; j < top_reg.frameWidth; j++){
                  if(tpg_reg.m_bTPG_en == 1) {
                      if (cnt == BlockWidth){
                          cnt = 1;
                          BlockID++;
                      } else {
                          cnt++;
                      }
      
                      if(BlockID > 7){
                          BlockID = 7;
                      }
                      dst_t =src.read();
      
                      channel = (((i & 1) << 1) + (j & 1))^top_reg.imgPattern;
                      dst_t   = ColorSelect(channel, BlockID, tpg_reg);
                      dst.write(dst_t);
                  } else {
                      dst_t = src.read();
                      dst.write(dst_t);
                      #ifdef DEBUG
                      if((i == ROW_TEST) && (j == COL_TEST)) {
                          printf("\t tpg_in = %x\n",dst_t.to_int());
                      }
                      #endif
                  }
              }
          }
      

      in tpg function, for the same col, there are same pixels in the output test image. for the same row, if the cnt == BlockWidth, cnt return to 1, and BlockID++, Different BlockID correspond to different colours, and the BlockWidthis the width of one color. channel is the bayer channel, for example, if the top_reg.imgPattern = 0, so, channel = 0, channel is r channel; channel = 1, channel is gr channel; channel = 10, channel is gb channel; channel = 11, channel is b channel. The output is then based on the ColorSelect function

      for the ColorSelect function, it use these code to update the initial color block.

      if(tpg_reg.m_bRollingEnable){
         RealID += tpg_reg.m_nID;
         if (RealID > 7){
             RealID -= 8;
         }
      }
      

      Then fill in the colours according to the realID, The correspondence is as follows:

      realID:
          0 -> white;
          1 -> black;
          2 -> red;
          3 -> green;
          4 -> blue;
          5 -> cyan(B+G);
          6 -> magenta(R+B);
          7 -> yellow(R+G);
      
      posted in xkISP
      X
      xiaowanwei
    • 1 / 1