All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aparapi.examples.median.MedianKernel7x7 Maven / Gradle / Ivy

/**
 * This product currently only contains code developed by authors
 * of specific components, as identified by the source code files.
 *
 * Since product implements StAX API, it has dependencies to StAX API
 * classes.
 *
 * For additional credits (generally to people who reported problems)
 * see CREDITS file.
 */
package com.aparapi.examples.median;

import com.aparapi.*;

/**
 * Provides support for pixel windows of size no greater than 49 (e.g. 7x7).
 * 

*

Demonstrates use of __private array for (partial) sorting, also demonstrates @NoCl annotation for specialised use of ThreadLocal in JTP execution. */ public class MedianKernel7x7 extends Kernel { public static final int CHANNEL_GRAY = -1; public static final int CHANNEL_ALPHA = 0; public static final int CHANNEL_RED = 1; public static final int CHANNEL_GREEN = 2; public static final int CHANNEL_BLUE = 3; protected static final int MONOCHROME = 0; protected static final int RGB = 1; protected static final int ARGB = 2; public static final int MAX_WINDOW_SIZE = 49; protected int _imageTypeOrdinal; protected int[] _sourcePixels; protected int _sourceWidth; protected int _sourceHeight; protected int[] _destPixels; // NB could also use suffix naming instead of annotation ... field would be named _window_$private$49 @PrivateMemorySpace(MAX_WINDOW_SIZE) private short[] _window = new short[MAX_WINDOW_SIZE]; @NoCL private static ThreadLocal _threadLocalWindow = new ThreadLocal() { @Override protected short[] initialValue() { return new short[MAX_WINDOW_SIZE]; } }; protected int _windowWidth; protected int _windowHeight; @NoCL public void setUpWindow() { _window = _threadLocalWindow.get(); } public void processImages(MedianSettings settings) { _windowWidth = settings.windowWidth; _windowHeight = settings.windowHeight; execute(_sourceWidth * _sourceHeight); } @Override public void run() { setUpWindow(); int index = getGlobalId(); int x = index % _sourceWidth; int y = index / _sourceWidth; int dx0 = -(_windowWidth / 2); int dx1 = _windowWidth + dx0; int dy0 = -(_windowHeight / 2); int dy1 = _windowHeight + dy0; int windowX0 = max(0, x + dx0); int windowX1 = min(_sourceWidth, x + dx1); int windowY0 = max(0, y + dy0); int windowY1 = min(_sourceHeight, y + dy1); int actualPixelCount = (windowX1 - windowX0) * (windowY1 - windowY0); int medianPixel = 0; if (_imageTypeOrdinal == MONOCHROME) { populateWindow(CHANNEL_GRAY, windowX0, windowX1, windowY0, windowY1); medianPixel = median(actualPixelCount); } else { int alpha = 0xff000000; if (_imageTypeOrdinal == ARGB) { populateWindow(CHANNEL_ALPHA, windowX0, windowX1, windowY0, windowY1); alpha = median(actualPixelCount); } populateWindow(CHANNEL_RED, windowX0, windowX1, windowY0, windowY1); int red = median(actualPixelCount); populateWindow(CHANNEL_GREEN, windowX0, windowX1, windowY0, windowY1); int green = median(actualPixelCount); populateWindow(CHANNEL_BLUE, windowX0, windowX1, windowY0, windowY1); int blue = median(actualPixelCount); medianPixel = alpha << 24 | red << 16 | green << 8 | blue; } _destPixels[index] = medianPixel; } protected void populateWindow(int channel, int windowX0, int windowX1, int windowY0, int windowY1) { int windowIndex = 0; for (int u = windowX0; u < windowX1; ++u) { for (int v = windowY0; v < windowY1; ++v) { int argb = _sourcePixels[u + _sourceWidth * v]; int sourcePixel = valueForChannel(channel, argb); setPixelWindowValue(windowIndex, (short) sourcePixel); ++windowIndex; } } } protected final int valueForChannel(int channel, int argb) { int sourcePixel = 0; if (channel == CHANNEL_GRAY) { sourcePixel = argb; } else if (channel == CHANNEL_ALPHA) { sourcePixel = (0xff000000 & argb) >>> 24; } else if (channel == CHANNEL_RED) { sourcePixel = (0x00ff0000 & argb) >>> 16; } else if (channel == CHANNEL_GREEN) { sourcePixel = (0x0000ff00 & argb) >>> 8; } else if (channel == CHANNEL_BLUE) { sourcePixel = 0x000000ff & argb; } return sourcePixel; } protected void setPixelWindowValue(int windowIndex, short value) { _window[windowIndex] = value; } /** * Fast median based on the following algorithm *

    *                   Author: Wirth, Niklaus
    *                    Title: Algorithms + data structures = programs
    *                Publisher: Englewood Cliffs: Prentice-Hall, 1976
    * 
*/ protected final int median(int actualPixelCount) { int i, j, L, m; short x; L = 0; m = actualPixelCount - 1; while (L < m) { x = _window[(actualPixelCount / 2)]; i = L; j = m; do { while (_window[i] < x) { i++; } while (x < _window[j]) { j--; } if (i <= j) { short temp = _window[i]; _window[i] = _window[j]; _window[j] = temp; i++; j--; } } while (i <= j); if (j < actualPixelCount / 2) { L = i; } if (actualPixelCount / 2 < i) { m = j; } } return _window[(actualPixelCount / 2)]; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy