static void
analyzeDistribution(struct pam *          const inpamP,
                    bool                  const verbose,
                    const unsigned int ** const histogramP,
                    struct range *        const rangeP) {
/*----------------------------------------------------------------------------
   Find the distribution of the sample values -- minimum, maximum, and
   how many of each value -- in input image *inpamP, whose file is
   positioned to the raster.

   Return the minimum and maximum as *rangeP and the frequency
   distribution as *histogramP, an array such that histogram[i] is the
   number of pixels that have sample value i.

   Assume the file is positioned to the raster upon entry and leave
   it positioned at the same place.
-----------------------------------------------------------------------------*/
    unsigned int row;
    tuple * inrow;
    tuplen * inrown;
    unsigned int * histogram;  /* malloced array */
    unsigned int i;

    pm_filepos rasterPos;      /* Position in input file of the raster */

    pm_tell2(inpamP->file, &rasterPos, sizeof(rasterPos));

    inrow = pnm_allocpamrow(inpamP);
    inrown = pnm_allocpamrown(inpamP);
    MALLOCARRAY(histogram, inpamP->maxval+1);
    if (histogram == NULL)
        pm_error("Unable to allocate space for %lu-entry histogram",
                 inpamP->maxval+1);

    /* Initialize histogram -- zero occurrences of everything */
    for (i = 0; i <= inpamP->maxval; ++i)
        histogram[i] = 0;

    initRange(rangeP);

    for (row = 0; row < inpamP->height; ++row) {
        unsigned int col;
        pnm_readpamrow(inpamP, inrow);
        pnm_normalizeRow(inpamP, inrow, NULL, inrown);
        for (col = 0; col < inpamP->width; ++col) {
            ++histogram[inrow[col][0]];
            addToRange(rangeP, inrown[col][0]);
        }
    }
    *histogramP = histogram;

    pnm_freepamrow(inrow);
    pnm_freepamrown(inrown);

    pm_seek2(inpamP->file, &rasterPos, sizeof(rasterPos));

    if (verbose)
        pm_message("Pixel values range from %f to %f",
                   rangeP->min, rangeP->max);
}
Exemple #2
0
struct Button* initSongButton(int x, int y, char* name, int id, struct Frame* panel){
	struct Button* sb = initButton();
	sb->name = name;
	sb->Panel = panel;
	sb->range = initRange(x, y, 79, 10);
	sb->x_pos = x;
	sb->y_pos = y;
	sb->draw = drawTxtButton;
	sb->collide = songButtonCollide;
	sb->id = id;
	return sb;
}
Exemple #3
0
struct Button* initMenuButton(int x, char* name, int type, struct Frame* menuFrame){
	struct Button* b = initButton();
	b->range = initRange(x, 1, 30, 10);
	b->name = name;
	b->x_pos = x;
	b->y_pos = 1; // all menu buttons have to be drawn at y = 1
	b->draw = drawTxtButton;
	b->type = type;
	b->collide = menuButtonCollide;
	b->Panel = menuFrame;
	b->buttonType = menu;
	return b;
}
static void
getLocalThreshold(tuplen **    const inrows,
                  unsigned int const windowWidth,
                  unsigned int const x,
                  unsigned int const localWidth,
                  unsigned int const localHeight,
                  float        const darkness,
                  float        const minSpread,
                  samplen      const defaultThreshold,
                  samplen *    const thresholdP) {
/*----------------------------------------------------------------------------
  Find a suitable threshold in local area around one pixel.

  inrows[][] is a an array of 'windowWidth' pixels by 'localHeight'.

  'x' is a column number within the window.

  We look at the rectangle consisting of the 'localWidth' columns
  surrounding x, all rows.  If x is near the left or right edge, we truncate
  the window as needed.

  We base the threshold on the local spread (difference between minimum
  and maximum sample values in the local areas) and the 'darkness'
  factor.  A higher 'darkness' gets a higher threshold.

  If the spread is less than 'minSpread', we return 'defaultThreshold' and
  'darkness' is irrelevant.

  'localWidth' must be odd.
-----------------------------------------------------------------------------*/
    unsigned int const startCol = x >= localWidth/2 ? x - localWidth/2 : 0;

    unsigned int col;
    struct range localRange;

    assert(localWidth % 2 == 1);  /* entry condition */

    initRange(&localRange);

    for (col = startCol; col <= x + localWidth/2 && col < windowWidth; ++col) {
        unsigned int row;

        for (row = 0; row < localHeight; ++row)
            addToRange(&localRange, inrows[row][col][0]);
    }

    if (spread(localRange) < minSpread)
        *thresholdP = defaultThreshold;
    else
        *thresholdP = localRange.min + darkness * spread(localRange);
}
Exemple #5
0
void LaserMessage::init(int num_readings, int num_remissions) {

  if (m_msg != NULL) {
    freeRange();
    freeRemission();
  }
  else {
    m_msg = new carmen_laser_laser_message;
    carmen_test_alloc(m_msg);
  }
  carmen_erase_structure(m_msg, sizeof(carmen_laser_laser_message));

  m_msg->config = LaserConfig();
  
  initRange(num_readings);
  initRemission(num_remissions);
}
static void
thresholdLocal(struct pam *       const inpamP,
               struct pam *       const outpamP,
               struct cmdlineInfo const cmdline) {
/*----------------------------------------------------------------------------
  Threshold the image described by *inpamP, whose file is positioned to the
  raster, and output the resulting raster to the image described by
  *outpamP.

  Use local adaptive thresholding aka dynamic thresholding or dual
  thresholding (global for low contrast areas, LAT otherwise)
-----------------------------------------------------------------------------*/
    struct range globalRange; /* Range of sample values in entire image */
    tuplen ** inrows;
        /* vertical window of image containing the local area.  This is
           a ring of 'windowHeight' rows.  Row R of the image, when it is
           in the window, is inrows[R % windowHeight].
        */
    unsigned int windowHeight;  /* size of 'inrows' window */
    unsigned int nextRowToRead;
        /* Number of the next row to be read from the file into the inrows[]
           buffer.
        */
    tuple * outrow;           /* raw output row */
    unsigned int row;
        /* Number of the current row.  The current row is normally the
           one in the center of the inrows[] buffer (which has an actual
           center row because it is of odd height), but when near the top
           and bottom edge of the image, it is not.
        */
    const unsigned int * histogram;
    samplen globalThreshold;
        /* This is a threshold based on the entire image, to use in areas
           where the contrast is too small to use a locally-derived threshold.
        */
    unsigned int oddLocalWidth;
    unsigned int oddLocalHeight;
    unsigned int i;
    
    /* use a subimage with odd width and height to have a middle pixel */

    if (cmdline.width % 2 == 0)
        oddLocalWidth = cmdline.width + 1;
    else 
        oddLocalWidth = cmdline.width;
    if (cmdline.height % 2 == 0)
        oddLocalHeight = cmdline.height + 1;
    else
        oddLocalHeight = cmdline.height;

    windowHeight = MIN(oddLocalHeight, inpamP->height);

    /* global information is needed for dual thresholding */
    if (cmdline.dual) {
        analyzeDistribution(inpamP, cmdline.verbose, &histogram, &globalRange);
        computeGlobalThreshold(inpamP, histogram, globalRange,
                               &globalThreshold);
    } else {
        histogram = NULL;
        initRange(&globalRange);
        globalThreshold = 1.0;
    }

    outrow = pnm_allocpamrow(outpamP);

    MALLOCARRAY(inrows, windowHeight);

    if (inrows == NULL)
        pm_error("Unable to allocate memory for a %u-row array", windowHeight);

    for (i = 0; i < windowHeight; ++i)
        inrows[i] = pnm_allocpamrown(inpamP);

    /* Fill the vertical window buffer */
    nextRowToRead = 0;

    while (nextRowToRead < windowHeight)
        pnm_readpamrown(inpamP, inrows[nextRowToRead++ % windowHeight]);

    for (row = 0; row < inpamP->height; ++row) {
        thresholdLocalRow(inpamP, inrows, oddLocalWidth, windowHeight, row,
                          cmdline, globalRange, globalThreshold,
                          outpamP, outrow);

        pnm_writepamrow(outpamP, outrow);
        
        /* read next image line if available and necessary */
        if (row + windowHeight / 2 >= nextRowToRead &&
            nextRowToRead < inpamP->height)
            pnm_readpamrown(inpamP, inrows[nextRowToRead++ % windowHeight]);
    }

    free((void*)histogram);
    for (i = 0; i < windowHeight; ++i)
        pnm_freepamrow(inrows[i]);
    free(inrows);
    pnm_freepamrow(outrow);
}