示例#1
0
void LocationSampler::sampleEquiDistant(cv::Rect &currentLocation,
                                        std::vector<cv::Rect> &locations) {

  double centerX = currentLocation.x + currentLocation.width / 2;
  double centerY = currentLocation.y + currentLocation.height / 2;

  std::vector<double> radialValues = this->linspace(0, radius, nRadial + 1);
  std::vector<double> angularValues = this->linspace(0, 2 * M_PI, nAngular  +1);
  int bb_x, bb_y = 0;

  cv::Rect imageBox(0, 0, this->n, this->m);

  int halfWidth = cvRound(currentLocation.width / 2.0);
  int halfHeight = cvRound(currentLocation.height / 2.0);

  for (int i = 1; i < radialValues.size(); ++i) {
    for (int j = 1; j < angularValues.size(); ++j) {

      // get the top left corner
      bb_x = centerX + (radialValues[i] * cos(angularValues[j])) - halfWidth;
      bb_y = centerY + (radialValues[i] * sin(angularValues[j])) - halfHeight;

      cv::Point topLeft(bb_x, bb_y);
      cv::Point bottomRight(bb_x + currentLocation.width,
                            bb_y + currentLocation.height);

      if (imageBox.contains(topLeft) && imageBox.contains(bottomRight)) {
        cv::Rect rect(bb_x, bb_y, currentLocation.width,
                      currentLocation.height);
        locations.push_back(rect);
      }
    }
  }
                                                                 }
示例#2
0
Py::Object
Image::resize(const Py::Tuple& args) {
  _VERBOSE("Image::resize");
  
  args.verify_length(2);
  
  if (bufferIn ==NULL) 
    throw Py::RuntimeError("You must first load the image"); 
  
  int numcols = Py::Int(args[0]);
  int numrows = Py::Int(args[1]);
  
  colsOut = numcols;
  rowsOut = numrows;
  
  
  size_t NUMBYTES(numrows * numcols * BPP);
  agg::int8u *buffer = new agg::int8u[NUMBYTES];  
  if (buffer ==NULL) //todo: also handle allocation throw
    throw Py::MemoryError("Image::resize could not allocate memory");
  
  rbufOut = new agg::rendering_buffer;
  rbufOut->attach(buffer, numcols, numrows, numcols * BPP);
  
  // init the output rendering/rasterizing stuff
  pixfmt pixf(*rbufOut);
  renderer_base rb(pixf);
  rb.clear(bg);
  agg::rasterizer_scanline_aa<> ras;
  agg::scanline_u8 sl;

  
  //srcMatrix *= resizingMatrix;
  //imageMatrix *= resizingMatrix;
  imageMatrix.invert();
  interpolator_type interpolator(imageMatrix); 
  
  
  
  
  agg::image_filter_base* filter = 0;  
  agg::span_allocator<agg::rgba8> sa;	
  agg::rgba8 background(agg::rgba8(int(255*bg.r),
				   int(255*bg.g),
				   int(255*bg.b),
				   int(255*bg.a)));




  // the image path
  agg::path_storage path;
  agg::int8u *bufferPad = NULL;
  agg::rendering_buffer rbufPad;

  double x0, y0, x1, y1;
  
  if (interpolation==NEAREST) {
    x0 = 0.0;
    x1 = colsIn;
    y0 = 0.0;
    y1 = rowsIn;
  }
  else {
    // if interpolation != nearest, create a new input buffer with the
    // edges mirrored on all size.  Then new buffer size is colsIn+2 by
    // rowsIn+2

    x0 = 1.0;
    x1 = colsIn+1;
    y0 = 1.0;
    y1 = rowsIn+1;

    bufferPad = new agg::int8u[(rowsIn+2) * (colsIn+2) * BPP];
    if (bufferPad ==NULL) 
      throw Py::MemoryError("Image::resize could not allocate memory");
    //pad the input buffer
    for (size_t rowNum=0; rowNum<rowsIn+2; rowNum++)
      for (size_t colNum=0; colNum<colsIn+2; colNum++) {
	if ( (colNum==0) && (rowNum==1||(rowNum==rowsIn+1))) {
	  //rewind to begining of column
	  bufferIn -= colsIn * BPP; 
	}
	*bufferPad++ = *bufferIn++;       //red
	*bufferPad++ = *bufferIn++;       //green
	*bufferPad++ = *bufferIn++;       //blue
	*bufferPad++ = *bufferIn++;       //alpha

	//rewind one byte on the first and next to last columns
	if ( colNum==0 || colNum==colsIn) bufferIn-=4;
      }
    //rewind the input buffers
    bufferIn  -= rowsIn * colsIn * BPP;
    bufferPad -= (rowsIn+2) * (colsIn+2) * BPP;
    rbufPad.attach(bufferPad, colsIn+2, rowsIn+2, (colsIn+2) * BPP);
  }



    
  if (buffer ==NULL) //todo: also handle allocation throw
    throw Py::MemoryError("Image::resize could not allocate memory");
  
  path.move_to(x0, y0);
  path.line_to(x1, y0);
  path.line_to(x1, y1);
  path.line_to(x0, y1);
  path.close_polygon();
  agg::conv_transform<agg::path_storage> imageBox(path, srcMatrix);
  ras.add_path(imageBox);

  switch(interpolation)
    {
    case NEAREST:
      {
	
	typedef agg::span_image_filter_rgba32_nn<agg::order_rgba32,
	  interpolator_type> span_gen_type;
	typedef agg::renderer_scanline_aa<renderer_base, span_gen_type> renderer_type;
	       
	span_gen_type sg(sa, *rbufIn, background, interpolator);
	renderer_type ri(rb, sg);
	agg::render_scanlines(ras, sl, ri);
	
      }
      break;
      
    case BILINEAR:
      {

       
	typedef agg::span_image_filter_rgba32_bilinear<agg::order_rgba32,
	  interpolator_type> span_gen_type;
	typedef agg::renderer_scanline_aa<renderer_base, span_gen_type> renderer_type;
		
	span_gen_type sg(sa, rbufPad, background, interpolator);
	renderer_type ri(rb, sg);
	agg::render_scanlines(ras, sl, ri);
      }
      break;
      
    case BICUBIC:     filter = new agg::image_filter<agg::image_filter_bicubic>;
    case SPLINE16:    filter = new agg::image_filter<agg::image_filter_spline16>;
    case SPLINE36:    filter = new agg::image_filter<agg::image_filter_spline36>;   
    case SINC64:      filter = new agg::image_filter<agg::image_filter_sinc64>;     
    case SINC144:     filter = new agg::image_filter<agg::image_filter_sinc144>;    
    case SINC256:     filter = new agg::image_filter<agg::image_filter_sinc256>;    
    case BLACKMAN64:  filter = new agg::image_filter<agg::image_filter_blackman64>; 
    case BLACKMAN100: filter = new agg::image_filter<agg::image_filter_blackman100>;
    case BLACKMAN256: filter = new agg::image_filter<agg::image_filter_blackman256>;
      
      typedef agg::span_image_filter_rgba32<agg::order_rgba32,
	interpolator_type> span_gen_type;
      typedef agg::renderer_scanline_aa<renderer_base, span_gen_type> renderer_type;
      span_gen_type sg(sa, rbufPad, background, interpolator, *filter);
      renderer_type ri(rb, sg);
      agg::render_scanlines(ras, sl, ri);
      
    }
  
  /*
    std::ofstream of2( "image_out.raw", std::ios::binary|std::ios::out);
    for (size_t i=0; i<NUMBYTES; ++i)
    of2.write((char*)&buffer[i], sizeof(char));
  */
  
  
  bufferOut = buffer;
  delete [] bufferPad;

  return Py::Object();
  
}
示例#3
0
Py::Object
Image::resize(const Py::Tuple& args) {
    _VERBOSE("Image::resize");

    args.verify_length(2);

    if (bufferIn ==NULL)
        throw Py::RuntimeError("You must first load the image");

    int numcols = Py::Int(args[0]);
    int numrows = Py::Int(args[1]);

    colsOut = numcols;
    rowsOut = numrows;


    size_t NUMBYTES(numrows * numcols * BPP);
    agg::int8u *buffer = new agg::int8u[NUMBYTES];
    if (buffer ==NULL) //todo: also handle allocation throw
        throw Py::MemoryError("Image::resize could not allocate memory");

    rbufOut = new agg::rendering_buffer;
    rbufOut->attach(buffer, numcols, numrows, numcols * BPP);

    // init the output rendering/rasterizing stuff
    pixfmt pixf(*rbufOut);
    renderer_base rb(pixf);
    rb.clear(bg);
    agg::rasterizer_scanline_aa<> ras;
    agg::scanline_u8 sl;


    //srcMatrix *= resizingMatrix;
    //imageMatrix *= resizingMatrix;
    imageMatrix.invert();
    interpolator_type interpolator(imageMatrix);

    // the image path
    agg::path_storage path;
    path.move_to(0, 0);
    path.line_to(colsIn, 0);
    path.line_to(colsIn, rowsIn);
    path.line_to(0, rowsIn);
    path.close_polygon();
    agg::conv_transform<agg::path_storage> imageBox(path, srcMatrix);
    ras.add_path(imageBox);



    agg::image_filter_base* filter = 0;
    agg::span_allocator<agg::rgba8> sa;
    switch(interpolation)
    {
    case NEAREST:
    {
        typedef agg::span_image_filter_rgba32_nn<agg::order_rgba32,
                interpolator_type> span_gen_type;
        typedef agg::renderer_scanline_u<renderer_base, span_gen_type> renderer_type;

        span_gen_type sg(sa, *rbufIn, agg::rgba(1,1,1,0), interpolator);
        renderer_type ri(rb, sg);
        ras.add_path(imageBox);
        ras.render(sl, ri);
    }
    break;

    case BILINEAR:
    {
        typedef agg::span_image_filter_rgba32_bilinear<agg::order_rgba32,
                interpolator_type> span_gen_type;
        typedef agg::renderer_scanline_u<renderer_base, span_gen_type> renderer_type;

        span_gen_type sg(sa, *rbufIn, agg::rgba(1,1,1,0), interpolator);
        renderer_type ri(rb, sg);
        ras.add_path(imageBox);
        ras.render(sl, ri);
    }
    break;

    case BICUBIC:
        filter = new agg::image_filter<agg::image_filter_bicubic>;
    case SPLINE16:
        filter = new agg::image_filter<agg::image_filter_spline16>;
    case SPLINE36:
        filter = new agg::image_filter<agg::image_filter_spline36>;
    case SINC64:
        filter = new agg::image_filter<agg::image_filter_sinc64>;
    case SINC144:
        filter = new agg::image_filter<agg::image_filter_sinc144>;
    case SINC256:
        filter = new agg::image_filter<agg::image_filter_sinc256>;
    case BLACKMAN64:
        filter = new agg::image_filter<agg::image_filter_blackman64>;
    case BLACKMAN100:
        filter = new agg::image_filter<agg::image_filter_blackman100>;
    case BLACKMAN256:
        filter = new agg::image_filter<agg::image_filter_blackman256>;

        typedef agg::span_image_filter_rgba32<agg::order_rgba32,
                interpolator_type> span_gen_type;
        typedef agg::renderer_scanline_u<renderer_base, span_gen_type> renderer_type;

        span_gen_type sg(sa, *rbufIn, agg::rgba(1,1,1,0), interpolator, *filter);
        renderer_type ri(rb, sg);
        ras.render(sl, ri);

    }

    /*
      std::ofstream of2( "image_out.raw", std::ios::binary|std::ios::out);
      for (size_t i=0; i<NUMBYTES; ++i)
      of2.write((char*)&buffer[i], sizeof(char));
    */


    bufferOut = buffer;


    return Py::Object();

}
示例#4
0
/**
 *  Samples rectangles in polar coordinates
 *
 *  @param currentLocation current bounding box
 *  @param locations       vector of sampled bounding boxes
 */
