示例#1
0
/**radiusX and radiusY specify how far the kernel extends from the
   central pixel.  Circular kernels cannot be separable.  The value of
   each pixel of the kernel within the elliptical area is scaled
   equally so that the entire filter sums to 1.  Areas outside the
   ellipse are set to zero.
 */
void DKernel2D::setCirc(int radiusX, int radiusY){
  int w, h;
  double dblSum;
  double rx2,ry2;
  w = radiusX*2+1;
  h = radiusY*2+1;
  this->radiusX = radiusX;
  this->radiusY = radiusY;
  fSep = false;
  deleteBuffers();
  allocBuffers(w,h);

  dblSum = 0.;
  rx2=(0.5+radiusX)*(0.5+radiusX);
  ry2=(0.5+radiusY)*(0.5+radiusY);
  for(int y = -radiusY, idx = 0; y <= radiusY; ++y){
    for(int x = -radiusX; x <= radiusX; ++x, ++idx){
      if(((x*x/rx2)+(y*y/ry2)) <= 1.){
	rgData_dbl[idx] = 1.;
	dblSum += 1.;
      }
      else
	rgData_dbl[idx] = 0.;
    }
  }
  for(int y = -radiusY, idx = 0; y <= radiusY; ++y){
    for(int x = -radiusX; x <= radiusX; ++x, ++idx){
      rgData_dbl[idx] /= dblSum;
      rgData_flt[idx] = rgData_dbl[idx];
    }
  }
}
示例#2
0
///Assignment operator (deep-copies the src kernel)
const DKernel2D& DKernel2D::operator=(const DKernel2D &src){
  int w, h;
  if(this != &src){
    fSep = src.fSep;
    radiusX = src.radiusX;
    radiusY = src.radiusY;
    numSigsX = src.numSigsX;
    numSigsY = src.numSigsY;
    w = 2*radiusX+1;
    h = 2*radiusY+1;
    deleteBuffers();
    if((w < 1) || (h < 1)){
      rgData_flt = NULL;
      rgData_dbl = NULL;
      rgSep_flt = NULL;
      rgSep_dbl = NULL;
    }
    else{
      allocBuffers(w, h);
      memcpy(rgData_flt, src.rgData_flt, sizeof(float)*w*h);
      memcpy(rgData_dbl, src.rgData_dbl, sizeof(double)*w*h);
      memcpy(rgSep_flt, src.rgSep_flt, sizeof(float)*(w+h));
      memcpy(rgSep_dbl, src.rgSep_dbl, sizeof(double)*(w+h));
    }
  }
  return *this;
}
示例#3
0
///Set the kernel to a Laplacian of Gaussian (2nd derivative of the Gaussian)
void DKernel2D::setLoG(int radiusX, int radiusY, bool fSeparable){
  int w, h;
  double xp, yp;
  double one_2piSigXsigY;
  double sigmaX, sigmaY;
  double sigmaX2, sigmaY2;
  double sigmaX4, sigmaY4;
  double ksum = 0.;

  sigmaX = radiusX / numSigsX;
  sigmaY = radiusY / numSigsY;
  sigmaX2 = sigmaX * sigmaX;
  sigmaY2 = sigmaY * sigmaY;
  sigmaX4 = sigmaX2 * sigmaX2;
  sigmaY4 = sigmaY2 * sigmaY2;

  w = radiusX*2+1;
  h = radiusY*2+1;
  this->radiusX = radiusX;
  this->radiusY = radiusY;
  fSep = fSeparable;
  deleteBuffers();
  allocBuffers(w,h);
  one_2piSigXsigY = 1. / (2* M_PI * sigmaX * sigmaY);

  if(fSeparable){
    fprintf(stderr, "DKernel2D::setLoG() separable kernel not implemented\n");
    exit(1);
  }
  else{
    one_2piSigXsigY = 1. / (2* M_PI * sigmaX * sigmaY);
    for(int y = 0, idx = 0; y < h; ++y){
      yp = y-radiusY;
      for(int x = 0; x < w; ++x, ++idx){
	xp = x-radiusX;
	rgData_dbl[idx] =
	  one_2piSigXsigY * exp(-0.5*(xp*xp/sigmaX2 + yp*yp/sigmaY2)) *
	  ((xp*xp/sigmaX4 - 1./sigmaX2) + (yp*yp/sigmaY4 - 1./sigmaY2));
	rgData_flt[idx] = (float)(rgData_dbl[idx]);
	ksum += rgData_dbl[idx];
      }
    }
  }
  printf("LoG ksum=%f\n", ksum);
//   // get rid of the bias (ksum)
//   ksum /= (w*h);
//   for(int i = 0; i < w*h; ++i){
//     rgData_dbl[i] -= ksum;
//     rgData_flt[i] -= ksum;
//   }
//   ksum = 0.;
//   for(int i = 0; i < w*h; ++i){
//     ksum += rgData_dbl[i];
//   }
//   printf("after adjusting, ksum=%f\n", ksum);

}
示例#4
0
///Set the kernel to a fake LaplacianOfGaussian
void DKernel2D::setFakeLoG(int radiusX, int radiusY){
  int w, h;
  double xp, yp;
  double one_2piSigXsigY;
  double sigmaX, sigmaY;
  double sigmaX2, sigmaY2;
  double sigmaX4, sigmaY4;
  double XoverY;
  double ksum = 0.;

  XoverY = (double)radiusX / (double)radiusY;

  sigmaX = radiusX / numSigsX;
  sigmaY = sigmaX;
//   sigmaY = radiusY / numSigsY;
  sigmaX2 = sigmaX * sigmaX;
  sigmaY2 = sigmaY * sigmaY;
  sigmaX4 = sigmaX2 * sigmaX2;
  sigmaY4 = sigmaY2 * sigmaY2;

  w = radiusX*2+1;
  h = radiusY*2+1;
  this->radiusX = radiusX;
  this->radiusY = radiusY;
  fSep = false;
  deleteBuffers();
  allocBuffers(w,h);
  one_2piSigXsigY = 1. / (2* M_PI * sigmaX * sigmaY);

  one_2piSigXsigY = 1. / (2* M_PI * sigmaX * sigmaY);
  for(int y = 0, idx = 0; y < h; ++y){
    yp = (y-radiusY)*XoverY;
    for(int x = 0; x < w; ++x, ++idx){
      xp = x-radiusX;
      rgData_dbl[idx] =
	one_2piSigXsigY * exp(-0.5*(xp*xp/sigmaX2 + yp*yp/sigmaY2)) *
	((xp*xp/sigmaX4 - 1./sigmaX2) + (yp*yp/sigmaY4 - 1./sigmaY2));
      rgData_flt[idx] = (float)(rgData_dbl[idx]);
      ksum += rgData_dbl[idx];
    }
  }
  printf("Fake LoG ksum=%f\n", ksum);
//   // get rid of the bias (ksum)
//   ksum /= (w*h);
//   for(int i = 0; i < w*h; ++i){
//     rgData_dbl[i] -= ksum;
//     rgData_flt[i] -= ksum;
//   }
//   ksum = 0.;
//   for(int i = 0; i < w*h; ++i){
//     ksum += rgData_dbl[i];
//   }
//   printf("after adjusting, ksum=%f\n", ksum);
}
示例#5
0
///Set the kernel to a 3x3 Laplace (-8 in the center, 1 everywhere else)
void DKernel2D::setLaplace(){
  int w, h;
  w = 3;
  h = 3;
  this->radiusX = 1;
  this->radiusY = 1;
  fSep = false;
  deleteBuffers();
  allocBuffers(w,h);
  for(int idx = 0; idx < 9; ++idx){
    rgData_dbl[idx] = 1.;
    rgData_flt[idx] = 1.;
  }
  rgData_dbl[4] = -8.;
  rgData_flt[4] = -8.;
}
示例#6
0
MBOOL
StereoNodeImpl::
onStart()
{
    FUNC_START;
    MBOOL ret = MFALSE;
    MSize rgbSize = getRgbImgSize();
    vector<HwPortConfig_t> lHwPortCfg;
    HwPortConfig_t cfgImg = {
        mapToPortID(STEREO_IMG),
        eImgFmt_YV12,
        getAlgoImgSize(),
        MRect( MPoint(0, 0), getAlgoImgSize() )
    };
    HwPortConfig_t cfgRgb = {
        mapToPortID(STEREO_RGB),
        eImgFmt_ARGB8888,
        rgbSize,
        MRect( MPoint(0, 0), rgbSize )
    };
    //
    if( !setupPort(mbCfgImgo, mbCfgFeo, mbCfgRgb ) )
        goto lbExit;
    //
    if ( mbCfgImgo )
        lHwPortCfg.push_back(cfgImg);
    //
    if ( mbCfgRgb )
        lHwPortCfg.push_back(cfgRgb);
    //
    CAM_TRACE_BEGIN("alloc");
    if( !allocBuffers(lHwPortCfg) )
    {
        MY_LOGE("alloc buffers failed");
        goto lbExit;
    }
    CAM_TRACE_END();
    //
    muPostFrameCnt = 0;
    muEnqFrameCnt = 0;
    muDeqFrameCnt = 0;
    //
    ret = MTRUE;
lbExit:
    FUNC_END;
    return ret;
}
示例#7
0
/**The internal data arrays are allocated and the values from rgData
 * are copied into the internal data arrays.  The size of the buffers
 * depends on whether fIsSeparable is true or false.  If fIsSeparable
 * is false, then the buffers hold w*h floats/doubles (multiply).  If
 * fIsSeparable is true, then the buffers only hold w+h floats/doubles
 * (add).  Not all kernels can be made separable, but if you use separable
 * kernels when possible, convolution is typically much faster.  When
 * calling either setData function, the internal arrays for both float and
 * double values are allocated and initialized to the proper values.  Both
 * functions are provided as a convenience to the caller so the data being
 * copied can be either float or double.
 *
 * For separable kernels, the horizontal component of the kernel is
 * first (w values), followed by the vertical component (h values).
 */
