![JAR search and dependency download from the Maven repository](/logo.png)
boofcv.gui.image.VisualizeImageData Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of visualize Show documentation
Show all versions of visualize Show documentation
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