image-js
Version:
Image processing and manipulation in JavaScript
43 lines • 1.99 kB
JavaScript
import { xMedian } from 'ml-spectra-processing';
import { Image } from '../Image.js';
import { getDefaultColor } from "../utils/getDefaultColor.js";
import { getBorderInterpolation } from '../utils/interpolateBorder.js';
import checkProcessable from '../utils/validators/checkProcessable.js';
/**
* Calculate a new image that replaces all pixel values by the median of neighbouring pixels.
* @param image - Image to be filtered.
* @param options - MedianFilterOptions
* @returns Image after median filter.
*/
export function medianFilter(image, options = {}) {
const { cellSize = 3, borderType = 'reflect101', borderValue = getDefaultColor(image), } = options;
checkProcessable(image, {
bitDepth: [8, 16],
});
if (cellSize < 1) {
throw new RangeError(`Invalid property "cellSize". Must be greater than 0. Received ${cellSize}.`);
}
if (cellSize % 2 === 0) {
throw new RangeError(`Invalid property "cellSize". Must be an odd number. Received ${cellSize}.`);
}
const interpolateBorder = getBorderInterpolation(borderType, borderValue);
const newImage = Image.createFrom(image);
const size = cellSize ** 2;
const cellValues = new Uint16Array(size);
const halfCellSize = (cellSize - 1) / 2;
for (let channel = 0; channel < image.channels; channel++) {
for (let row = 0; row < image.height; row++) {
for (let column = 0; column < image.width; column++) {
let n = 0;
for (let cellRow = -halfCellSize; cellRow <= halfCellSize; cellRow++) {
for (let cellColumn = -halfCellSize; cellColumn <= halfCellSize; cellColumn++) {
cellValues[n++] = interpolateBorder(column + cellColumn, row + cellRow, channel, image);
}
}
newImage.setValue(column, row, channel, xMedian(cellValues));
}
}
}
return newImage;
}
//# sourceMappingURL=medianFilter.js.map