void LocationSampler::sampleEquiDistantMultiScale(
    cv::Rect &currentLocation, std::vector<cv::Rect> &locations) {

  double centerX = currentLocation.x + currentLocation.width / 2;
  double centerY = currentLocation.y + currentLocation.height / 2;

  std::vector<double> radialValues = this->linspace(0, radius, nRadial + 1);
  std::vector<double> angularValues = this->linspace(0, 2 * M_PI, nAngular  +1);
  int bb_x, bb_y = 0;

  cv::Rect imageBox(0, 0, this->n, this->m);

  int halfWidth = cvRound(currentLocation.width / 2.0);
  int halfHeight = cvRound(currentLocation.height / 2.0);

  for (int i = 1; i < radialValues.size(); ++i) {
    for (int j = 1; j < angularValues.size(); ++j) {

      // get the top left corner
      bb_x = centerX + (radialValues[i] * cos(angularValues[j])) - halfWidth;
      bb_y = centerY + (radialValues[i] * sin(angularValues[j])) - halfHeight;

      cv::Point topLeft(bb_x, bb_y);
      cv::Point bottomRight(bb_x + currentLocation.width,
                            bb_y + currentLocation.height);

      if (imageBox.contains(topLeft) && imageBox.contains(bottomRight)) {
        cv::Rect rect(bb_x, bb_y, currentLocation.width,
                      currentLocation.height);
        locations.push_back(rect);
      }
    }
  }

  // auto div = [](double x, double y) {return x/y;};

  int scaleR = this->radius;

  // halfWidth=cvRound(this->objectWidth/2.0);
  // halfHeight=cvRound(this->objectHeight/2.0);

  // halfWidth=cvRound(currentLocation.width/2.0);
  // halfHeight=cvRound(currentLocation.height/2.0);

  double downsample = 1.05;
  radialValues = this->linspace(0, scaleR, nRadial / 3 + 1);
  angularValues = this->linspace(0, 2 * M_PI, nAngular / 3 + 1);
  // radialValues=arma::linspace<arma::vec>(0,scaleR,3);
  // angularValues=arma::linspace<arma::vec>(0,2*M_PI, 3);

  int scale = 8;
  int shrinkOneSideScale = 2;

  // return;
  std::vector<int> scale_half_width;
  std::vector<int> scale_half_height;

  // for (int scale_w=-MIN(2, scale); scale_w<=scale; scale_w++) {

  double downsample_2 = 1.05;

  for (int scale_h = -shrinkOneSideScale + 1; scale_h <= shrinkOneSideScale;
       scale_h++) {
    int scale_w = scale_h;

    for (int scale_w = -shrinkOneSideScale + 1; scale_w <= shrinkOneSideScale;
         scale_w++) {

      // continue;
      if ((scale_w == 0 && scale_h == 0)) {
        continue;
      }

      int halfWidth_scale = cvRound(halfWidth * pow(downsample_2, scale_w));
      int halfHeight_scale = cvRound(halfHeight * pow(downsample_2, scale_h));

      if (halfWidth_scale <= 10 || halfHeight_scale <= 10) {
        continue;
      }

      scale_half_width.push_back(halfWidth_scale);
      scale_half_height.push_back(halfHeight_scale);
    }
  }

  for (int scale_h = -scale + 5; scale_h <= scale; scale_h++) {
    int scale_w = scale_h;

    if (scale_w == 0 && scale_h == 0) {
      continue;
    }

    int halfWidth_scale =
        cvRound((this->objectWidth / 2.0) * pow(downsample, scale_w));
    int halfHeight_scale =
        cvRound((this->objectHeight / 2.0) * pow(downsample, scale_h));

    if (halfWidth_scale <= 10 || halfHeight_scale <= 10) {
      continue;
    }

    scale_half_width.push_back(halfWidth_scale);
    scale_half_height.push_back(halfHeight_scale);
  }

  for (int s = 0; s < scale_half_width.size(); s++) {

    int width_scale = scale_half_width[s] * 2;
    int height_scale = scale_half_height[s] * 2;

    // double widthRatio=((double)width_scale)/this->objectWidth;
    // double heightRatio=((double)height_scale)/this->objectHeight;

    //            if (widthRatio<=0.6 || heightRatio<=0.6) {
    //                continue;
    //            }

    //            if
    //            (std::abs(div(width_scale,height_scale)-div(this->objectWidth,this->objectHeight))*(div(height_scale,width_scale)-div(this->objectHeight,this->objectWidth))>1)
    //            {
    //                continue;
    //            }

    for (int i = 0; i < radialValues.size(); ++i) {
      for (int j = 0; j < angularValues.size(); ++j) {

        // get the top left corner
          bb_x = centerX + (radialValues[i] * cos(angularValues[j])) -
               scale_half_width[s];
          bb_y = centerY + (radialValues[i] * sin(angularValues[j])) -
               scale_half_height[s];

        cv::Point topLeft(bb_x, bb_y);
        cv::Point bottomRight(bb_x + width_scale, bb_y + height_scale);

        if (imageBox.contains(topLeft) && imageBox.contains(bottomRight)) {

          cv::Rect rect(bb_x, bb_y, width_scale, height_scale);
          locations.push_back(rect);
        }
      }
      // }
    }
  }
}
示例#5
0
/**
 *  Sample on a grid
 *
 *  @param currentLocation current location
 *  @param locations       vector with locations
 *  @param R               radius vector to use for sampling
 *  @param step            how spread should locations be, default=1
 */
