/*
 * Copyright (c) 2011-2015, 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.learning;

import boofcv.gui.image.ShowImages;
import org.ejml.data.DenseMatrix64F;
import org.ejml.ops.RandomMatrices;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.util.Random;


/**
 * Visualizes a confusion matrix.  Each element is assumed to have a value from 0 to 1.0
 *
 * @author Peter Abeles
 */
public class ConfusionMatrixPanel extends JPanel {

	DenseMatrix64F temp = new DenseMatrix64F(1,1);
	DenseMatrix64F confusion = new DenseMatrix64F(1,1);
	boolean dirty = false;

	boolean gray = false;

	boolean showNumbers = true;

	boolean showZeros = true;

	/**
	 * Constructor that specifies the confusion matrix and width/height
	 * @param width preferred width and height
	 * @param gray Render gray scale or color image
	 */
	public ConfusionMatrixPanel( DenseMatrix64F M , int width , boolean gray ) {
		this(width, width);
		setMatrix(M);
		this.gray = gray;
	}

	/**
	 * Constructor in which the prefered width and height is specified in pixels
	 * @param width preferred width
	 * @param height preferred height
	 */
	public ConfusionMatrixPanel(int width, int height) {
		setPreferredSize(new Dimension(width,height));
		setMinimumSize(new Dimension(width, height));
	}

	public void setMatrix( DenseMatrix64F A ) {
		synchronized ( this ) {
			temp.set(A);
			dirty = true;
		}
		repaint();
	}

	public boolean isGray() {
		return gray;
	}

	public void setGray(boolean gray) {
		this.gray = gray;
	}

	public boolean isShowNumbers() {
		return showNumbers;
	}

	public void setShowNumbers(boolean showNumbers) {
		this.showNumbers = showNumbers;
	}

	public boolean isShowZeros() {
		return showZeros;
	}

	public void setShowZeros(boolean showZeros) {
		this.showZeros = showZeros;
	}

	@Override
	public synchronized void paint( Graphics g ) {
		synchronized ( this ) {
			if (dirty) {
				confusion.set(temp);
				dirty = false;
			}
		}

		Graphics2D g2 = (Graphics2D)g;

		int numRows = confusion.getNumRows();
		int numCols = confusion.getNumCols();

		int height = getHeight();
		int width = getWidth();

		Font font = new Font("Serif", Font.BOLD, (int)(0.6*width/numCols));
		g2.setFont(font);
		FontMetrics metrics = g2.getFontMetrics(font);
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

		for (int i = 0; i < numRows; i++) {
			int y0 = i*height/(numRows-1);
			int y1 = (i+1)*height/(numRows-1);

			for (int j = 0; j < numCols; j++) {
				int x0 = j*width/(numCols-1);
				int x1 = (j+1)*width/(numCols-1);

				double value = confusion.unsafe_get(i,j);

				int red,green,blue;
				if( gray ) {
					red = green = blue = (int)(255*(1.0-value));
				} else {
					green = 0;
					red = (int)(255*value);
					blue = (int)(255*(1.0-value));
				}
				g2.setColor(new Color(red, green, blue));

				g2.fillRect(x0,y0,x1-x0,y1-y0);

				if( showNumbers && (showZeros || value != 0 )) {
					int a = (red+green+blue)/3;


					String text = ""+(int)(value*100.0+0.5);
					Rectangle2D r = metrics.getStringBounds(text,null);

					float adjX = (float)(r.getX()*2 + r.getWidth())/2.0f;
					float adjY = (float)(r.getY()*2 + r.getHeight())/2.0f;

					float x = ((x1+x0)/2f-adjX);
					float y = ((y1+y0)/2f-adjY);



					int gray = a > 127 ? 0 : 255;

					g2.setColor(new Color(gray,gray,gray));
					g2.drawString(text,x,y);
				}
			}
		}
	}

	public static void main(String[] args) {
		DenseMatrix64F m = RandomMatrices.createRandom(5,5,0,1,new Random(234));

		ShowImages.showWindow(new ConfusionMatrixPanel(m,300,true),"Window",true);
	}

}

 

Ads help maintain this website.