UNPKG

image-js

Version:

Image processing and manipulation in JavaScript

64 lines (51 loc) 1.98 kB
import quickSelectMedian from 'median-quickselect'; import { validateArrayOfChannels } from '../../util/channel'; import Image from '../Image'; /** * Each pixel of the image becomes the median of the neighbor pixels. * @memberof Image * @instance * @param {object} options * @param {SelectedChannels} [options.channels] - Specify which channels should be processed. * @param {number} [options.radius=1] - Distance of the square to take the mean of. * @param {string} [options.border='copy'] - Algorithm that will be applied after to deal with borders. * @return {Image} */ export default function medianFilter(options = {}) { let { radius = 1, border = 'copy', channels } = options; this.checkProcessable('medianFilter', { bitDepth: [8, 16], }); if (radius < 1) { throw new Error('radius must be greater than 0'); } channels = validateArrayOfChannels(this, channels, true); let kWidth = radius; let kHeight = radius; let newImage = Image.createFrom(this); let size = (kWidth * 2 + 1) * (kHeight * 2 + 1); let kernel = new Array(size); for (let channel = 0; channel < channels.length; channel++) { let c = channels[channel]; for (let y = kHeight; y < this.height - kHeight; y++) { for (let x = kWidth; x < this.width - kWidth; x++) { let n = 0; for (let j = -kHeight; j <= kHeight; j++) { for (let i = -kWidth; i <= kWidth; i++) { let index = ((y + j) * this.width + x + i) * this.channels + c; kernel[n++] = this.data[index]; } } let index = (y * this.width + x) * this.channels + c; newImage.data[index] = quickSelectMedian(kernel); } } } if (this.alpha && !channels.includes(this.channels)) { for (let i = this.components; i < this.data.length; i = i + this.channels) { newImage.data[i] = this.data[i]; } } newImage.setBorder({ size: [kWidth, kHeight], algorithm: border }); return newImage; }