void DKernel2D::setData_dbl(double *rgData, int w, int h, bool fIsSeparable){
  if((0 == (w & 1)) || (0 == (h & 1))){
    fprintf(stderr, "DKernel2D::setData_dbl() w,h must be odd\n");
    exit(1);
  }
  this->radiusX = w/2;
  this->radiusY = h/2;
  this->fSep = fIsSeparable;
  deleteBuffers();
  allocBuffers(w,h);
  for(int y =0, idx=0; y < h; ++y){
    for(int x = 0; x < w; ++x, ++idx){
      rgData_flt[idx] = (float)(rgData[idx]);
      rgData_dbl[idx] = rgData[idx];
    }
  }
}
示例#8
0
///Assignment from a DImage object (creates a kernel based on srcImg contents)
const DKernel2D& DKernel2D::operator=(const DImage &srcImg){
  int w, h;
  DImage imgDbl;
  double *pDataDbl;
  double *pDataDst;
  float *pDataFlt;

  if((0 == (srcImg.width() & 1)) || (0 == (srcImg.height() & 1))){
    fprintf(stderr, "DKernel2D::operator=() source image w,h must be odd\n");
    exit(1);
  }
  if(1 != srcImg.numChannels()){
    fprintf(stderr, "DKernel2D::operator=() source image numChannels != 1\n");
    exit(1);
  }
  if(srcImg.getImageType() == DImage::DImage_cmplx){
    fprintf(stderr, "DKernel2D::operator=() DImage_cmplx not supported\n");
    exit(1);
  }
  srcImg.convertedImgType_(imgDbl, DImage::DImage_dbl_multi, 1);
  pDataDbl = imgDbl.dataPointer_dbl();
  fSep = false;
  radiusX = srcImg.width() / 2;
  radiusY = srcImg.height() / 2;
  numSigsX = DEFAULT_NUM_SIGMAS;
  numSigsY = DEFAULT_NUM_SIGMAS;
  w = 2*radiusX+1;
  h = 2*radiusY+1;
  deleteBuffers();
  allocBuffers(w, h);
  pDataDst = rgData_dbl;
  pDataFlt = rgData_flt;
  
  for(int y = 0; y < h; ++y){
    memcpy(pDataDst, pDataDbl, sizeof(double) * w);
    for(int x = 0; x < w; ++x)
      pDataFlt[x] = (float)(pDataDst[x]);
    pDataDst += w;
    pDataDbl += w;
    pDataFlt += w;
  }

  return *this;
}
示例#9
0
/**radiusX and radiusY specify how far the kernel extends from the
   central pixel.  fSeparable specifies whether this should be a
   separable kernel, which allows dconvolver to perform convolution
   faster than standard non-separable convolution.  The value of each
   pixel of the kernel is scaled equally so that the entire filter
   sums to 1.
 */
void DKernel2D::setRect(int radiusX, int radiusY, bool fSeparable){
  int w, h;
  float fltVal;
  double dblVal;
  w = radiusX*2+1;
  h = radiusY*2+1;
  this->radiusX = radiusX;
  this->radiusY = radiusY;
  fSep = fSeparable;
  deleteBuffers();
  allocBuffers(w,h);


  if(fSeparable){
    dblVal = 1./w;
    fltVal = (float)dblVal;
    for(int x = 0; x < w; ++x){
      rgSep_flt[x] = fltVal;
      rgSep_dbl[x] = dblVal;
    }
    dblVal = 1./h;
    fltVal = (float)dblVal;
    for(int y = 0; y < h; ++y){
      rgSep_flt[w+y] = fltVal;
      rgSep_dbl[w+y] = dblVal;
    }
  }
  else{
    dblVal = 1./(w*h);
    fltVal = (float)dblVal;
    for(int y = 0, idx = 0; y < h; ++y){
      for(int x = 0; x < w; ++x, ++idx){
	rgData_flt[idx] = fltVal;
	rgData_dbl[idx] = dblVal;
      }
    }
  }
}
示例#10
0
///Copy Construstor (makes a deep copy of the data)
DKernel2D::DKernel2D(const DKernel2D &src){
  int w, h;
  DInstanceCounter::addInstance("DKernel2D");
  fSep = src.fSep;
  radiusX = src.radiusX;
  radiusY = src.radiusY;
  numSigsX = src.numSigsX;
  numSigsY = src.numSigsY;
  w = 2*radiusX+1;
  h = 2*radiusY+1;
  if((w < 1) || (h < 1)){
    rgData_flt = NULL;
    rgData_dbl = NULL;
    rgSep_flt = NULL;
    rgSep_dbl = NULL;
  }
  else{
    allocBuffers(w, h);
    memcpy(rgData_flt, src.rgData_flt, sizeof(float)*w*h);
    memcpy(rgData_dbl, src.rgData_dbl, sizeof(double)*w*h);
    memcpy(rgSep_flt, src.rgSep_flt, sizeof(float)*(w+h));
    memcpy(rgSep_dbl, src.rgSep_dbl, sizeof(double)*(w+h));
  }
}
示例#11
0
/**fSeparable should be set to true if you want a separable kernel,
 * which is faster than a non-separable kernel when convolving.  (for
 * an NxN separable kernel, convolution is a 2*N operation instead of
 * N*N operation for each image pixel).  By default, 3 standard
 * deviations (sigmas) fit under the gaussian curve on each side of
 * the central pixel.  If you need more (or fewer) standard deviations
 * to fit within the kernel, use setNumSigmas().
*/
void DKernel2D::setGauss(int radiusX, int radiusY, bool fSeparable){
  int w, h;
  double xp, yp;
  double one_2piSigXsigY;
  double coef;
  double coefX, coefY;
  double sigmaX, sigmaY;
  double dblSum;

  w = radiusX*2+1;
  h = radiusY*2+1;
  this->radiusX = radiusX;
  this->radiusY = radiusY;
  fSep = fSeparable;
  deleteBuffers();
  allocBuffers(w,h);
  sigmaX = radiusX / numSigsX;
  sigmaY = radiusY / numSigsY;

  coefX = -0.5 / sigmaX / sigmaX;
  coefY = -0.5 / sigmaY / sigmaY;
  if(fSeparable){
    one_2piSigXsigY = 1. / (2* M_PI * sigmaX * sigmaY);
    dblSum = 0.;
    for(int x = 0; x < w; ++x){
      xp = x-radiusX;
      rgSep_dbl[x] = one_2piSigXsigY * exp(xp*xp * coefX);
      dblSum += rgSep_dbl[x];
    }
    for(int x = 0; x < w; ++x){
      rgSep_dbl[x] /= dblSum;
      rgSep_flt[x] = (float)(rgSep_dbl[x]);
    }
    dblSum = 0.;
    for(int y = 0; y < h; ++y){
      yp = y-radiusY;
      rgSep_dbl[w+y] = one_2piSigXsigY * exp(yp*yp * coefY);
      dblSum += rgSep_dbl[w+y];
    }
    for(int y = 0; y < h; ++y){
      rgSep_dbl[w+y] /= dblSum;
      rgSep_flt[w+y] = (float)(rgSep_dbl[w+y]);
    }
  }
  else{
    one_2piSigXsigY = 1. / (2* M_PI * sigmaX * sigmaY);
    dblSum = 0.;
    for(int y = 0, idx = 0; y < h; ++y){
      yp = y-radiusY;
      for(int x = 0; x < w; ++x, ++idx){
	xp = x-radiusX;
	rgData_dbl[idx] =
	  one_2piSigXsigY * exp(coefX*xp*xp + coefY*yp*yp);
	dblSum += rgData_dbl[idx];
      }
    }
    for(int idx = 0; idx < w*h; ++idx){
      rgData_dbl[idx] /= dblSum;
      rgData_flt[idx] = (float)(rgData_dbl[idx]);
    }
  }
}
示例#12
0
/*
 * New media loaded.  Check if data in buffers
 * is validate and can be reused.
 */
static void
checkBuffers(
	char *new_vsn)
{
	u_longlong_t currentPos;

	/* If first request for this thread, allocate buffers. */
	if (IoThread->io_numBuffers == 0) {
		allocBuffers();
		strcpy(Instance->ci_vsn, new_vsn);
		return;
	}

	/* If disk archiving, invalidate buffers. */
	if (IoThread->io_flags & IO_diskArchiving) {
		ResetBuffers();
		IoThread->io_position = 0;
		strcpy(Instance->ci_vsn, new_vsn);
		return;
	}

	/* Get current position of removable media file. */
	currentPos = GetPosition();

	Trace(TR_FILES, "Get position %lld block size %d",
	    currentPos, GetBlockSize());

	/*
	 * If we loaded the same VSN as last time this proc was
	 * active, the buffers may be valid and thus data in the buffers
	 * can be reused.  If this is not the same VSN, invalidate
	 * the buffers and save VSN label in the thread's context.
	 */
	if (strcmp(Instance->ci_vsn, new_vsn) != 0) {
		int blockSize;

		/*
		 * New media.  If block size has changed set new mau
		 * information.  If necessary, reallocate buffers based
		 * on the new block size.
		 */
		blockSize = GetBlockSize();
		if (IoThread->io_blockSize != blockSize) {
			freeBuffers();
			allocBuffers();
		} else {
			ResetBuffers();
		}

		strcpy(Instance->ci_vsn, new_vsn);

	} else if (IoThread->io_position != currentPos) {

		/*
		 * The last known media position does not match the
		 * removable media file's position.  Since the position has
		 * changed, buffers must be invalidated.
		 */
		ResetBuffers();

	}

	/*
	 * Archive read thread needs mount position to maintain
	 * position on the media.
	 */
	IoThread->io_position = currentPos;
}