Beispiel #1
2
void cvCLAdaptEqualize(const CvArr* srcarr, CvArr* dstarr,
                        unsigned int xdivs, unsigned int ydivs, unsigned int bins,
                        float limit, int range)
{
       
        double min_val, max_val;
        unsigned char min, max;
       
        int type;

       IplImage sstub, *src = cvGetImage(srcarr, &sstub);
       IplImage dstub, *dst = cvGetImage(dstarr, &dstub);

        if ((src == NULL) || (dst == NULL))
        CV_ERROR( CV_StsUnsupportedFormat, "NULL value passed as image to function" );
       
        CV_CALL( type = cvGetElemType( src ));
        if( type != CV_8UC1 )
                CV_ERROR( CV_StsUnsupportedFormat, "Only 8uC1 images are supported" );
        CV_CALL( type = cvGetElemType( src ));
        if( type != CV_8UC1 )
                CV_ERROR( CV_StsUnsupportedFormat, "Only 8uC1 images are supported" );
       
        //if( !CV_ARE_SIZES_EQ( src, dst ))     // Modified by Shervin Emami, 17Nov2010.
        if (src->width != dst->width || src->height != dst->height)
                CV_ERROR( CV_StsUnmatchedSizes, "src and dst images must be equal sizes" );
    
        if (((xdivs < 2) || (xdivs > 16)) || ((ydivs < 2) || (ydivs > 16)))
                CV_ERROR( CV_StsBadFlag, "xdivs and ydivs must in range (MIN=2 MAX = 16)" );

        if ((bins < 2) || (bins > 256))
                CV_ERROR( CV_StsBadFlag, "bins must in range (MIN=2 MAX = 256)" );

        // copy src to dst for in-place CLAHE.
     cvCopy(src, dst);
   

        // If the dimensions of the image are not a multiple of the xdivs and ydivs, then enlarge the image to be a correct size and then shrink the image.
        // Also make sure the image is aligned to 8 pixels width, so that OpenCV won't add extra padding to the image.
        // Added by Shervin Emami, 17Nov2010.
        int enlarged = 0;
        int origW = dst->width;
        int origH = dst->height;
        IplImage *tmpDst = 0;
        if ((dst->width & (8-1)) || (dst->height & (8-1)) || (dst->width % xdivs) || (dst->height % ydivs)) {
                int newW = ((dst->width + 8-1) & -8);   // Align to 8 pixels, so that widthStep hopefully equals width.
                newW = ((newW + xdivs-1) & -xdivs);             // Also align for CLAHE.
                int newH = ((dst->height + ydivs-1) & -ydivs);
                //std::cout << "w=" << dst->width << ", h=" << dst->height << ". new w = " << newW << ", h = " << newH << std::endl;
                IplImage *enlargedDst = cvCreateImage(cvSize(newW, newH), dst->depth, dst->nChannels);
                cvResize(dst, enlargedDst, CV_INTER_CUBIC);
                //cvReleaseImage(&dst);
                tmpDst = dst;
                dst = enlargedDst;      // Use the enlarged image instead of the original dst image.
                enlarged = 1;   // signal that we need to shrink later!
        }
        // Check if OpenCV adds padding bytes on each row. Added by Shervin Emami, 17Nov2010.
        if (dst->width != dst->widthStep)
                CV_ERROR( CV_StsBadFlag, "dst->widthStep should be the same as dst->width. The IplImage has padding, so use a larger image." );


        // check number of xdivs and ydivs is a multiple of image dimensions
        if (dst->width % xdivs)
                CV_ERROR( CV_StsBadFlag, "xdiv must be an integer multiple of image width " );
        if (dst->height % ydivs)
                CV_ERROR( CV_StsBadFlag, "ydiv must be an integer multiple of image height " );
               
        // get the min and max values of the image
       
        if (range == CV_CLAHE_RANGE_INPUT) {
                cvMinMaxLoc(dst, &min_val, &max_val);
                min = (unsigned char) min_val;
                max = (unsigned char) max_val;
        } else {
                min = 0;
                max = 255;
        }
        // call CLHAHE for in-place CLAHE
       
        //int rcode =
        CLAHE((kz_pixel_t*) (dst->imageData), (unsigned int) dst->width, (unsigned int)
        dst->height, (kz_pixel_t) min, (kz_pixel_t) max, (unsigned int) xdivs, (unsigned int) ydivs,
              (unsigned int) bins, (float) limit);

        //printf("RCODE %i\n", rcode);  

        // If the dst image was enlarged to fit the alignment, then shrink it back now.
        // Added by Shervin Emami, 17Nov2010.
 
        if (enlarged) {
                //std::cout << "w=" << dst->width << ", h=" << dst->height << ". orig w=" << origW << ", h=" << origH << std::endl;
                cvResize(dst, tmpDst, CV_INTER_CUBIC);  // Shrink the enlarged image back into the original dst image.
                cvReleaseImage(&dst);   // Free the enlarged image.
        }

}
Beispiel #2
0
void convert(uint8_t img[], int* nrows, int* ncols, int ldim)
{
	int h, w, chrh, chrw;

	//
	h = *nrows;
	w = *ncols;
		
	//
	CLAHE(img, img, h, w, ldim, 8, 8, 2);
	
	//
	chrh = 16;
	chrw = 8;
	
	decimate(img, img, h, w, ldim, chrh, chrw);
	
	h = h/chrh;
	w = w/chrw;
	
	//
	CLAHE(img, img, h, w, w, 4, 8, 3);
	
	// pixel intensity quantization
	quantize(img, img, h, w, w);
	
	//
	*nrows = h;
	*ncols = w;
}
Beispiel #3
0
SEXP clahe (SEXP x, SEXP _uiNrX, SEXP _uiNrY, SEXP _uiNrBins, SEXP _fCliplimit, SEXP _keepRange) {
  int nx, ny, nz, i, j;
  unsigned int uiNrX, uiNrY, uiNrBins;
  float fCliplimit;
  int keepRange;
  double *src, *tgt;
  SEXP res;
  
  kz_pixel_t min = 0, max = uiNR_OF_GREY-1;
  kz_pixel_t *img;
  
  double maxPixelValue = uiNR_OF_GREY-1;
  
  PROTECT( res = allocVector(REALSXP, XLENGTH(x)) );
  DUPLICATE_ATTRIB(res, x);
  
  nx = INTEGER(GET_DIM(x))[0];
  ny = INTEGER(GET_DIM(x))[1];
  nz = getNumberOfFrames(x, 0);
  
  uiNrX = INTEGER(_uiNrX)[0];
  uiNrY = INTEGER(_uiNrY)[0];
  uiNrBins = INTEGER(_uiNrBins)[0];
  fCliplimit = REAL(_fCliplimit)[0];
  keepRange = LOGICAL(_keepRange)[0];
  
  img = R_Calloc(nx*ny, kz_pixel_t);
  
  // process channels separately
  for(j = 0; j < nz; j++) {
    src = &(REAL(x)[j*nx*ny]);
    tgt = &(REAL(res)[j*nx*ny]);
    
    if (keepRange) {
      min = uiNR_OF_GREY-1;
      max = 0;
    }
    
    // convert frame to CLAHE-compatible format
    for (i = 0; i < nx*ny; i++) {
      double el = src[i];
      
      // clip
      if (el < 0.0) el = 0;
      else if (el > 1.0) el = 1.0;
      // convert to int
      kz_pixel_t nel = (kz_pixel_t) round(el * maxPixelValue);
      
      if (keepRange) {
        if (nel < min) min = nel;
        if (nel > max) max = nel;
      }
      
      img[i] = nel;
    }
    
    int val = CLAHE (img, (unsigned int) nx, (unsigned int) ny,
                     min, max, uiNrX, uiNrY, uiNrBins, fCliplimit);
    
    // translate internal error codes
    switch (val) {
    case -1:
      error("# of regions x-direction too large");
      break;
    case -2:
      error("# of regions y-direction too large");
      break;
    case -3:
      error("x-resolution no multiple of 'nx'");
      break;
    case -4:
      error("y-resolution no multiple of 'ny'");
      break;
    case -5:
      error("maximum too large");
      break;
    case -6:
      error("minimum equal or larger than maximum");
      break;
    case -7:
      error("at least 4 contextual regions required");
      break;
    case -8:
      error("not enough memory! (try reducing 'bins')");
      break;
    }
    
    // convert back to [0:1] range
    for (i = 0; i < nx*ny; i++) {
      tgt[i] = (double) img[i] / maxPixelValue;
    }
  }
  
  R_Free(img);
  
  UNPROTECT(1);
  
  return res;
}