Source: background.js

const debug = require('debug')('image-augment:augmenters:background');
const h = require('hasard');
const AbstractAugmenter = require('./abstract');

/**
* Overlay an image on top of another image
* @param {Object | Generator | Hasard} generator kernel size or explict options
* @param {Generator} generator.generator Generator
* @example
// Add a noisy background
const noiseGenerator = ia.gaussianNoise();
const augmenter = ia.background(noiseGenerator);
*/

class BackgroundAugmenter extends AbstractAugmenter {
	constructor(opts, ia) {
		let o;
		if (AbstractAugmenter.isGenerator(opts) || h.isHasard(opts)) {
			o = {generator: opts};
		} else {
			o = opts;
		}

		super(o, ia);
		const {generator} = o;
		if (!generator) {
			throw (new Error('background augmenter need a generator as input'));
		}

		this.generator = generator;
	}

	buildAllImagesHasard({metadatas}) {
		const contextName = 'background';
		debug(`start generator ${this._name} (${this.backend._tf && this.backend._tf.memory().numTensors})`);
		this.generator.setBackend(this.backend.backendLib);
		const joinId = function (m) {
			return m.width + m.height + m.channels;
		};

		const uniq = function (arr) {
			return arr.filter((a, index) => arr.indexOf(a) === index);
		};

		const mGroups = uniq(metadatas.map(joinId));

		if (mGroups.length > 1) {
			const generatedImagesHasard = h.array(metadatas.map(m => {
				return this.generator.build({nImages: 1, width: m.width, height: m.height, channels: m.channels});
			}));
			return h.object({
				background: h.fn(ims => this.backend.mergeImages(ims.map(({images}) => images), true))(generatedImagesHasard)
			}, {
				contextName
			});
		}

		return h.object({
			background: this.generator.build(Object.assign({}, metadatas[0], {nImages: metadatas.length}))
		}, {
			contextName
		});
	}

	augment({images, metadatas}, {background}) {
		// Console.log(image.getDataAsArray()[100].slice(50, 60))
		debug(`start overlay ${this._name} (${this.backend._tf && this.backend._tf.memory().numTensors})`);
		const res = this.backend.overlay({foregrounds: images, backgrounds: background.images, metadatas});
		this.backend.dispose(background.images);
		debug(`overlay done ${this._name} (${this.backend._tf && this.backend._tf.memory().numTensors})`);
		// Console.log(res.getDataAsArray()[100].slice(50, 60))
		return {images: res};
	}

	augmentBoxes({boxes}, {background}) {
		// Console.log('augmentBoxes ', {boxes, back: background.boxes})
		return boxes.concat(background.boxes || []);
	}
}

module.exports = BackgroundAugmenter;