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

boofcv.gui.image.VisualizeImageData Maven / Gradle / Ivy

Go to download

BoofCV is an open source Java library for real-time computer vision and robotics applications.

The newest version!
/*
 * Copyright (c) 2011-2016, 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.gui.image;

import boofcv.alg.InputSanityCheck;
import boofcv.alg.misc.GImageStatistics;
import boofcv.alg.misc.ImageStatistics;
import boofcv.io.image.ConvertBufferedImage;
import boofcv.struct.image.*;
import sun.awt.image.IntegerInterleavedRaster;

import java.awt.image.BufferedImage;

/**
 * Renders different primitive image types into a BufferedImage for visualization purposes.
 *
 * @author Peter Abeles
 */
public class VisualizeImageData {

	public static BufferedImage standard(ImageGray src, BufferedImage dst) {
		if (src.getDataType().isInteger()) {
			GrayI srcInt = (GrayI) src;

			if (src.getDataType().isSigned()) {
				double max = GImageStatistics.maxAbs(srcInt);
				return colorizeSign(srcInt, dst, (int) max);
			} else {
				if (src.getDataType().getNumBits() == 8) {
					dst = ConvertBufferedImage.convertTo((GrayU8) src, dst);
				} else {
					double max = GImageStatistics.maxAbs(srcInt);
					dst = grayUnsigned(srcInt, dst, (int) max);
				}
			}
		} else if (GrayF32.class.isAssignableFrom(src.getClass())) {
			GrayF32 img = (GrayF32) src;
			float max = ImageStatistics.maxAbs(img);

			boolean hasNegative = false;
			for (int i = 0; i < img.getHeight(); i++) {
				for (int j = 0; j < img.getWidth(); j++) {
					if (img.get(j, i) < 0) {
						hasNegative = true;
						break;
					}
				}
			}

			if (hasNegative)
				return colorizeSign(img, dst, (int) max);
			else
				return grayMagnitude((GrayF32) src, dst, max);
		}

		return dst;
	}