void LocationSampler::sampleOnAGrid(cv::Rect &currentLocation,
                                    std::vector<cv::Rect> &locations, int R,
                                    int step) {
  int centerX = cvRound(currentLocation.x + currentLocation.width / 2.0);
  int centerY = cvRound(currentLocation.y + currentLocation.height / 2.0);

  int halfWidth = cvRound(currentLocation.width / 2.0);
  int halfHeight = cvRound(currentLocation.height / 2.0);
  cv::Rect imageBox(0, 0, this->n, this->m);

  for (int x = -R; x <= R; x = x + step) {
    for (int y = -R; y <= R; y = y + step) {

      // make sure everything is within the radius
      if (sqrt(pow(x, 2) + pow(y, 2)) > R) {
        continue;
      }

      // get the top left corner
      int bb_x = centerX + x - halfWidth;
      int bb_y = centerY + y - halfHeight;

      cv::Point topLeft(bb_x, bb_y);
      cv::Point bottomRight(bb_x + currentLocation.width,
                            bb_y + currentLocation.height);

      if (imageBox.contains(topLeft) && imageBox.contains(bottomRight)) {

        cv::Rect rect(bb_x, bb_y, currentLocation.width,
                      currentLocation.height);
        locations.push_back(rect);
      }
    }
  }

  int scaleR = R / 6;

  double downsample = 1.05;

  for (int scale_w = -2; scale_w <= 2; scale_w++) {

    for (int scale_h = -2; scale_h <= 2; scale_h++) {

      if (scale_w == 0 && scale_h == 0) {
        continue;
      }

      int halfWidth_scale = cvRound(halfWidth * pow(downsample, scale_w));
      int halfHeight_scale = cvRound(halfHeight * pow(downsample, scale_h));

      int width_scale = halfWidth_scale * 2;
      int height_scale = halfHeight_scale * 2;

      for (int x = -scaleR; x <= scaleR; x = x + step) {
        for (int y = -scaleR; y <= scaleR; y = y + step) {

          // make sure everything is within the radius
          if (sqrt(pow(x, 2) + pow(y, 2)) > scaleR) {
            continue;
          }

          // get the top left corner
          int bb_x = centerX + x - halfWidth_scale;
          int bb_y = centerY + y - halfHeight_scale;

          cv::Point topLeft(bb_x, bb_y);
          cv::Point bottomRight(bb_x + width_scale, bb_y + height_scale);

          if (imageBox.contains(topLeft) && imageBox.contains(bottomRight)) {

            cv::Rect rect(bb_x, bb_y, width_scale, height_scale);
            locations.push_back(rect);
          }
        }
      }
    }
  }
}
示例#6
0
Py::Object
Image::resize(const Py::Tuple& args, const Py::Dict& kwargs) {
  _VERBOSE("Image::resize");

  args.verify_length(2);

  int norm = 1;
  if ( kwargs.hasKey("norm") ) norm = Py::Int( kwargs["norm"] );

  double radius = 4.0;
  if ( kwargs.hasKey("radius") ) radius = Py::Float( kwargs["radius"] );

  if (bufferIn ==NULL)
    throw Py::RuntimeError("You must first load the image");

  int numcols = Py::Int(args[0]);
  int numrows = Py::Int(args[1]);

  colsOut = numcols;
  rowsOut = numrows;


  size_t NUMBYTES(numrows * numcols * BPP);

  delete [] bufferOut;
  bufferOut = new agg::int8u[NUMBYTES];
  if (bufferOut ==NULL) //todo: also handle allocation throw
    throw Py::MemoryError("Image::resize could not allocate memory");

  delete rbufOut;
  rbufOut = new agg::rendering_buffer;
  rbufOut->attach(bufferOut, numcols, numrows, numcols * BPP);

  // init the output rendering/rasterizing stuff
  pixfmt pixf(*rbufOut);
  renderer_base rb(pixf);
  rb.clear(bg);
  agg::rasterizer_scanline_aa<> ras;
  agg::scanline_u8 sl;


  //srcMatrix *= resizingMatrix;
  //imageMatrix *= resizingMatrix;
  imageMatrix.invert();
  interpolator_type interpolator(imageMatrix);

  typedef agg::span_allocator<agg::rgba8> span_alloc_type;
  span_alloc_type sa;
  agg::rgba8 background(agg::rgba8(int(255*bg.r),
				   int(255*bg.g),
				   int(255*bg.b),
				   int(255*bg.a)));

  // the image path
  agg::path_storage path;
  agg::int8u *bufferPad = NULL;
  agg::rendering_buffer rbufPad;

  double x0, y0, x1, y1;

  x0 = 0.0;
  x1 = colsIn;
  y0 = 0.0;
  y1 = rowsIn;

  path.move_to(x0, y0);
  path.line_to(x1, y0);
  path.line_to(x1, y1);
  path.line_to(x0, y1);
  path.close_polygon();
  agg::conv_transform<agg::path_storage> imageBox(path, srcMatrix);
  ras.add_path(imageBox);

  typedef agg::wrap_mode_reflect reflect_type;
  typedef agg::image_accessor_wrap<pixfmt, reflect_type, reflect_type> img_accessor_type;

  pixfmt pixfmtin(*rbufIn);
  img_accessor_type ia(pixfmtin);
  switch(interpolation)
    {

    case NEAREST:
      {
	typedef agg::span_image_filter_rgba_nn<img_accessor_type, interpolator_type> span_gen_type;
	typedef agg::renderer_scanline_aa<renderer_base, span_alloc_type, span_gen_type> renderer_type;
	span_gen_type sg(ia, interpolator);
	renderer_type ri(rb, sa, sg);
	agg::render_scanlines(ras, sl, ri);
      }
      break;
        case BILINEAR:
        case BICUBIC:
        case SPLINE16:
        case SPLINE36:
        case HANNING:
        case HAMMING:
        case HERMITE:
        case KAISER:
        case QUADRIC:
        case CATROM:
        case GAUSSIAN:
        case BESSEL:
        case MITCHELL:
        case SINC:
        case LANCZOS:
        case BLACKMAN:
            {
                agg::image_filter_lut filter;
                switch(interpolation)
                {
                case BILINEAR:  filter.calculate(agg::image_filter_bilinear(), norm); break;
                case BICUBIC:  filter.calculate(agg::image_filter_bicubic(), norm); break;
                case SPLINE16:  filter.calculate(agg::image_filter_spline16(), norm); break;
                case SPLINE36:  filter.calculate(agg::image_filter_spline36(), norm); break;
                case HANNING:  filter.calculate(agg::image_filter_hanning(), norm); break;
                case HAMMING:  filter.calculate(agg::image_filter_hamming(), norm); break;
                case HERMITE:  filter.calculate(agg::image_filter_hermite(), norm); break;
                case KAISER:  filter.calculate(agg::image_filter_kaiser(), norm); break;
                case QUADRIC:  filter.calculate(agg::image_filter_quadric(), norm); break;
                case CATROM: filter.calculate(agg::image_filter_catrom(), norm); break;
                case GAUSSIAN: filter.calculate(agg::image_filter_gaussian(), norm); break;
                case BESSEL: filter.calculate(agg::image_filter_bessel(), norm); break;
                case MITCHELL: filter.calculate(agg::image_filter_mitchell(), norm); break;
                case SINC: filter.calculate(agg::image_filter_sinc(radius), norm); break;
                case LANCZOS: filter.calculate(agg::image_filter_lanczos(radius), norm); break;
                case BLACKMAN: filter.calculate(agg::image_filter_blackman(radius), norm); break;
                }
	typedef agg::span_image_filter_rgba_2x2<img_accessor_type, interpolator_type> span_gen_type;
	typedef agg::renderer_scanline_aa<renderer_base, span_alloc_type, span_gen_type> renderer_type;
	span_gen_type sg(ia, interpolator, filter);
	renderer_type ri(rb, sa, sg);
	agg::render_scanlines(ras, sl, ri);
      }
      break;

    }

  delete [] bufferPad;
  return Py::Object();

}