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

boofcv.core.image.FactoryGImageMultiBand Maven / Gradle / Ivy

/*
 * Copyright (c) 2021, Peter Abeles. All Rights Reserved.
 *
 * This file is part of BoofCV (http://boofcv.org).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package boofcv.core.image;

import boofcv.misc.BoofMiscOps;
import boofcv.struct.border.ImageBorder;
import boofcv.struct.border.ImageBorder_IL_F32;
import boofcv.struct.border.ImageBorder_IL_F64;
import boofcv.struct.border.ImageBorder_IL_S32;
import boofcv.struct.image.*;

/**
 * @author Peter Abeles
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public class FactoryGImageMultiBand {

	public static GImageMultiBand wrap( ImageBase image ) {
		if (image instanceof ImageGray)
			return wrap((ImageGray)image);
		else if (image instanceof Planar)
			return wrap((Planar)image);
		else if (image instanceof ImageInterleaved)
			return wrap((ImageInterleaved)image);
		throw new RuntimeException("Unknown image type");
	}

	public static GImageMultiBand wrap( ImageGray image ) {
		return new GSingleToMB(FactoryGImageGray.wrap(image));
	}

	public static GImageMultiBand create( ImageType imageType ) {
		if (imageType.getFamily() == ImageType.Family.GRAY) {
			return new GSingleToMB(FactoryGImageGray.create(imageType.getImageClass()));
		}
		if (imageType.getFamily() == ImageType.Family.PLANAR) {
			return new PL();
		} else if (imageType.getFamily() == ImageType.Family.INTERLEAVED) {
			return switch (imageType.getDataType()) {
				case U8 -> new IL_U8();
				case S8 -> new IL_S8();
				case F32 -> new IL_F32();
				default -> throw new IllegalArgumentException("Need to support more data types");
			};
		} else {
			throw new RuntimeException("Add support for more families");
		}
	}

	public static GImageMultiBand wrap( Planar image ) {
		return new PL(image);
	}

	public static GImageMultiBand wrap( ImageInterleaved image ) {
		return switch (image.getDataType()) {
			case U8 -> new IL_U8((InterleavedU8)image);
			case S8 -> new IL_S8((InterleavedS8)image);
			case U16 -> new IL_U16((InterleavedU16)image);
			case S16 -> new IL_S16((InterleavedS16)image);
			case S32 -> new IL_S32((InterleavedS32)image);
			case S64 -> new IL_S64((InterleavedS64)image);
			case F32 -> new IL_F32((InterleavedF32)image);
			case F64 -> new IL_F64((InterleavedF64)image);
			default -> throw new IllegalArgumentException("Need to support more data types: " + image.getDataType());
		};
	}

	public static class PL implements GImageMultiBand {
		Planar image;
		GImageGray[] bandWrappers;

		public PL( Planar image ) {
			wrap(image);
		}

		public PL() {
		}

		@Override
		public void wrap( ImageBase image ) {
			if (this.image == null) {
				this.image = (Planar)image;

				bandWrappers = new GImageGray[this.image.getNumBands()];
				for (int i = 0; i < bandWrappers.length; i++) {
					bandWrappers[i] = FactoryGImageGray.wrap(this.image.getBand(i));
				}
			} else {
				this.image = (Planar)image;
				for (int i = 0; i < bandWrappers.length; i++) {
					bandWrappers[i].wrap(this.image.getBand(i));
				}
			}
		}

		@Override
		public int getWidth() {return image.getWidth();}

		@Override
		public int getHeight() {return image.getHeight();}

		@Override
		public int getNumberOfBands() {return image.getNumBands();}

		@Override
		public int getPixelStride() {
			return 1;
		}

		@Override
		public int getIndex( int x, int y ) {
			return this.image.getIndex(x, y);
		}

		@Override
		public void set( int x, int y, float[] value ) {
			int index = this.image.getIndex(x, y);
			setF(index, value);
		}

		@Override
		public void get( int x, int y, float[] value ) {
			int index = this.image.getIndex(x, y);
			getF(index, value);
		}

		@Override
		public Number get( int x, int y, int band ) {
			return bandWrappers[band].get(x, y);
		}

		@Override
		public void setF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				bandWrappers[i].set(index, value[i]);
			}
		}

		@Override
		public void getF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				value[i] = bandWrappers[i].getF(index);
			}
		}

		@Override
		public float getF( int index ) {
			throw new RuntimeException("Not supported for Planar images. Would be slow.");
		}

		@Override
		public > T getImage() {
			return (T)image;
		}
	}

	public static class GSingleToMB implements GImageMultiBand {

		GImageGray sb;

		public GSingleToMB( GImageGray sb ) {
			this.sb = sb;
		}

		@Override
		public void wrap( ImageBase image ) {
			if (this.sb == null) {
				this.sb = FactoryGImageGray.wrap((ImageGray)image);
			} else {
				this.sb.wrap((ImageGray)image);
			}
		}

		@Override
		public int getWidth() {return sb.getWidth();}

		@Override
		public int getHeight() {return sb.getHeight();}

		@Override
		public int getNumberOfBands() {return 1;}

		@Override
		public int getPixelStride() {
			return 1;
		}

		@Override
		public int getIndex( int x, int y ) {
			return sb.getImage().getIndex(x, y);
		}

		@Override
		public void set( int x, int y, float[] value ) {
			sb.set(x, y, value[0]);
		}

		@Override
		public void get( int x, int y, float[] value ) {
			value[0] = sb.unsafe_getF(x, y);
		}

		@Override
		public Number get( int x, int y, int band ) {
			if (band != 0)
				throw new IllegalArgumentException("Must be band 0");
			return this.sb.get(x, y);
		}

		@Override
		public void setF( int index, float[] value ) {
			sb.set(index, value[0]);
		}

		@Override
		public void getF( int index, float[] value ) {
			value[0] = sb.getF(index);
		}

		@Override
		public float getF( int index ) {
			return sb.getF(index);
		}

		@Override
		public > T getImage() {
			return (T)sb.getImage();
		}
	}

	public static abstract class IL> implements GImageMultiBand {
		T image;

		@Override
		public void wrap( ImageBase image ) {
			this.image = (T)image;
		}

		@Override
		public int getWidth() {return image.getWidth();}

		@Override
		public int getHeight() {return image.getHeight();}

		@Override
		public int getNumberOfBands() {return image.getNumBands();}

		@Override
		public int getPixelStride() {
			return image.getNumBands();
		}

		@Override
		public int getIndex( int x, int y ) {
			return image.getIndex(x, y);
		}

		@Override
		public > GT getImage() {
			return (GT)image;
		}
	}

	public static class IL_U8 extends IL {
		public IL_U8( InterleavedU8 image ) {
			wrap(image);
		}

		public IL_U8() {}

		@Override
		public void set( int x, int y, float[] value ) {
			setF(image.getIndex(x, y), value);
		}

		@Override
		public void get( int x, int y, float[] value ) {
			getF(image.getIndex(x, y), value);
		}

		@Override
		public Number get( int x, int y, int band ) {
			return image.data[image.getIndex(x, y, band)] & 0xFF;
		}

		@Override
		public void setF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				image.data[index++] = (byte)value[i];
			}
		}

		@Override
		public void getF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				value[i] = image.data[index++] & 0xFF;
			}
		}

		@Override
		public float getF( int index ) {
			return image.data[index] & 0xFF;
		}
	}

	public static class IL_S8 extends IL {
		public IL_S8( InterleavedS8 image ) {
			wrap(image);
		}

		public IL_S8() {}

		@Override
		public void set( int x, int y, float[] value ) {
			setF(image.getIndex(x, y), value);
		}

		@Override
		public void get( int x, int y, float[] value ) {
			getF(image.getIndex(x, y), value);
		}

		@Override
		public Number get( int x, int y, int band ) {
			return image.data[image.getIndex(x, y, band)];
		}

		@Override
		public void setF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				image.data[index++] = (byte)value[i];
			}
		}

		@Override
		public void getF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				value[i] = image.data[index++];
			}
		}

		@Override
		public float getF( int index ) {
			return image.data[index];
		}
	}

	public static class IL_U16 extends IL {
		public IL_U16( InterleavedU16 image ) {
			wrap(image);
		}

		public IL_U16() {}

		@Override
		public void set( int x, int y, float[] value ) {
			setF(image.getIndex(x, y), value);
		}

		@Override
		public void get( int x, int y, float[] value ) {
			getF(image.getIndex(x, y), value);
		}

		@Override
		public Number get( int x, int y, int band ) {
			return image.data[image.getIndex(x, y, band)] & 0xFFFF;
		}

		@Override
		public void setF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				image.data[index++] = (short)value[i];
			}
		}

		@Override
		public void getF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				value[i] = image.data[index++] & 0xFFFF;
			}
		}

		@Override
		public float getF( int index ) {
			return image.data[index] & 0xFF;
		}
	}

	public static class IL_S16 extends IL {
		public IL_S16( InterleavedS16 image ) {
			wrap(image);
		}

		public IL_S16() {}

		@Override
		public void set( int x, int y, float[] value ) {
			setF(image.getIndex(x, y), value);
		}

		@Override
		public void get( int x, int y, float[] value ) {
			getF(image.getIndex(x, y), value);
		}

		@Override
		public Number get( int x, int y, int band ) {
			return image.data[image.getIndex(x, y, band)];
		}

		@Override
		public void setF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				image.data[index++] = (short)value[i];
			}
		}

		@Override
		public void getF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				value[i] = image.data[index++];
			}
		}

		@Override
		public float getF( int index ) {
			return image.data[index];
		}
	}

	public static class IL_S32 extends IL {
		public IL_S32( InterleavedS32 image ) {
			wrap(image);
		}

		public IL_S32() {}

		@Override
		public void set( int x, int y, float[] value ) {
			setF(image.getIndex(x, y), value);
		}

		@Override
		public void get( int x, int y, float[] value ) {
			getF(image.getIndex(x, y), value);
		}

		@Override
		public Number get( int x, int y, int band ) {
			return image.data[image.getIndex(x, y, band)];
		}

		@Override
		public void setF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				image.data[index++] = (int)value[i];
			}
		}

		@Override
		public void getF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				value[i] = image.data[index++];
			}
		}

		@Override
		public float getF( int index ) {
			return image.data[index];
		}
	}

	public static class IL_S64 extends IL {
		public IL_S64( InterleavedS64 image ) {
			wrap(image);
		}

		public IL_S64() {}

		@Override
		public void set( int x, int y, float[] value ) {
			setF(image.getIndex(x, y), value);
		}

		@Override
		public void get( int x, int y, float[] value ) {
			getF(image.getIndex(x, y), value);
		}

		@Override
		public Number get( int x, int y, int band ) {
			return image.data[image.getIndex(x, y, band)];
		}

		@Override
		public void setF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				image.data[index++] = (long)value[i];
			}
		}

		@Override
		public void getF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				value[i] = image.data[index++];
			}
		}

		@Override
		public float getF( int index ) {
			return image.data[index];
		}
	}

	public static class IL_F32 extends IL {
		public IL_F32( InterleavedF32 image ) {
			wrap(image);
		}

		public IL_F32() {}

		@Override
		public void set( int x, int y, float[] value ) {
			setF(image.getIndex(x, y), value);
		}

		@Override
		public void get( int x, int y, float[] value ) {
			getF(image.getIndex(x, y), value);
		}

		@Override
		public Number get( int x, int y, int band ) {
			return image.data[image.getIndex(x, y, band)];
		}

		@Override
		public void setF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				image.data[index++] = value[i];
			}
		}

		@Override
		public void getF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				value[i] = image.data[index++];
			}
		}

		@Override
		public float getF( int index ) {
			return image.data[index];
		}
	}

	public static class IL_F64 extends IL {
		public IL_F64( InterleavedF64 image ) {
			wrap(image);
		}

		public IL_F64() {}

		@Override
		public void set( int x, int y, float[] value ) {
			setF(image.getIndex(x, y), value);
		}

		@Override
		public void get( int x, int y, float[] value ) {
			getF(image.getIndex(x, y), value);
		}

		@Override
		public Number get( int x, int y, int band ) {
			return image.data[image.getIndex(x, y, band)];
		}

		@Override
		public void setF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				image.data[index++] = value[i];
			}
		}

		@Override
		public void getF( int index, float[] value ) {
			for (int i = 0; i < image.getNumBands(); i++) {
				value[i] = (float)image.data[index++];
			}
		}

		@Override
		public float getF( int index ) {
			return (float)image.data[index];
		}
	}

	public static GImageMultiBand wrap( ImageBorder image ) {
		if (image instanceof ImageBorder_IL_S32) {
			return new Border_IL_S32((ImageBorder_IL_S32)image);
		} else if (image instanceof ImageBorder_IL_F32) {
			return new Border_IL_F32((ImageBorder_IL_F32)image);
		} else if (image instanceof ImageBorder_IL_F64) {
			return new Border_IL_F64((ImageBorder_IL_F64)image);
		} else {
			throw new IllegalArgumentException("Not supported yet?");
		}
	}

	public static class Border_IL_S32 extends GMultiBorder {

		public Border_IL_S32( ImageBorder_IL_S32 image ) {
			super(image);
		}

		@Override
		public int getNumberOfBands() {
			return ((ImageMultiBand)image.getImage()).getNumBands();
		}

		@Override
		public void set( int x, int y, float[] value ) {
			int[] value_d = BoofMiscOps.convertArray(value, (int[])null);
			image.set(x, y, value_d);
		}

		@Override
		public void get( int x, int y, float[] value ) {
			int[] value_d = new int[value.length];
			image.get(x, y, value_d);
			BoofMiscOps.convertArray(value_d, value);
		}

		@Override
		public Number get( int x, int y, int band ) {
			int[] value_d = new int[image.getImage().getImageType().numBands];
			image.get(x, y, value_d);
			return value_d[band];
		}
	}

	public static class Border_IL_F32 extends GMultiBorder {

		public Border_IL_F32( ImageBorder_IL_F32 image ) {
			super(image);
		}

		@Override
		public int getNumberOfBands() {
			return ((ImageMultiBand)image.getImage()).getNumBands();
		}

		@Override
		public void set( int x, int y, float[] value ) {
			image.set(x, y, value);
		}

		@Override
		public void get( int x, int y, float[] value ) {
			image.get(x, y, value);
		}

		@Override
		public Number get( int x, int y, int band ) {
			float[] value_d = new float[image.getImage().getImageType().numBands];
			image.get(x, y, value_d);
			return value_d[band];
		}
	}

	public static class Border_IL_F64 extends GMultiBorder {

		public Border_IL_F64( ImageBorder_IL_F64 image ) {
			super(image);
		}

		@Override
		public int getNumberOfBands() {
			return ((ImageMultiBand)image.getImage()).getNumBands();
		}

		@Override
		public void set( int x, int y, float[] value ) {
			double[] value_d = BoofMiscOps.convertArray(value, (double[])null);
			image.set(x, y, value_d);
		}

		@Override
		public void get( int x, int y, float[] value ) {
			double[] value_d = new double[value.length];
			image.get(x, y, value_d);
			BoofMiscOps.convertArray(value_d, value);
		}

		@Override
		public Number get( int x, int y, int band ) {
			double[] value_d = new double[image.getImage().getImageType().numBands];
			image.get(x, y, value_d);
			return value_d[band];
		}
	}

	public static abstract class GMultiBorder implements GImageMultiBand {

		protected T image;

		protected GMultiBorder( T image ) {
			this.image = image;
		}

		@Override
		public void wrap( ImageBase image ) {
			this.image.setImage(image);
		}

		@Override
		public int getWidth() {
			return image.getImage().getWidth();
		}

		@Override
		public int getHeight() {
			return image.getImage().getHeight();
		}

		@Override
		public ImageMultiBand getImage() {
			return (ImageMultiBand)image.getImage();
		}

		@Override
		public int getPixelStride() {
			throw new RuntimeException("Not supported");
		}

		@Override
		public int getIndex( int x, int y ) {
			throw new RuntimeException("Not supported");
		}

		@Override
		public void setF( int index, float[] value ) {throw new RuntimeException("Not supported");}

		@Override
		public void getF( int index, float[] value ) {throw new RuntimeException("Not supported");}

		@Override
		public float getF( int index ) {throw new RuntimeException("Not supported");}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy