예제 #1
0
파일: yuv.cpp 프로젝트: tempbottle/fawkes
/** Copy part of the U anv V planes of a YUV422planar image to another
 */
void
yuv422planar_copy_uv(const unsigned char *src, unsigned char *dst,
		     unsigned int width, unsigned int height,
		     unsigned int x, unsigned int y,
		     unsigned int copy_width, unsigned int copy_height)
{

  const unsigned char *sup = YUV422_PLANAR_U_PLANE(src, width, height) + (x / 2);
  const unsigned char *svp = YUV422_PLANAR_V_PLANE(src, width, height) + (x / 2);

  unsigned char *dup = YUV422_PLANAR_U_PLANE(dst, width, height) + (x / 2);
  unsigned char *dvp = YUV422_PLANAR_V_PLANE(dst, width, height) + (x / 2);

  unsigned int w;
  unsigned int h;

  unsigned const char *lsup = sup, *lsvp = svp, *ldup = dup, *ldvp = dvp;

  for (h = 0; h < copy_height; ++h) {
    for ( w = 0; w < copy_width; w += 2 ) {
      *dup++ = *sup++;
      *dvp++ = *svp++;
    }
    lsup += width / 2;
    lsvp += width / 2;
    ldup += width / 2;
    ldvp += width / 2;
  }
}
예제 #2
0
파일: lossy.cpp 프로젝트: fuxiang90/fawkes
void
LossyScaler::scale()
{
  if ( orig_width  == 0 ) return;
  if ( orig_height == 0 ) return;
  if ( scal_width  == 0 ) return;
  if ( scal_height == 0 ) return;
  if ( orig_buffer == NULL ) return;
  if ( scal_buffer == NULL ) return;
  if ( scal_width < needed_scaled_width() ) return;
  if ( scal_height < needed_scaled_height() ) return;

  float skip = 1 / scale_factor;
  unsigned char *oyp = orig_buffer;
  unsigned char *oup = YUV422_PLANAR_U_PLANE( orig_buffer, orig_width, orig_height );
  unsigned char *ovp = YUV422_PLANAR_V_PLANE( orig_buffer, orig_width, orig_height );

  unsigned char *syp = scal_buffer;
  unsigned char *sup = YUV422_PLANAR_U_PLANE( scal_buffer, scal_width, scal_height );
  unsigned char *svp = YUV422_PLANAR_V_PLANE( scal_buffer, scal_width, scal_height );

  memset( syp,   0, scal_width * scal_height );
  memset( sup, 128, scal_width * scal_height );

  float oh_float = 0.0;
  float ow_float = 0.0;

  unsigned int oh_pixel;
  unsigned int ow_pixel;
  unsigned int ow_pixel_next;

  for (unsigned int h = 0; h < scal_height; ++h) {
    oh_pixel = (unsigned int) rint(oh_float);
    ow_float = 0.0;

    if (oh_pixel >= orig_height) {
      oh_pixel = orig_height - 1;
    }
    for (unsigned int w = 0; w < scal_width; w += 2) {
      ow_pixel = (unsigned int) rint(ow_float);
      ow_pixel_next = (unsigned int) rint( ow_float + skip);
      
      if (ow_pixel >= orig_width) {
	ow_pixel = orig_width - 1;
      }

      if (ow_pixel_next >= orig_width) {
	ow_pixel_next = orig_width - 1;
      }

      syp[ h * scal_width + w ] = oyp[ oh_pixel * orig_width + ow_pixel ];
      syp[ h * scal_width + w + 1 ] = oyp[ oh_pixel * orig_width + ow_pixel_next ];
      sup[ (h * scal_width + w) / 2 ] = (oup[ (oh_pixel * orig_width + ow_pixel) / 2 ] + oup[ (oh_pixel * orig_width + ow_pixel_next) / 2 ]) / 2;
      svp[ (h * scal_width + w) / 2 ] = (ovp[ (oh_pixel * orig_width + ow_pixel) / 2 ] + ovp[ (oh_pixel * orig_width + ow_pixel_next) / 2 ]) / 2;

      ow_float += 2 * skip;
    }
    oh_float += skip;
  }
}
예제 #3
0
파일: yuv.cpp 프로젝트: tempbottle/fawkes
/** Copy part of the U anv V planes of a YUV422planar image to another
 */
void
yuv420planar_to_yuv422planar(const unsigned char *src, unsigned char *dst,
			     unsigned int width, unsigned int height)
{
  const unsigned char *sup = YUV420_PLANAR_U_PLANE(src, width, height);
  const unsigned char *svp = YUV420_PLANAR_V_PLANE(src, width, height);

  unsigned char *dup       = YUV422_PLANAR_U_PLANE(dst, width, height);
  unsigned char *dvp       = YUV422_PLANAR_V_PLANE(dst, width, height);

  unsigned int h;

  // cp Y plane
  memcpy(dst, src, width * height);

  for (h = 0; h < height / 2; ++h) {
    // cp U line twice!
    memcpy(dup, sup, width / 2);
    dup += width / 2;
    memcpy(dup, sup, width / 2);
    dup += width / 2;
    sup += width / 2;

    // cp V line twice!
    memcpy(dvp, svp, width / 2);
    dvp += width / 2;
    memcpy(dvp, svp, width / 2);
    dvp += width / 2;
    svp += width / 2;
  }
}
예제 #4
0
/** Get mass point of primary color.
 * @param roi ROI to consider
 * @param massPoint contains mass point upon return
 */
void
SimpleColorClassifier::get_mass_point_of_color( ROI *roi,
        fawkes::upoint_t *massPoint )
{
    unsigned int nrOfOrangePixels;
    nrOfOrangePixels = 0;
    massPoint->x     = 0;
    massPoint->y     = 0;

    // for accessing ROI pixels
    register unsigned int h = 0;
    register unsigned int w = 0;
    // planes
    register unsigned char *yp   = _src + (roi->start.y * roi->line_step) + (roi->start.x * roi->pixel_step);
    register unsigned char *up   = YUV422_PLANAR_U_PLANE(_src, roi->image_width, roi->image_height)
                                   + ((roi->start.y * roi->line_step) / 2 + (roi->start.x * roi->pixel_step) / 2) ;
    register unsigned char *vp   = YUV422_PLANAR_V_PLANE(_src, roi->image_width, roi->image_height)
                                   + ((roi->start.y * roi->line_step) / 2 + (roi->start.x * roi->pixel_step) / 2);
    // line starts
    unsigned char *lyp  = yp;
    unsigned char *lup  = up;
    unsigned char *lvp  = vp;

    color_t dcolor;

    // consider each ROI pixel
    for (h = 0; h < roi->height; ++h) {
        for (w = 0; w < roi->width; w += 2) {
            // classify its color
            dcolor = color_model->determine(*yp++, *up++, *vp++);
            yp++;
            // ball pixel?
            if (color == dcolor) {
                // take into account its coordinates
                massPoint->x += w;
                massPoint->y += h;
                nrOfOrangePixels++;
            }
        }
        // next line
        lyp  += roi->line_step;
        lup  += roi->line_step / 2;
        lvp  += roi->line_step / 2;
        yp    = lyp;
        up    = lup;
        vp    = lvp;
    }

    // to obtain mass point, divide by number of pixels that were added up
    massPoint->x = (unsigned int) (float(massPoint->x) / float(nrOfOrangePixels));
    massPoint->y = (unsigned int) (float(massPoint->y) / float(nrOfOrangePixels));

    /* shift mass point
     such that it is relative to image
     (not relative to ROI) */
    massPoint->x += roi->start.x;
    massPoint->y += roi->start.y;
}
예제 #5
0
파일: yuv.cpp 프로젝트: tempbottle/fawkes
/** 8-Bit gray to YUV422_PLANAR
 */
void
gray8_to_yuv422planar_plainc(const unsigned char *src, unsigned char *dst,
			     unsigned int width, unsigned int height)
{
  // copy Y plane
  memcpy(dst, src, width * height);
  // set U and V plane
  memset(YUV422_PLANAR_U_PLANE(dst, width, height), 128, width * height);
}
예제 #6
0
파일: yuv.cpp 프로젝트: tempbottle/fawkes
/* Convert quarter YUV422 planar buffer to plain YUV422 planar.
 * @param quarter input buffer in YUV422_PLANAR_QUARTER
 * @param output buffer in YUV422_PLANAR
 * @param width width of the image (width of YUV422_PLANAR image)
 * @param height height of the image (height of YUV422_PLANAR image)
 */
void
yuv422planar_quarter_to_yuv422planar(const unsigned char *quarter,
				     unsigned char *planar,
				     const unsigned int width,
				     const unsigned int height)
{
  volatile const unsigned char *y, *u, *v;
  unsigned int w, h;

  const unsigned int w_h_4 = (width * height) / 4;
  const unsigned int w_h_8 = (width * height) / 8;
  //const unsigned int w_t_2   = width * 2;
  const unsigned int w_b_2   = width / 2;
  const unsigned int w_b_4   = width / 4;

  unsigned char *yp, *up, *vp, t;
  yp = planar;
  up = YUV422_PLANAR_U_PLANE(planar, width, height);
  vp = YUV422_PLANAR_V_PLANE(planar, width, height);

  for (h = 0; h < height / 2; ++h) {
    y  = quarter + (h * w_b_2);
    u  = quarter + w_h_4 + (h * w_b_4);
    v  = quarter + w_h_4 + w_h_8 + (h * w_b_4);

    for (w = 0; w < w_b_4; ++w) {
      t = *y++;
      *yp++ = t;
      *yp++ = t;
      t = *y++;
      *yp++ = t;
      *yp++ = t;
      t = *u++;
      *up++ = t;
      *up++ = t;
      t = *v++;
      *vp++ = t;
      *vp++ = t;
    }

    memcpy(yp, yp - width, width);
    memcpy(up, up - w_b_2, w_b_2);
    memcpy(vp, vp - w_b_2, w_b_2);
    yp += width;
    up += w_b_2;
    vp += w_b_2;
  }

}
예제 #7
0
파일: bayer.cpp 프로젝트: tempbottle/fawkes
void
bayerGBRG_to_yuv422planar_nearest_neighbour(const unsigned char *bayer, unsigned char *yuv,
					    unsigned int width, unsigned int height)
{
  unsigned char *y = yuv;
  unsigned char *u = YUV422_PLANAR_U_PLANE(yuv, width, height);
  unsigned char *v = YUV422_PLANAR_V_PLANE(yuv, width, height);
  const unsigned char *b = bayer;

  int y1, u1, v1, y2, u2, v2;
  int t1, t2;

  for ( unsigned int h = 0; h < height; h += 2) {

    // g  b  ... line
    for (unsigned int w = 0; w < width; w += 2) {
      t1 = b[width];
      t2 = b[1];
      RGB2YUV(t1, *b, t2, y1, u1, v1);
      ++b;

      t1 = b[width - 1];
      t2 = b[-1];
      RGB2YUV(t1, t2, *b, y2, u2, v2);
      ++b;

      assign(y, u, v, y1, u1, v1, y2, u2, v2);
    }

    // r  g  ... line
    for (unsigned int w = 0; w < width; w += 2) {
      t1 = b[1];
      t2 = b[-width+1];
      RGB2YUV(*b, t1, t2, y1, u1, v1);
      ++b;

      t1 = b[-1];
      t2 = b[-width];
      RGB2YUV(t1, *b, t2, y2, u2, v2);
      ++b;

      assign(y, u, v, y1, u1, v1, y2, u2, v2);
    }
  }
}
예제 #8
0
/** Create image from LUT.
 * Create image from LUT, useful for debugging and analysing.
 * This method produces a representation of the given level
 * (Y range with 0 <= level < depth) for visual inspection of the colormap.
 * The dimensions of the resulting image are 512x512 pixels. It uses standard strong
 * colors for the different standard color classes. C_UNKNOWN is grey, C_BACKGROUND
 * is black (like C_BLACK).
 * If the standard method does not suit your needs you can override this method.
 * @param yuv422_planar_buffer contains the image upon return, must be initialized
 * with the appropriate memory size before calling, dimensions are 512x512 pixels.
 * @param level the level to draw, it's a range in the Y direction and is in the
 * range 0 <= level < depth.
 */
void
Colormap::to_image(unsigned char *yuv422_planar_buffer, unsigned int level)
{
  unsigned int iwidth  = image_width()  / 2;
  unsigned int iheight = image_height() / 2;

  unsigned int lwidth  = width();
  unsigned int lheight = height();

  unsigned int pixel_per_step = iheight / lheight;
  unsigned int lines_per_step = iwidth  / lwidth;

  unsigned char *yp = yuv422_planar_buffer;
  unsigned char *up = YUV422_PLANAR_U_PLANE(yuv422_planar_buffer, iwidth * 2, iheight * 2);
  unsigned char *vp = YUV422_PLANAR_V_PLANE(yuv422_planar_buffer, iwidth * 2, iheight * 2);

  unsigned int y = level * deepness() / depth();

  YUV_t c;
  for (unsigned int v = lwidth; v > 0 ; --v) {
    unsigned int v_index = (v - 1) * deepness() / lwidth;
    for (unsigned int u = 0; u < lheight; ++u) {
      unsigned int u_index = u * deepness() / lheight;
      c = ColorObjectMap::get_color(determine(y, u_index, v_index));

      for (unsigned int p = 0; p < pixel_per_step; ++p) {
	*yp++ = c.Y;
	*yp++ = c.Y;
	*up++ = c.U;
	*vp++ = c.V;
      }
    }
    // Double line
    unsigned int lines = (2 * (lines_per_step - 1)) + 1;
    memcpy(yp, (yp - iwidth * 2), (iwidth * 2) * lines);
    yp += (iwidth * 2) * lines;
    memcpy(up, (up - iwidth), iwidth * lines);
    memcpy(vp, (vp - iwidth), iwidth * lines);
    up += iwidth * lines;
    vp += iwidth * lines;
  }
}
예제 #9
0
파일: bayer.cpp 프로젝트: tempbottle/fawkes
void
bayerRGGB_to_yuv422planar_nearest_neighbour(const unsigned char *bayer,
					    unsigned char *yuv,
					    unsigned int width,
					    unsigned int height)
{
  unsigned char *y = yuv;
  unsigned char *u = YUV422_PLANAR_U_PLANE(yuv, width, height);
  unsigned char *v = YUV422_PLANAR_V_PLANE(yuv, width, height);
  const unsigned char *b = bayer;

  int y1, u1, v1, y2, u2, v2;

  for ( unsigned int h = 0; h < height; h += 2) {

    // r  g  ... line
    for (unsigned int w = 0; w < width; w += 2) {
      RGB2YUV(*b, b[1], b[width+1], y1, u1, v1);
      ++b;

      RGB2YUV(b[-1], *b, b[width], y2, u2, v2);
      ++b;

      assign(y, u, v, y1, u1, v1, y2, u2, v2);
    }

    // g  b  ... line
    for (unsigned int w = 0; w < width; w += 2) {
      RGB2YUV(*(b-width), *b, b[1], y1, u1, v1);
      ++b;

      RGB2YUV(*(b-width-1), b[-1], *b, y2, u2, v2);
      ++b;

      assign(y, u, v, y1, u1, v1, y2, u2, v2);
    }
  }
}
예제 #10
0
파일: sum.cpp 프로젝트: timn/fawkes
void
FilterSum::apply()
{
  if ( src[0] == NULL ) return;
  if ( src[1] == NULL ) return;
  if ( src_roi[0] == NULL ) return;
  if ( src_roi[1] == NULL ) return;

  unsigned int h = 0;
  unsigned int w = 0;


  // y-plane
  unsigned char *byp   = src[0] + (src_roi[0]->start.y * src_roi[0]->line_step) + (src_roi[0]->start.x * src_roi[0]->pixel_step);
  // u-plane
  unsigned char *bup   = YUV422_PLANAR_U_PLANE(src[0], src_roi[0]->image_width, src_roi[0]->image_height)
    + ((src_roi[0]->start.y * src_roi[0]->line_step) / 2 + (src_roi[0]->start.x * src_roi[0]->pixel_step) / 2) ;
  // v-plane
  unsigned char *bvp   = YUV422_PLANAR_V_PLANE(src[0], src_roi[0]->image_width, src_roi[0]->image_height)
    + ((src_roi[0]->start.y * src_roi[0]->line_step) / 2 + (src_roi[0]->start.x * src_roi[0]->pixel_step) / 2);


  // y-plane
  unsigned char *fyp   = src[1] + (src_roi[1]->start.y * src_roi[1]->line_step) + (src_roi[1]->start.x * src_roi[1]->pixel_step);
  // u-plane
  unsigned char *fup   = YUV422_PLANAR_U_PLANE(src[1], src_roi[1]->image_width, src_roi[1]->image_height)
    + ((src_roi[1]->start.y * src_roi[1]->line_step) / 2 + (src_roi[1]->start.x * src_roi[1]->pixel_step) / 2) ;
  // v-plane
  unsigned char *fvp   = YUV422_PLANAR_V_PLANE(src[1], src_roi[1]->image_width, src_roi[1]->image_height)
    + ((src_roi[1]->start.y * src_roi[1]->line_step) / 2 + (src_roi[1]->start.x * src_roi[1]->pixel_step) / 2);


  // destination y-plane
  unsigned char *dyp  = dst + (dst_roi->start.y * dst_roi->line_step) + (dst_roi->start.x * dst_roi->pixel_step);
  // destination u-plane
  unsigned char *dup   = YUV422_PLANAR_U_PLANE(dst, dst_roi->image_width, dst_roi->image_height)
    + ((dst_roi->start.y * dst_roi->line_step) / 2 + (dst_roi->start.x * dst_roi->pixel_step) / 2) ;
  // destination v-plane
  unsigned char *dvp   = YUV422_PLANAR_V_PLANE(dst, dst_roi->image_width, dst_roi->image_height)
    + ((dst_roi->start.y * dst_roi->line_step) / 2 + (dst_roi->start.x * dst_roi->pixel_step) / 2);
  
  // line starts
  unsigned char *lbyp = byp;   // y-plane
  unsigned char *lbup = fup;   // u-plane
  unsigned char *lbvp = fvp;   // v-plane
  unsigned char *lfyp = fyp;   // y-plane
  unsigned char *lfup = fup;   // u-plane
  unsigned char *lfvp = fvp;   // v-plane
  unsigned char *ldyp = dyp;  // destination y-plane
  unsigned char *ldup = dup;  // destination u-plane
  unsigned char *ldvp = dvp;  // destination v-plane

  for (h = 0; (h < src_roi[1]->height) && (h < dst_roi->height); ++h) {
    for (w = 0; (w < src_roi[1]->width) && (w < dst_roi->width); w += 2) {
      *dyp++ = ((*byp + *fyp) > 255) ? 255 : (*byp + *fyp);
      ++byp; ++fyp;
      *dyp++ = ((*byp + *fyp) > 255) ? 255 : (*byp + *fyp);
      ++byp; ++fyp;

      *dup++ = (*fup++ + *bup++) / 2;
      *dvp++ = (*fvp++ + *bvp++) / 2;
    }

    lbyp   += src_roi[0]->line_step;
    lbup   += src_roi[0]->line_step / 2;
    lbvp   += src_roi[0]->line_step / 2;
    lfyp   += src_roi[1]->line_step;
    lfup   += src_roi[1]->line_step / 2;
    lfvp   += src_roi[1]->line_step / 2;
    ldyp  += dst_roi->line_step;
    ldup  += dst_roi->line_step / 2;
    ldvp  += dst_roi->line_step / 2;
    byp    = lbyp;
    bup    = lbup;
    bvp    = lbvp;
    fyp    = lfyp;
    fup    = lfup;
    fvp    = lfvp;
    dyp    = ldyp;
    dup    = ldup;
    dvp    = ldvp;
  }

}
예제 #11
0
파일: bayer.cpp 프로젝트: tempbottle/fawkes
void
bayerGBRG_to_yuv422planar_bilinear(const unsigned char *bayer, unsigned char *yuv,
				   unsigned int width, unsigned int height)
{
  unsigned char *y = yuv;
  unsigned char *u = YUV422_PLANAR_U_PLANE(yuv, width, height);
  unsigned char *v = YUV422_PLANAR_V_PLANE(yuv, width, height);
  const unsigned char *bf = bayer;

  int y1, u1, v1, y2, u2, v2;
  int r, g, b;

  // first line is special
  // g  b  ... line
  // not full data in first columns
  RGB2YUV(bf[width], *bf, bf[1], y1, u1, v1);
  ++bf;

  r = (bf[width - 1] + bf[width + 1]) >> 1;
  // correct:
  // g = (bf[-1] + bf[width] + bf[1]) / 3;
  // faster:
  g = (bf[-1] + bf[1]) >> 1;
  RGB2YUV(r, g, *bf, y2, u2, v2);
  ++bf;

  assign(y, u, v, y1, u1, v1, y2, u2, v2);

  // rest of first line
  for (unsigned int w = 2; w < width - 2; w += 2) {
    b = (bf[-1] + bf[1]) >> 1;
    RGB2YUV(bf[width], *bf, b, y1, u1, v1);
    ++bf;

    r = (bf[width - 1] + bf[width + 1]) >> 1;
    // correct:
    // g = (bf[-1] + bf[width] + bf[1]) / 3;
    // faster:
    g = (bf[-1] + bf[1]) >> 1;
    RGB2YUV(r, g, *bf, y2, u2, v2);
    ++bf;

    assign(y, u, v, y1, u1, v1, y2, u2, v2);
  }

  // not full data in last columns
  b = (bf[-1] + bf[1]) >> 1;
  RGB2YUV(bf[width], *bf, b, y1, u1, v1);
  ++bf;

  g = (bf[-1] + bf[width]) >> 1;
  RGB2YUV(bf[width - 1], g, *bf, y2, u2, v2);
  ++bf;

  assign(y, u, v, y1, u1, v1, y2, u2, v2);

  for ( unsigned int h = 1; h < height - 1; h += 2) {

    // r  g  ... line
    // correct: g = (bf[-width] + bf[1] + bf[width]) / 3;
    // faster:
    g = (bf[-width] + bf[1]) >> 1;
    b = (bf[width-1] + bf[width+1]) >> 1;
    RGB2YUV(*bf, g, b, y1, u1, v1);
    ++bf;

    r = (bf[-1] + bf[1]) >> 1;
    b = (bf[-width] + bf[width]) >> 1;
    RGB2YUV(r, *bf, b, y2, u2, v2);
    ++bf;

    assign(y, u, v, y1, u1, v1, y2, u2, v2);

    for (unsigned int w = 2; w < width - 2; w += 2) {
      g = (bf[-width] + bf[1] + bf[width] + bf[-1]) >> 2;
      b = (bf[-width-1] + bf[-width+1] + bf[width-1] + bf[width+1]) >> 2;
      RGB2YUV(*bf, g, b, y1, u1, v1);
      ++bf;

      r = (bf[-1] + bf[1]) >> 1;
      b = (bf[-width] + bf[width]) >> 1;
      RGB2YUV(r, *bf, b, y2, u2, v2);
      ++bf;

      assign(y, u, v, y1, u1, v1, y2, u2, v2);
    }

    g = (bf[-width] + bf[1] + bf[width] + bf[-1]) >> 2;
    b = (bf[-width-1] + bf[-width+1] + bf[width-1] + bf[width+1]) >> 2;
    RGB2YUV(*bf, g, b, y1, u1, v1);
    ++bf;

    b = (bf[-width] + bf[width]) >> 1;
    RGB2YUV(bf[-1], *bf, g, y2, u2, v2);
    ++bf;

    assign(y, u, v, y1, u1, v1, y2, u2, v2);



    // g  b  ... line
    r = (bf[width] + bf[-width]) >> 1;
    RGB2YUV(r, *bf, bf[1], y1, u1, v1);
    ++bf;

    r = (bf[-width-1] + bf[-width+1] + bf[width - 1] + bf[width + 1]) >> 2;
    g = (bf[-width] + bf[1] + bf[width] + bf[-1]) >> 2;
    RGB2YUV(r, g, *bf, y2, u2, v2);
    ++bf;

    assign(y, u, v, y1, u1, v1, y2, u2, v2);

    for (unsigned int w = 2; w < width - 2; w += 2) {
      r = (bf[width] + bf[-width]) >> 1;
      b = (bf[-1] + bf[1]) >> 1;
      RGB2YUV(r, *bf, b, y1, u1, v1);
      ++bf;

      r = (bf[-width-1] + bf[-width+1] + bf[width-1] + bf[width+1]) >> 2;
      g = (bf[-width] + bf[1] + bf[width] + bf[-1]) >> 2;
      RGB2YUV(r, g, *bf, y2, u2, v2);
      ++bf;

      assign(y, u, v, y1, u1, v1, y2, u2, v2);
    }

    r = (bf[width] + bf[-width]) >> 1;
    b = (bf[-1] + bf[1]) >> 1;
    RGB2YUV(r, *bf, b, y1, u1, v1);
    ++bf;

    r = (bf[-width-1] + bf[width-1]) >> 1;
    // correct: g = (bf[-width] + bf[width] + bf[-1]) / 3;
    // faster:
    g = (bf[-width] + bf[-1]) >> 1;
    RGB2YUV(r, g, *bf, y2, u2, v2);
    ++bf;

    assign(y, u, v, y1, u1, v1, y2, u2, v2);
  }

  // last r  g  ... line
  // correct: g = (bf[-width] + bf[1] + bf[width]) / 3;
  // faster:
  g = (bf[-width] + bf[1]) >> 1;
  b = bf[-width+1];
  RGB2YUV(*bf, g, b, y1, u1, v1);
  ++bf;

  r = (bf[-1] + bf[1]) >> 1;
  b = bf[-width];
  RGB2YUV(r, g, *bf, y2, u2, v2);
  ++bf;

  assign(y, u, v, y1, u1, v1, y2, u2, v2);

  for (unsigned int w = 2; w < width - 2; w += 2) {
    // correct: g = (bf[-width] + bf[1] + bf[-1]) / 3
    // faster:
    g = (bf[-width] + bf[-1]) >> 1;
    b = (bf[-width-1] + bf[-width+1]) >> 1;
    RGB2YUV(*bf, g, b, y1, u1, v1);
    ++bf;

    r = (bf[-1] + bf[1]) >> 1;
    b = bf[-width];
    RGB2YUV(r, *bf, b, y2, u2, v2);
    ++bf;

    assign(y, u, v, y1, u1, v1, y2, u2, v2);
  }

  // correct: g = (bf[-width] + bf[1] + bf[-1]) / 3;
  // faster:
  g = (bf[-width] + bf[-1]) >> 1;
  b = (bf[-width-1] + bf[-width+1]) >> 1;
  RGB2YUV(*bf, g, b, y1, u1, v1);
  ++bf;

  b = bf[-width];
  RGB2YUV(bf[-1], *bf, b, y2, u2, v2);
  ++bf;

  assign(y, u, v, y1, u1, v1, y2, u2, v2);

}
예제 #12
0
파일: bayer.cpp 프로젝트: tempbottle/fawkes
void
bayerGBRG_to_yuv422planar_bilinear2(const unsigned char *bayer, unsigned char *yuv,
				   unsigned int width, unsigned int height)
{
  unsigned char *y = yuv;
  unsigned char *u = YUV422_PLANAR_U_PLANE(yuv, width, height);
  unsigned char *v = YUV422_PLANAR_V_PLANE(yuv, width, height);
  const unsigned char *bf = bayer;

  int y1, u1, v1, y2, u2, v2;
  int r, g, b;

  // ignore first g  b  ... line
  bf += width;
  y  += width;
  u  += width >> 1;
  v  += width >> 1;

  for ( unsigned int h = 1; h < height - 1; h += 2) {

    // r  g  ... line
    // ignore first two columns
    ++bf; ++bf;
    ++y; ++y;
    ++u; ++v;

    for (unsigned int w = 2; w < width - 2; w += 2) {
      g = (bf[1] + bf[-1]) >> 1;
      b = (bf[width-1] + bf[width+1]) >> 1;
      RGB2YUV(*bf, g, b, y1, u1, v1);
      ++bf;

      r = (bf[-1] + bf[1]) >> 1;
      b = (bf[-width] + bf[width]) >> 1;
      RGB2YUV(r, *bf, b, y2, u2, v2);
      ++bf;

      assign(y, u, v, y1, u1, v1, y2, u2, v2);
    }

    // ignore last two columns
    ++bf; ++bf;
    ++y; ++y;
    ++u; ++v;

    // g  b  ... line
    // ignore first two columns
    ++bf; ++bf;
    ++y; ++y;
    ++u; ++v;

    for (unsigned int w = 2; w < width - 2; w += 2) {
      r = (bf[width] + bf[-width]) >> 1;
      b = (bf[-1] + bf[1]) >> 1;
      RGB2YUV(r, *bf, b, y1, u1, v1);
      ++bf;

      r = (bf[width-1] + bf[width+1]) >> 1;
      g = (bf[1] + bf[width]) >> 1;
      RGB2YUV(r, g, *bf, y2, u2, v2);
      ++bf;

      assign(y, u, v, y1, u1, v1, y2, u2, v2);
    }

    // ignore last two columns
    ++bf; ++bf;
    ++y; ++y;
    ++u; ++v;
  }

  // ignore last r  g  ... line

}
예제 #13
0
void
FilterUnwarp::apply()
{
	// destination y-plane
	unsigned char *dyp =
	  dst + (dst_roi->start.y * dst_roi->line_step) + (dst_roi->start.x * dst_roi->pixel_step);

	// destination u-plane
	unsigned char *dup =
	  YUV422_PLANAR_U_PLANE(dst, dst_roi->image_width, dst_roi->image_height)
	  + ((dst_roi->start.y * dst_roi->line_step) / 2 + (dst_roi->start.x * dst_roi->pixel_step) / 2);
	// v-plane
	unsigned char *dvp =
	  YUV422_PLANAR_V_PLANE(dst, dst_roi->image_width, dst_roi->image_height)
	  + ((dst_roi->start.y * dst_roi->line_step) / 2 + (dst_roi->start.x * dst_roi->pixel_step) / 2);

	// line starts
	unsigned char *ldyp = dyp; // destination y-plane
	unsigned char *ldup = dup; // u-plane
	unsigned char *ldvp = dvp; // v-plane

	unsigned int warp1_x = 0, warp1_y = 0, warp2_x = 0, warp2_y = 0;

	unsigned char py1 = 0, py2 = 0, pu1 = 0, pu2 = 0, pv1 = 0, pv2 = 0;

	for (unsigned int h = 0; h < dst_roi->height; ++h) {
		for (unsigned int w = 0; w < dst_roi->width; w += 2) {
			mm->unwarp2warp(dst_roi->start.x + w, dst_roi->start.y + h, &warp1_x, &warp1_y);
			mm->unwarp2warp(dst_roi->start.x + w + 1, dst_roi->start.y + h + 1, &warp2_x, &warp2_y);

			if ((warp1_x < src_roi[0]->image_width) && (warp1_y < src_roi[0]->image_height)) {
				// Src pixel is in original image

				YUV422_PLANAR_YUV(src[0],
				                  src_roi[0]->image_width,
				                  src_roi[0]->image_height,
				                  warp1_x,
				                  warp1_y,
				                  py1,
				                  pu1,
				                  pv1);

				*dyp++ = py1;
				*dup   = pu1;
				*dvp   = pv1;

				if ((warp2_x < src_roi[0]->image_width) && (warp2_y < src_roi[0]->image_height)) {
					YUV422_PLANAR_YUV(src[0],
					                  src_roi[0]->image_width,
					                  src_roi[0]->image_height,
					                  warp2_x,
					                  warp2_y,
					                  py2,
					                  pu2,
					                  pv2);

					*dyp++ = py2;
					*dup   = (*dup + pu2) / 2;
					*dvp   = (*dvp + pv2) / 2;
				} else {
					*dyp++ = 0;
				}
				dup++;
				dvp++;
			} else {
				*dyp++ = 0;
				*dup   = 0;
				*dvp   = 0;

				if ((warp2_x < src_roi[0]->image_width) && (warp2_y < src_roi[0]->image_height)) {
					YUV422_PLANAR_YUV(src[0],
					                  src_roi[0]->image_width,
					                  src_roi[0]->image_height,
					                  warp2_x,
					                  warp2_y,
					                  py2,
					                  pu2,
					                  pv2);

					*dyp++ = py2;
					*dup   = pu2;
					*dvp   = pv2;
				} else {
					*dyp++ = 0;
				}

				dup++;
				dvp++;
			}
		}

		ldyp += dst_roi->line_step;
		ldup += dst_roi->line_step;
		ldup += dst_roi->line_step;
		dyp = ldyp;
		dup = ldup;
		dvp = ldvp;
	}
}