/*************************************************************** * pointProcessing.cpp - contains point-based image enhancement * algorithms * * - negative: image negative * - cs: contrast stretching * - logtran: log transformation * - powerlaw: power-law transformation * - threshold: thresholding an image using either binary or * gray-level thresholding * - bitplane: bitplane slicing * - sampling: downsample the image * - quantization: quantize the image * - histeq: histogram equalization * * Author: Hairong Qi (C) hqi@utk.edu * * Created: 01/24/06 * * Modified: * 07/31/09 - move rescale() to imageIO.cpp * 02/06/06 - Chris reported problem with gcc4 when using * new (float *). Removed (). ***************************************************************/ #include "Image.h" #include "Dip.h" #include #include using namespace std; /** * Image negative. s = L - r where * L: the largest intensity in the image, * s: the enhanced pixel intensity, and * r: the original pixel intensity. * @para inimg Input image * @return Negative of the input image */ Image negative(Image &inimg) { Image outimg; int i, j, k; int nc, nr, ntype, nchan; Image maxi; nc = inimg.getCol(); nr = inimg.getRow(); ntype = inimg.getType(); nchan = inimg.getChannel(); // allocate memory for the negative image outimg.createImage(nr, nc, ntype); // find the negative for (i=0; i1, * compress the low intensity content. * @return Image corrected by power-law transformation */ Image powerlaw(Image &inimg, float gamma) { Image outimg; int i, j, k; int nr, nc, ntype, nchan; // allocate memory nr = inimg.getRow(); nc = inimg.getCol(); ntype = inimg.getType(); nchan = inimg.getChannel(); outimg.createImage(nr, nc, ntype); for (i=0; i= thresh) outimg(i,j,k) = (nt == GRAY) ? inimg(i,j,k) : L; else outimg(i,j,k) = 0; return outimg; } /** * Thresholding image to a gray-level or a binary image between certain range * @param inimg The input image. * @param lthresh The lower threshold. * @param uthresh The upper threshold. * @param nt The type of the resulting image. When nt==BINARY, using binary * thresholding; when nt==GRAY, using gray-level thresholding. * @return The thresholded image. */ Image threshold(Image &inimg, float lthresh, float uthresh, int nt) { Image outimg; int i, j; int nr, nc, ntype, nchan; // allocate memory nr = inimg.getRow(); nc = inimg.getCol(); ntype = inimg.getType(); nchan = inimg.getChannel(); if (nchan > 1) { cout << "threshold: can only handle single-channel image.\n"; exit(3); } outimg.createImage(nr, nc, ntype); if (nt != GRAY && nt != BINARY) nt = BINARY; for (i=0; i= lthresh && inimg(i,j) <= uthresh) outimg(i,j) = (nt == GRAY) ? inimg(i,j) : L; else outimg(i,j) = 0; return outimg; } /** * Automatic thresholding using Otsu's method * Qi (10/06/07) revision: * - couldn't remember who wrote the first version of this code * - instead of returning the thresholded image, it returns the optimal threshold * @param inimg The input image. * @return The thresholded image and the threshold automatically determined. */ Image autoThreshold(Image &inimg) { Image temp; float maxi, mini; float *hist, *chist, *ihist; // histogram, cumulative histogram, and // intensity cumulative histogram int i, j; int nr, nc, ntype, nchan; // allocate memory nr = inimg.getRow(); nc = inimg.getCol(); ntype = inimg.getType(); nchan = inimg.getChannel(); if (nchan > 1) { cout << "autoThreshold: Can only process gray-scale images.\n"; exit(3); } // check the range of the pixel intensity. rescale if out-of-range maxi = inimg.getMaximum(); // wonder if we should just make mini = inimg.getMinimum(); // getMaximum() return a scalar if (mini<0 || maxi>L) { cout << "autoThreshold: " << "The intensity value is outside [0, " << L << "], rescale.\n"; temp = rescale(inimg); } else temp = inimg; // initialize the histogram and the cumulative histogram arrays hist = (float *) new float [(int)L+1]; chist = (float *) new float [(int)L+1]; ihist = (float *) new float [(int)L+1]; for (i=0; i<=L; i++) { hist[i] = 0; chist[i] = 0; ihist[i] = 0; } // get the histogram from the scaled inimg for (i=0; i 1 and s is integer) * @return The downsampled image. */ Image sampling(Image &inimg, int s) { Image outimg; int i, j, k; int nr, nc, ntype, nchan; // check the range of s if (s < 1) { cout << "sampling: Cannot process downsample rate less than 1\n."; exit(3); } // allocate memory nr = inimg.getRow(); nc = inimg.getCol(); ntype = inimg.getType(); nchan = inimg.getChannel(); outimg.createImage(nr, nc, ntype); for (i=0; i 1) { cout << "histeq: can only handle gray-scale images\n"; exit(3); } // create histogram equalized image outimg.createImage(nr, nc, nt); // check the range of the pixel intensity. rescale if out-of-range maxi = inimg.getMaximum(); mini = inimg.getMinimum(); if (mini<0 || maxi>L) { cout << "histeq: " << "The intensity value is outside [0, " << L << "], rescale.\n"; temp = rescale(inimg); } else temp = inimg; // initialize the histogram arrays hist = (float *) new float [(int)L+1]; // Chris reported problem with gcc4 // chist = (float *) new float [(int)L+1]; // when have the () outside float * for (i=0; i<=L; i++) { hist[i] = 0; // chist[i] = 0; } // get the histogram from inimg for (i=0; i