/* * Gray8SumGray32.java * "Sum Gray8[Sub]Image to Gray32[Sub]Image". * Forms integral image by summing pixels in a * Gray8[Sub]Image to form a Gray32[Sub]Image. * The computation is O(i,j) = Sum for k<=i,l<=j of I(k,l) * Note output type is 32 bit because otherwise we'd get * truncation. With 32-bit output we can go up to * 65,536 = 256x256 pixels in the input image. * * Created on July 1, 2007, 3:39 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package jjil.algorithm; import jjil.core.Error; import jjil.core.Gray32Image; import jjil.core.Gray32OffsetImage; import jjil.core.Gray8Image; import jjil.core.Gray8OffsetImage; import jjil.core.Image; import jjil.core.PipelineStage; /** * Forms integral image by summing pixels in a * Gray8[Sub]Image to form a Gray32[Sub]Image.<br> * The computation is O(i,j) = ∑<sub>k ≤ i, l ≤ j</sub> I(k,l)<br> * Note output type is 32 bit because otherwise we'd get * truncation. With 32-bit output we can go up to * 2<sup>12</sup>× 2<sup>12</sup> = 4096 × 4096 pixels in the input image. * * @author webb */ public class Gray8SumGray32 extends PipelineStage { /** * Creates a new instance of Gray8SumGray32 */ public Gray8SumGray32() { } /** * Form the cumulative sum<p> * Output(i,j) = ∑<sub>k ≤ i, l ≤ j</sub> Input(k,l) * @param image input image. * @throws jjil.core.Error if the input is not a Gray8Image. */ public void push(Image image) throws jjil.core.Error { if (!(image instanceof Gray8Image)) { throw new Error( Error.PACKAGE.ALGORITHM, ErrorCodes.IMAGE_NOT_GRAY8IMAGE, image.toString(), null, null); } Gray32Image imageResult; if (image instanceof Gray8OffsetImage) { Gray8OffsetImage sub = (Gray8OffsetImage) image; imageResult = new Gray32OffsetImage(sub.getWidth(), sub.getHeight(), sub.getXOffset(), sub.getYOffset()); } else { // must be a Gray8Image imageResult = new Gray32Image(image.getWidth(), image.getHeight()); } byte[] inData = ((Gray8Image) image).getData(); // pointer to output data area, whether Gray32Image or Gray32OffsetImage int[] outData = imageResult.getData(); // initialize first row int prevPixel = 0; for (int i=0; i<image.getWidth(); i++) { prevPixel += inData[i]; outData[i] = prevPixel; } // initialize first column prevPixel = 0; for (int i=0; i<image.getHeight(); i++) { prevPixel += inData[i*image.getWidth()]; outData[i*image.getWidth()] = prevPixel; } // fill in the rest of the array int nPrevRow = 0; for (int i=1; i<image.getHeight(); i++) { int nCurrRow = nPrevRow + image.getWidth(); prevPixel = inData[nCurrRow]; for (int j=1; j<image.getWidth(); j++) { outData[nCurrRow + j] = inData[nCurrRow + j] + prevPixel + outData[nPrevRow + j]; prevPixel += inData[nCurrRow + j]; } nPrevRow = nCurrRow; } super.setOutput(imageResult); } }