	/**
	 * 

* Renders a colored image where the color indicates the sign and intensity its magnitude. The input is divided * by normalize to render it in the appropriate scale. *

* * @param src Input single band image. * @param dst Where the image is rendered into. If null a new BufferedImage will be created and return. * @param normalize Used to normalize the input image. If ≤ 0 then the max value will be used * @return Rendered image. */ public static BufferedImage colorizeSign(ImageGray src, BufferedImage dst, double normalize) { dst = checkInputs(src, dst); if (normalize <= 0) { normalize = GImageStatistics.maxAbs(src); } if (normalize == 0) { // sets the output to black ConvertBufferedImage.convertTo(src,dst,true); return dst; } if (src.getClass().isAssignableFrom(GrayF32.class)) { return colorizeSign((GrayF32) src, dst, (float) normalize); } else { return colorizeSign((GrayI) src, dst, (int) normalize); } } private static BufferedImage colorizeSign(GrayI src, BufferedImage dst, int normalize) { dst = checkInputs(src, dst); for (int y = 0; y < src.height; y++) { for (int x = 0; x < src.width; x++) { int v = src.get(x, y); int rgb; if (v > 0) { rgb = ((255 * v / normalize) << 16); } else { rgb = -((255 * v / normalize) << 8); } dst.setRGB(x, y, rgb); } } return dst; } public static BufferedImage grayUnsigned(GrayI src, BufferedImage dst, int normalize) { dst = checkInputs(src, dst); if (src.getDataType().isSigned()) throw new IllegalArgumentException("Can only convert unsigned images."); for (int y = 0; y < src.height; y++) { for (int x = 0; x < src.width; x++) { int v = src.get(x, y); int rgb = 255 * v / normalize; dst.setRGB(x, y, rgb << 16 | rgb << 8 | rgb); } } return dst; } /** *

* Renders a gray scale image of the input image's intensity.
*
* dst(i,j) = 255*abs(src(i,j))/normalize *

* * @param src Input single band image. * @param dst Where the image is rendered into. If null a new BufferedImage will be created and return. * @param normalize Used to normalize the input image. If < 0 then this value is automatically computed. * @return Rendered image. */ public static BufferedImage grayMagnitude(ImageGray src, BufferedImage dst, double normalize) { if (normalize < 0) normalize = GImageStatistics.maxAbs(src); dst = checkInputs(src, dst); if (src.getDataType().isInteger()) { return grayMagnitude((GrayI) src, dst, (int) normalize); } else if( src instanceof GrayF32){ return grayMagnitude((GrayF32) src, dst, (float) normalize); } else if( src instanceof GrayF64){ return grayMagnitude((GrayF64) src, dst, (float) normalize); } else { throw new RuntimeException("Unsupported type"); } } /** *

* Renders a gray scale image using color values from cold to hot. *

* * @param src Input single band image. * @param dst Where the image is rendered into. If null a new BufferedImage will be created and return. * @param normalize Used to normalize the input image. * @return Rendered image. */ public static BufferedImage grayMagnitudeTemp(ImageGray src, BufferedImage dst, double normalize) { if (normalize < 0) normalize = GImageStatistics.maxAbs(src); dst = checkInputs(src, dst); if (src.getDataType().isInteger()) { return grayMagnitudeTemp((GrayI) src, dst, (int) normalize); } else { throw new RuntimeException("Add support"); } } private static BufferedImage grayMagnitude(GrayI src, BufferedImage dst, int maxValue) { for (int y = 0; y < src.height; y++) { for (int x = 0; x < src.width; x++) { int v = Math.abs(src.get(x, y)); int rgb = 255 * v / maxValue; dst.setRGB(x, y, rgb << 16 | rgb << 8 | rgb); } } return dst; } private static BufferedImage grayMagnitudeTemp(GrayI src, BufferedImage dst, int maxValue) { int halfValue = maxValue / 2 + maxValue % 2; for (int y = 0; y < src.height; y++) { for (int x = 0; x < src.width; x++) { int v = Math.abs(src.get(x, y)); int r, b; if (v >= halfValue) { r = 255 * (v - halfValue) / halfValue; b = 0; } else { r = 0; b = 255 * v / halfValue; } if (v == 0) { r = b = 0; } else { r = 255 * v / maxValue; b = 255 * (maxValue - v) / maxValue; } dst.setRGB(x, y, r << 16 | b); } } return dst; } /** *

* Renders a gray scale image using color values from cold to hot. *

* * @param disparity Input disparity image * @param dst Where the image is rendered into. If null a new BufferedImage will be created and return. * @param minDisparity Minimum disparity that can be computed * @param maxDisparity Maximum disparity that can be computed * @param invalidColor RGB value for invalid pixels. Try 0xFF << 8 for green * @return Rendered image. */ public static BufferedImage disparity(ImageGray disparity, BufferedImage dst, int minDisparity, int maxDisparity, int invalidColor) { if( dst == null ) dst = new BufferedImage(disparity.getWidth(),disparity.getHeight(),BufferedImage.TYPE_INT_RGB); if (disparity.getDataType().isInteger()) { return disparity((GrayI) disparity, dst, minDisparity, maxDisparity, invalidColor); } else if (disparity instanceof GrayF32) { return disparity((GrayF32) disparity, dst, minDisparity, maxDisparity, invalidColor); } else { throw new RuntimeException("Add support"); } } private static BufferedImage disparity(GrayI src, BufferedImage dst, int minValue, int maxValue, int invalidColor) { int range = maxValue - minValue; for (int y = 0; y < src.height; y++) { for (int x = 0; x < src.width; x++) { int v = src.unsafe_get(x, y); if (v > range) { dst.setRGB(x, y, invalidColor); } else { int r, b; if (v == 0) { r = b = 0; } else { r = 255 * v / maxValue; b = 255 * (maxValue - v) / maxValue; } dst.setRGB(x, y, r << 16 | b); } } } return dst; } private static BufferedImage disparity(GrayF32 src, BufferedImage dst, int minValue, int maxValue, int invalidColor) { float range = maxValue - minValue; for (int y = 0; y < src.height; y++) { for (int x = 0; x < src.width; x++) { float v = src.unsafe_get(x, y); if (v > range) { dst.setRGB(x, y, invalidColor); } else { int r, b; if (v == 0) { r = b = 0; } else { r = (int) (255 * v / maxValue); b = (int) (255 * (maxValue - v) / maxValue); } dst.setRGB(x, y, r << 16 | b); } } } return dst; } private static BufferedImage colorizeSign(GrayF32 src, BufferedImage dst, float maxAbsValue) { for (int y = 0; y < src.height; y++) { for (int x = 0; x < src.width; x++) { float v = src.get(x, y); int rgb; if (v > 0) { rgb = (int) (255 * v / maxAbsValue) << 16; } else { rgb = (int) (-255 * v / maxAbsValue) << 8; } dst.setRGB(x, y, rgb); } } return dst; } public static BufferedImage graySign(GrayF32 src, BufferedImage dst, float maxAbsValue) { dst = checkInputs(src, dst); if (maxAbsValue < 0) maxAbsValue = ImageStatistics.maxAbs(src); for (int y = 0; y < src.height; y++) { for (int x = 0; x < src.width; x++) { float v = src.get(x, y); int rgb = 127 + (int) (127 * v / maxAbsValue); dst.setRGB(x, y, rgb << 16 | rgb << 8 | rgb); } } return dst; } private static BufferedImage grayMagnitude(GrayF32 src, BufferedImage dst, float maxAbsValue) { for (int y = 0; y < src.height; y++) { for (int x = 0; x < src.width; x++) { float v = Math.abs(src.get(x, y)); int rgb = (int) (255 * v / maxAbsValue); dst.setRGB(x, y, rgb << 16 | rgb << 8 | rgb); } } return dst; } private static BufferedImage grayMagnitude(GrayF64 src, BufferedImage dst, double maxAbsValue) { for (int y = 0; y < src.height; y++) { for (int x = 0; x < src.width; x++) { double v = Math.abs(src.get(x, y)); int rgb = (int) (255 * v / maxAbsValue); dst.setRGB(x, y, rgb << 16 | rgb << 8 | rgb); } } return dst; } /** * If null the dst is declared, otherwise it checks to see if the 'dst' as the same shape as 'src'. * * The returned image will be 8-bit RGB */ private static BufferedImage checkInputs(ImageBase src, BufferedImage dst) { if (dst != null) { if (dst.getWidth() != src.getWidth() || dst.getHeight() != src.getHeight()) { throw new IllegalArgumentException("image dimension are different"); } } else { dst = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_RGB); } return dst; } /** * Renders two gradients on the same image using two sets of colors, on for each input image. * * @param derivX (Input) Image with positive and negative values. * @param derivY (Input) Image with positive and negative values. * @param maxAbsValue The largest absolute value of any pixel in the image. Set to < 0 if not known. * @return visualized gradient */ public static BufferedImage colorizeGradient(ImageGray derivX , ImageGray derivY , double maxAbsValue ){ if( derivX instanceof GrayS16) { return colorizeGradient((GrayS16)derivX,(GrayS16)derivY,(int)maxAbsValue); } else if( derivX instanceof GrayF32) { return colorizeGradient((GrayF32)derivX,(GrayF32)derivY,(int)maxAbsValue); } else { throw new IllegalArgumentException("Image type not supported"); } } /** * Renders two gradients on the same image using two sets of colors, on for each input image. * * @param derivX (Input) Image with positive and negative values. * @param derivY (Input) Image with positive and negative values. * @param maxAbsValue The largest absolute value of any pixel in the image. Set to < 0 if not known. * @return visualized gradient */ public static BufferedImage colorizeGradient(GrayS16 derivX , GrayS16 derivY , int maxAbsValue ) { InputSanityCheck.checkSameShape(derivX,derivY); BufferedImage output = new BufferedImage(derivX.width,derivX.height,BufferedImage.TYPE_INT_RGB); IntegerInterleavedRaster outputRaster = (IntegerInterleavedRaster)output.getRaster(); int[] outData = outputRaster.getDataStorage(); int outStride = outputRaster.getScanlineStride(); int outOffset = outputRaster.getDataOffset(0)-outputRaster.getPixelStride()+1; if( maxAbsValue < 0 ) { maxAbsValue = ImageStatistics.maxAbs(derivX); maxAbsValue = Math.max(maxAbsValue, ImageStatistics.maxAbs(derivY)); } if( maxAbsValue == 0 ) return output; int indexOut = outOffset; for( int y = 0; y < derivX.height; y++ ) { int indexX = derivX.startIndex + y*derivX.stride; int indexY = derivY.startIndex + y*derivY.stride; for( int x = 0; x < derivX.width; x++ ) { int valueX = derivX.data[ indexX++ ]; int valueY = derivY.data[ indexY++ ]; int r=0,g=0,b=0; if( valueX > 0 ) { r = 255*valueX/maxAbsValue; } else { g = -255*valueX/maxAbsValue; } if( valueY > 0 ) { b = 255*valueY/maxAbsValue; } else { int v = -255*valueY/maxAbsValue; r += v; g += v; if( r > 255 ) r = 255; if( g > 255 ) g = 255; } outData[indexOut++] = r << 16 | g << 8 | b; } } return output; } /** * Renders two gradients on the same image using two sets of colors, on for each input image. * * @param derivX (Input) Image with positive and negative values. * @param derivY (Input) Image with positive and negative values. * @param maxAbsValue The largest absolute value of any pixel in the image. Set to < 0 if not known. * @return visualized gradient */ public static BufferedImage colorizeGradient(GrayF32 derivX , GrayF32 derivY , float maxAbsValue ) { InputSanityCheck.checkSameShape(derivX,derivY); BufferedImage output = new BufferedImage(derivX.width,derivX.height,BufferedImage.TYPE_INT_RGB); IntegerInterleavedRaster outputRaster = (IntegerInterleavedRaster)output.getRaster(); int[] outData = outputRaster.getDataStorage(); int outStride = outputRaster.getScanlineStride(); int outOffset = outputRaster.getDataOffset(0)-outputRaster.getPixelStride()+1; if( maxAbsValue < 0 ) { maxAbsValue = ImageStatistics.maxAbs(derivX); maxAbsValue = Math.max(maxAbsValue, ImageStatistics.maxAbs(derivY)); } if( maxAbsValue == 0 ) return output; int indexOut = outOffset; for( int y = 0; y < derivX.height; y++ ) { int indexX = derivX.startIndex + y*derivX.stride; int indexY = derivY.startIndex + y*derivY.stride; for( int x = 0; x < derivX.width; x++ ) { float valueX = derivX.data[ indexX++ ]; float valueY = derivY.data[ indexY++ ]; int r=0,g=0,b=0; if( valueX > 0 ) { r = (int)(255*valueX/maxAbsValue); } else { g = -(int)(255*valueX/maxAbsValue); } if( valueY > 0 ) { b = (int)(255*valueY/maxAbsValue); } else { int v = -(int)(255*valueY/maxAbsValue); r += v; g += v; if( r > 255 ) r = 255; if( g > 255 ) g = 255; } outData[indexOut++] = r << 16 | g << 8 | b; } } return output; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy