In the game that I am making called Flood It I am having trouble printing the objects that I am making which have a constructor that is:
Dot(int x, int y, int color)
I have three classes one class is DotInfo.java:
public class DotInfo {
private int x;
private int y;
private int color;
private boolean captured;
public DotInfo(int x, int y, int color){
this.x = x;
this.y = y;
this.color = color;
captured = false;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public void setCaptured(boolean captured) {
this.captured = captured;
}
public boolean isCaptured(){
return captured;
}
public int getColor() {
return color;
}
}
My second class is GameModel.java:
import java.util.Random;
public class GameModel {
/**
* predefined values to capture the color of a DotInfo
*/
public static final int COLOR_0 = 0;
public static final int COLOR_1 = 1;
public static final int COLOR_2 = 2;
public static final int COLOR_3 = 3;
public static final int COLOR_4 = 4;
public static final int COLOR_5 = 5;
public static final int NUMBER_OF_COLORS = 6;
public static DotInfo[][] dots;
private DotInfo dot;
private int size;
private int currentColor;
private Random generator;
private int steps;
private String rep;
/**
* Constructor to initialize the model to a given size of board.
*
* #param size
* the size of the board
*/
public GameModel(int size) {
this.size = size;
}
/**
* Resets the model to (re)start a game. The previous game (if there is one)
* is cleared up .
*/
public void reset(){
int color = 0;
dots = new DotInfo[size][size];
for (int i=0;i<size;i++) {
for (int j=0;j<size;j++) {
new DotInfo(i, j, generator.nextInt(NUMBER_OF_COLORS)+1);
System.out.println(dots[i][j]);
}
}
}
/**
* Getter method for the size of the game
*
* #return the value of the attribute sizeOfGame
*/
public int getSize(){
return size;
}
/**
* returns the current color of a given dot in the game
*
* #param i
* the x coordinate of the dot
* #param j
* the y coordinate of the dot
* #return the status of the dot at location (i,j)
*/
public int getColor(int i, int j){
int color=0;
for (int x=0;x<size;x++) {
for (int y=0;y<size;y++) {
if (dots[x][y].getX()==i && dots[x][y].getY()==j) {
color=dots[x][y].getColor();
}
}
}
return color;
}
/**
* returns true is the dot is captured, false otherwise
*
* #param i
* the x coordinate of the dot
* #param j
* the y coordinate of the dot
* #return the status of the dot at location (i,j)
*/
public boolean isCaptured(int i, int j){
boolean capture = true;
for (int x=0;x<size;x++) {
for (int y=0;y<size;y++) {
if (dots[x][y].getX()==i && dots[x][y].getY()==j) {
capture=dots[x][y].isCaptured();
}
}
}
return capture;
}
/**
* Sets the status of the dot at coordinate (i,j) to captured
*
* #param i
* the x coordinate of the dot
* #param j
* the y coordinate of the dot
*/
public void capture(int i, int j){
for (int x=0;x<size;x++) {
for (int y=0;y<size;y++) {
if (dots[x][y].getX()==i && dots[x][y].getY()==j) {
dots[x][y].setCaptured(true);
}
}
}
}
/**
* Getter method for the current number of steps
*
* #return the current number of steps
*/
public int getNumberOfSteps(){
return steps;
}
/**
* Setter method for currentSelectedColor
*
* #param val
* the new value for currentSelectedColor
*/
public void setCurrentSelectedColor(int val) {
currentColor = val;
}
/**
* Getter method for currentSelectedColor
*
* #return currentSelectedColor
*/
public int getCurrentSelectedColor() {
return currentColor;
}
/**
* Getter method for the model's dotInfo reference
* at location (i,j)
*
* #param i
* the x coordinate of the dot
* #param j
* the y coordinate of the dot
*
* #return model[i][j]
*/
public DotInfo get(int i, int j) {
for (int x=0;x<size;x++) {
for (int y=0;y<size;y++) {
if (dots[x][y].getX()==i && dots[x][y].getY()==j) {
dot = dots[x][y];
}
}
}
return dot;
}
/**
* The metod <b>step</b> updates the number of steps. It must be called
* once the model has been updated after the payer selected a new color.
*/
public void step(){
steps++;
}
/**
* The metod <b>isFinished</b> returns true iff the game is finished, that
* is, all the dats are captured.
*
* #return true if the game is finished, false otherwise
*/
public boolean isFinished(){
boolean flag=true;
for (int x=0;x<size;x++) {
for (int y=0;y<size;y++) {
if (dots[x][y].isCaptured()==false) {
flag=false;
}
}
}
return flag;
}
/**
* Builds a String representation of the model
*
* #return String representation of the model
*/
public String toString(){
for (int x=0;x<size;x++) {
for (int y=0;y<size;y++) {
rep += "Dot("+dots[x][y].getX()+", "+ dots[x][y].getY()+", "+dots[x][y].getColor()+")";
}
}
return rep;
}
}
My main class that runs everything is Floodit.java
public class FloodIt {
/**
* <b>main</b> of the application. Creates the instance of GameController
* and starts the game. If a game size (<12) is passed as parameter, it is
* used as the board size. Otherwise, a default value is passed
*
* #param args
* command line parameters
*/
public static void main(String[] args) {
GameModel model = new GameModel(5);
model.reset();
System.out.println(model);
}
}
Can someone tell me why my array will not update when i call my reset() method?
You forgot to assign the new DotInfo() objects to every position of the array.
The line:
new DotInfo(i, j, generator.nextInt(NUMBER_OF_COLORS)+1);
should be:
dots[i][j] = new DotInfo(i, j, generator.nextInt(NUMBER_OF_COLORS)+1);
in the reset method you have a for loop doing:
dots = new DotInfo[size][size];
for (int i=0;i<size;i++) {
for (int j=0;j<size;j++) {
new DotInfo(i, j, generator.nextInt(NUMBER_OF_COLORS)+1);
System.out.println(dots[i][j]);
}
}
this line,
new DotInfo(i, j, generator.nextInt(NUMBER_OF_COLORS)+1);
is doing NOTHING....
You are creating an object, yes, but not assigning it to nothing, so that object is getting lost....
You have to assign that new object to the element in the 2D array...
dots[i][j] = new DotInfo(i, j, generator.nextInt(NUMBER_OF_COLORS)+1);
Edit:
on the other hand, you need to init the generator object:
public GameModel(int size) {
this.size = size;
generator = new Random();
}
Related
I am developing a floodFill game using the Model-view-controller method. Now I am stuck building a stack that can store the clones of my gameModel objects.
public class GameModel implements Cloneable {
/**
* predefined values to capture the color of a DotInfo
*/
public static final int COLOR_0 = 0;
public static final int COLOR_1 = 1;
public static final int COLOR_2 = 2;
public static final int COLOR_3 = 3;
public static final int COLOR_4 = 4;
public static final int COLOR_5 = 5;
public static final int NUMBER_OF_COLORS = 6;
/**
* The current selection color
*/
private int currentSelectedColor;
/**
* The size of the game.
*/
private int sizeOfGame;
/**
* A 2 dimentionnal array of sizeOfGame*sizeOfGame recording the state of each dot
*/
private DotInfo[][] model;
/**
* The number of steps played since the last reset
*/
private int numberOfSteps;
/**
* The number of captered dots
*/
private int numberCaptured;
/**
* Random generator
*/
private Random generator;
/**
* Constructor to initialize the model to a given size of board.
*
* #param size
* the size of the board
*/
public GameModel(int size) {
generator = new Random();
sizeOfGame = size;
reset();
}
/**
* Resets the model to (re)start a game. The previous game (if there is one)
* is cleared up .
*/
public void reset(){
model = new DotInfo[sizeOfGame][sizeOfGame];
for(int i = 0; i < sizeOfGame; i++){
for(int j = 0; j < sizeOfGame; j++){
model[i][j] = new DotInfo(i,j,generator.nextInt(NUMBER_OF_COLORS));
}
}
numberOfSteps =0;
}
/**
* Getter method for the size of the game
*
* #return the value of the attribute sizeOfGame
*/
public int getSize(){
return sizeOfGame;
}
/**
* returns the color of a given dot in the game
*
* #param i
* the x coordinate of the dot
* #param j
* the y coordinate of the dot
* #return the status of the dot at location (i,j)
*/
public int getColor(int i, int j){
return isCaptured(i, j) ? currentSelectedColor : model[i][j].getColor();
}
/**
* returns true is the dot is captured, false otherwise
*
* #param i
* the x coordinate of the dot
* #param j
* the y coordinate of the dot
* #return the status of the dot at location (i,j)
*/
public boolean isCaptured(int i, int j){
return model[i][j].isCaptured();
}
/**
* Sets the status of the dot at coordinate (i,j) to captured
*
* #param i
* the x coordinate of the dot
* #param j
* the y coordinate of the dot
*/
public void capture(int i, int j){
model[i][j].setCaptured(true);
numberCaptured++;
}
/**
* Getter method for the current number of steps
*
* #return the current number of steps
*/
public int getNumberOfSteps(){
return numberOfSteps;
}
/**
* Setter method for currentSelectedColor
*
* #param val
* the new value for currentSelectedColor
*/
public void setCurrentSelectedColor(int val) {
currentSelectedColor = val;
}
/**
* Getter method for currentSelectedColor
*
* #return currentSelectedColor
*/
public int getCurrentSelectedColor() {
return currentSelectedColor ;
}
/**
* Getter method for the model's dotInfo reference
* at location (i,j)
*
* #param i
* the x coordinate of the dot
* #param j
* the y coordinate of the dot
*
* #return model[i][j]
*/
public DotInfo get(int i, int j) {
return model[i][j];
}
/**
* The metod <b>step</b> updates the number of steps. It must be called
* once the model has been updated after the payer selected a new color.
*/
public void step(){
numberOfSteps++;
}
/**
* The metod <b>isFinished</b> returns true iff the game is finished, that
* is, all the dats are captured.
*
* #return true if the game is finished, false otherwise
*/
public boolean isFinished(){
return numberCaptured == sizeOfGame*sizeOfGame;
}
public GameModel clone(){
try {
return (GameModel)super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
/**
* Builds a String representation of the model
*
* #return String representation of the model
*/
public String toString(){
StringBuffer b = new StringBuffer();
for(int i = 0; i < sizeOfGame; i++){
for(int j = 0; j < sizeOfGame; j++){
b.append(getColor(i, j) + " ");
}
b.append("\n");
}
return b.toString();
}
}
As you can see I have implemented cloneable and defined overriden the clone method the abstract class.
I am trying to clone the model so that the controller can use the function in its actionPerformed undo method.
public class GameController implements ActionListener{
/**
* Reference to the view of the board
*/
private GameView gameView;
/**
* Reference to the model of the game
*/
private GameModel gameModel;
private GameModel oldMove;
private int size;
private int i;
private int j;
private Stack<DotInfo> stack;
private boolean setting1;
private boolean setting2;
Stack<GameModel> steps;
/**
* Constructor used for initializing the controller. It creates the game's view
* and the game's model instances
*
* #param size
* the size of the board on which the game will be played
*/
public GameController(int size) {
gameModel = new GameModel(size);
gameView = new GameView(gameModel, this);
reset();
}
/**
* resets the game
*/
public void reset(){
steps= new GenericLinkedStack<GameModel>();
gameModel.reset();
flood();
gameView.update();
setting1 = false;
setting2 = false;
}
/**
* Callback used when the user clicks a button (reset or quit)
*
* #param e
* the ActionEvent
*/
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof DotButton) {
if(gameModel.getNumberOfSteps()==0){
int row = ((DotButton)(e.getSource())).getRow();
int column = ((DotButton)(e.getSource())).getColumn();
gameModel.capture(row,column);
}
selectColor(((DotButton)(e.getSource())).getColor());
} else if (e.getSource() instanceof JButton) {
JButton clicked = (JButton)(e.getSource());
if (clicked.getText().equals("Quit")) {
System.exit(0);
} else if (clicked.getText().equals("Reset")){
reset();
} else if (clicked.getText().equals("Redo")) {
} else if (clicked.getText().equals("Undo")) {
steps.pop();
gameView.update();
} else if (clicked.getText().equals("Settings")) {
gameView.settingsMenu();
}
} else if (e.getSource() instanceof JRadioButton) {
JRadioButton clickedR = (JRadioButton)(e.getSource());
if (clickedR.getText().equals("Torus")) {
setting1 = true;
}
if (clickedR.getText().equals("Diagonal")) {
setting2 = true;
}
}
}
/**
* <b>selectColor</b> is the method called when the user selects a new color.
* If that color is not the currently selected one, then it applies the logic
* of the game to capture possible locations. It then checks if the game
* is finished, and if so, congratulates the player, showing the number of
* moves, and gives to options: start a new game, or exit
* #param color
* the newly selected color
*/
public void selectColor(int color){
steps.push(gameModel.clone());
if(color != gameModel.getCurrentSelectedColor()) {
gameModel.setCurrentSelectedColor(color);
flood();
gameModel.step();
gameView.update();
finished();
}
}
/**
* <b>flood</b> is the method that computes which new dots should be ``captured''
* when a new color has been selected. The Model is updated accordingly
*/
private void flood() {
size = gameModel.getSize()-1;
stack = new GenericLinkedStack<DotInfo>();
for(int i =0; i < gameModel.getSize(); i++) {
for(int j =0; j < gameModel.getSize(); j++) {
if(gameModel.isCaptured(i,j)) {
stack.push(gameModel.get(i,j));
}
}
}
DotInfo dotInfo;
while(!stack.isEmpty()){
dotInfo = stack.pop();
i = dotInfo.getX();
j = dotInfo.getY();
orthogonal();
if (setting1 == true) {
torus();
}
if (setting2 == true) {
diagonal();
}
}
}
/**
* <b>shouldBeCaptured</b> is a helper method that decides if the dot
* located at position (i,j), which is next to a captured dot, should
* itself be captured
* #param i
* row of the dot
* #param j
* column of the dot
*/
private boolean shouldBeCaptured(int x, int y) {
return (!gameModel.isCaptured(x, y) && (gameModel.getColor(x,y) == gameModel.getCurrentSelectedColor())) ? true : false;
}
private void captureAndStack(int x, int y) {
gameModel.capture(x, y);
stack.push(gameModel.get(x,y));
}
private void finished() {
if(gameModel.isFinished()) {
if (gameView.finishedMenu() == 0) {
reset();
} else {
System.exit(0);
}
}
}
I am using a stack to hold the states of the game but I am not sure how i can update the view using the past state. I dont think you need to see the view class of my game.
Can someone lead me on the right path of which methods i should implement and where.
I have found Haralick's algorithm already implemented. It is used to get some feature with the help of Gray-Level Co-occurence matrices.
Now i have problems getting it to work. There are no exceptions. The code is fine. I'm not sure where to begin. Can someone help me with the first steps?How to i get a texture feature?
Below you can find the complete Haralick source code:
package de.lmu.dbs.jfeaturelib.features;
import Jama.Matrix;
import de.lmu.dbs.jfeaturelib.Progress;
import de.lmu.ifi.dbs.utilities.Arrays2;
import ij.plugin.filter.PlugInFilter;
import ij.process.ByteProcessor;
import ij.process.ImageProcessor;
import java.util.Arrays;
import java.util.EnumSet;
/**
* Haralick texture features
*
* http://makseq.com/materials/lib/Articles-Books/Filters/Texture/Co-occurence/haralick73.pdf
* <pre>
* #article{haralick1973textural,
* title={Textural features for image classification},
* author={Haralick, R.M. and Shanmugam, K. and Dinstein, I.},
* journal={Systems, Man and Cybernetics, IEEE Transactions on},
* volume={3},
* number={6},
* pages={610--621},
* year={1973},
* publisher={IEEE}
* }
* </pre>
*
* #author graf
*/
public class Haralick extends AbstractFeatureDescriptor {
/**
* The number of gray values for the textures
*/
private final int NUM_GRAY_VALUES = 32;
/**
* p_(x+y) statistics
*/
private double[] p_x_plus_y = new double[2 * NUM_GRAY_VALUES - 1];
/**
* p_(x-y) statistics
*/
private double[] p_x_minus_y = new double[NUM_GRAY_VALUES];
/**
* row mean value
*/
private double mu_x = 0;
/**
* column mean value
*/
private double mu_y = 0;
/**
* row variance
*/
private double var_x = 0;
/**
* column variance
*/
private double var_y = 0;
/**
* HXY1 statistics
*/
private double hx = 0;
/**
* HXY2 statistics
*/
private double hy = 0;
/**
* HXY1 statistics
*/
private double hxy1 = 0;
/**
* HXY2 statistics
*/
private double hxy2 = 0;
/**
* p_x statistics
*/
private double[] p_x = new double[NUM_GRAY_VALUES];
/**
* p_y statistics
*/
private double[] p_y = new double[NUM_GRAY_VALUES];
// -
private int haralickDist;
double[] features = null;
/**
* Constructs a haralick detector with default parameters.
*/
public Haralick() {
this.haralickDist = 1;
}
/**
* Constructs a haralick detector.
*
* #param haralickDist Integer for haralick distribution
*/
public Haralick(int haralickDist) {
this.haralickDist = haralickDist;
}
/**
* Defines the capability of the algorithm.
*
* #see PlugInFilter
* #see #supports()
*/
#Override
public EnumSet<Supports> supports() {
EnumSet set = EnumSet.of(
Supports.NoChanges,
Supports.DOES_8C,
Supports.DOES_8G,
Supports.DOES_RGB);
return set;
}
/**
* Starts the haralick detection.
*
* #param ip ImageProcessor of the source image
*/
#Override
public void run(ImageProcessor ip) {
if (!ByteProcessor.class.isAssignableFrom(ip.getClass())) {
ip = ip.convertToByte(true);
}
firePropertyChange(Progress.START);
process((ByteProcessor) ip);
addData(features);
firePropertyChange(Progress.END);
}
/**
* Returns information about the getFeature
*/
#Override
public String getDescription() {
StringBuilder sb = new StringBuilder();
sb.append("Haralick features: ");
sb.append("Angular 2nd moment, ");
sb.append("Contrast, ");
sb.append("Correlation, ");
sb.append("variance, ");
sb.append("Inverse Difference Moment, ");
sb.append("Sum Average, ");
sb.append("Sum Variance, ");
sb.append("Sum Entropy, ");
sb.append("Entropy, ");
sb.append("Difference Variance, ");
sb.append("Difference Entropy, ");
sb.append("Information Measures of Correlation, ");
sb.append("Information Measures of Correlation, ");
sb.append("Maximum Correlation COefficient");
return sb.toString();
}
private void process(ByteProcessor image) {
features = new double[14];
firePropertyChange(new Progress(1, "creating coocurrence matrix"));
Coocurrence coocurrence = new Coocurrence(image, NUM_GRAY_VALUES, this.haralickDist);
double[][] cooccurrenceMatrix = coocurrence.getCooccurrenceMatrix();
double meanGrayValue = coocurrence.getMeanGrayValue();
firePropertyChange(new Progress(25, "normalizing"));
normalize(cooccurrenceMatrix, coocurrence.getCooccurenceSums());
firePropertyChange(new Progress(50, "computing statistics"));
calculateStatistics(cooccurrenceMatrix);
firePropertyChange(new Progress(75, "computing features"));
double[][] p = cooccurrenceMatrix;
double[][] Q = new double[NUM_GRAY_VALUES][NUM_GRAY_VALUES];
for (int i = 0; i < NUM_GRAY_VALUES; i++) {
double sum_j_p_x_minus_y = 0;
for (int j = 0; j < NUM_GRAY_VALUES; j++) {
double p_ij = p[i][j];
sum_j_p_x_minus_y += j * p_x_minus_y[j];
features[0] += p_ij * p_ij;
features[2] += i * j * p_ij - mu_x * mu_y;
features[3] += (i - meanGrayValue) * (i - meanGrayValue) * p_ij;
features[4] += p_ij / (1 + (i - j) * (i - j));
features[8] += p_ij * log(p_ij);
// feature 13
if (p_ij != 0 && p_x[i] != 0) { // would result in 0
for (int k = 0; k < NUM_GRAY_VALUES; k++) {
if (p_y[k] != 0 && p[j][k] != 0) { // would result in NaN
Q[i][j] += (p_ij * p[j][k]) / (p_x[i] * p_y[k]);
}
}
}
}
features[1] += i * i * p_x_minus_y[i];
features[9] += (i - sum_j_p_x_minus_y) * (i - sum_j_p_x_minus_y) * p_x_minus_y[i];
features[10] += p_x_minus_y[i] * log(p_x_minus_y[i]);
}
// feature 13: Max Correlation Coefficient
double[] realEigenvaluesOfQ = new Matrix(Q).eig().getRealEigenvalues();
Arrays2.abs(realEigenvaluesOfQ);
Arrays.sort(realEigenvaluesOfQ);
features[13] = Math.sqrt(realEigenvaluesOfQ[realEigenvaluesOfQ.length - 2]);
features[2] /= Math.sqrt(var_x * var_y);
features[8] *= -1;
features[10] *= -1;
double maxhxhy = Math.max(hx, hy);
if (Math.signum(maxhxhy) == 0) {
features[11] = 0;
} else {
features[11] = (features[8] - hxy1) / maxhxhy;
}
features[12] = Math.sqrt(1 - Math.exp(-2 * (hxy2 - features[8])));
for (int i = 0; i < 2 * NUM_GRAY_VALUES - 1; i++) {
features[5] += i * p_x_plus_y[i];
features[7] += p_x_plus_y[i] * log(p_x_plus_y[i]);
double sum_j_p_x_plus_y = 0;
for (int j = 0; j < 2 * NUM_GRAY_VALUES - 1; j++) {
sum_j_p_x_plus_y += j * p_x_plus_y[j];
}
features[6] += (i - sum_j_p_x_plus_y) * (i - sum_j_p_x_plus_y) * p_x_plus_y[i];
}
features[7] *= -1;
}
/**
* Calculates the statistical properties.
*/
private void calculateStatistics(double[][] cooccurrenceMatrix) {
// p_x, p_y, p_x+y, p_x-y
for (int i = 0; i < NUM_GRAY_VALUES; i++) {
for (int j = 0; j < NUM_GRAY_VALUES; j++) {
double p_ij = cooccurrenceMatrix[i][j];
p_x[i] += p_ij;
p_y[j] += p_ij;
p_x_plus_y[i + j] += p_ij;
p_x_minus_y[Math.abs(i - j)] += p_ij;
}
}
// mean and variance values
double[] meanVar;
meanVar = meanVar(p_x);
mu_x = meanVar[0];
var_x = meanVar[1];
meanVar = meanVar(p_y);
mu_y = meanVar[0];
var_y = meanVar[1];
for (int i = 0; i < NUM_GRAY_VALUES; i++) {
// hx and hy
hx += p_x[i] * log(p_x[i]);
hy += p_y[i] * log(p_y[i]);
// hxy1 and hxy2
for (int j = 0; j < NUM_GRAY_VALUES; j++) {
double p_ij = cooccurrenceMatrix[i][j];
hxy1 += p_ij * log(p_x[i] * p_y[j]);
hxy2 += p_x[i] * p_y[j] * log(p_x[i] * p_y[j]);
}
}
hx *= -1;
hy *= -1;
hxy1 *= -1;
hxy2 *= -1;
}
/**
* Compute mean and variance of the given array
*
* #param a inut values
* #return array{mean, variance}
*/
private double[] meanVar(double[] a) {
// VAR(X) = E(X^2) - E(X)^2
double ex = 0, ex2 = 0; // E(X), E(X^2)
for (int i = 0; i < NUM_GRAY_VALUES; i++) {
ex += a[i];
ex2 += a[i] * a[i];
}
ex /= a.length;
ex2 /= a.length;
double var = ex2 - ex * ex;
return new double[]{ex, var};
}
/**
* Returns the logarithm of the specified value.
*
* #param value the value for which the logarithm should be returned
* #return the logarithm of the specified value
*/
private double log(double value) {
double log = Math.log(value);
if (log == Double.NEGATIVE_INFINITY) {
log = 0;
}
return log;
}
private void normalize(double[][] A, double sum) {
for (int i = 0; i < A.length; i++) {
Arrays2.div(A[i], sum);
}
}
//<editor-fold defaultstate="collapsed" desc="getter/Setter">
/**
* Getter for haralick distributions
*
* #return haralick distributions
*/
public int getHaralickDist() {
return haralickDist;
}
/**
* Setter for haralick distributions
*
* #param haralickDist int for haralick distributions
*/
public void setHaralickDist(int haralickDist) {
this.haralickDist = haralickDist;
}
//</editor-fold>
}
//<editor-fold defaultstate="collapsed" desc="Coocurrence Matrix">
/**
* http://makseq.com/materials/lib/Articles-Books/Filters/Texture/Co-occurence/haralick73.pdf
*/
class Coocurrence {
/**
* The number of gray values for the textures
*/
private final int NUM_GRAY_VALUES;
/**
* The number of gray levels in an image
*/
private final int GRAY_RANGES = 256;
/**
* The scale for the gray values for conversion rgb to gray values.
*/
private final double GRAY_SCALE;
/**
* gray histogram of the image.
*/
private final double[] grayHistogram;
/**
* quantized gray values of each pixel of the image.
*/
private final byte[] grayValue;
/**
* mean gray value
*/
private double meanGrayValue = 0;
/**
* The cooccurrence matrix
*/
private final double[][] cooccurrenceMatrices;
/**
* The value for one increment in the gray/color histograms.
*/
private final int HARALICK_DIST;
private final ByteProcessor image;
public Coocurrence(ByteProcessor b, int numGrayValues, int haralickDist) {
this.NUM_GRAY_VALUES = numGrayValues;
this.image = b;
this.GRAY_SCALE = (double) GRAY_RANGES / (double) NUM_GRAY_VALUES;
this.cooccurrenceMatrices = new double[NUM_GRAY_VALUES][NUM_GRAY_VALUES];
this.grayValue = new byte[image.getPixelCount()];
this.grayHistogram = new double[GRAY_RANGES];
this.HARALICK_DIST = haralickDist;
calculate();
}
public double getMeanGrayValue() {
return this.meanGrayValue;
}
public double[][] getCooccurrenceMatrix() {
return this.cooccurrenceMatrices;
}
public double getCooccurenceSums() {
return image.getPixelCount() * 8;
}
private void calculate() {
calculateGreyValues();
final int imageWidth = image.getWidth();
final int imageHeight = image.getHeight();
final int d = HARALICK_DIST;
int i, j, pos;
// image is not empty per default
for (int y = 0; y < imageHeight; y++) {
for (int x = 0; x < imageWidth; x++) {
pos = imageWidth * y + x;
// horizontal neighbor: 0 degrees
i = x - d;
// j = y;
if (!(i < 0)) {
increment(grayValue[pos], grayValue[pos - d]);
}
// vertical neighbor: 90 degree
// i = x;
j = y - d;
if (!(j < 0)) {
increment(grayValue[pos], grayValue[pos - d * imageWidth]);
}
// 45 degree diagonal neigbor
i = x + d;
j = y - d;
if (i < imageWidth && !(j < 0)) {
increment(grayValue[pos], grayValue[pos + d - d * imageWidth]);
}
// 135 vertical neighbor
i = x - d;
j = y - d;
if (!(i < 0) && !(j < 0)) {
increment(grayValue[pos], grayValue[pos - d - d * imageWidth]);
}
}
}
meanGrayValue = Arrays2.sum(grayValue);
}
private void calculateGreyValues() {
int size = image.getPixelCount();
int gray;
for (int pos = 0; pos < size; pos++) {
gray = image.get(pos);
grayValue[pos] = (byte) (gray / GRAY_SCALE); // quantized for texture analysis
grayHistogram[gray]++;
}
Arrays2.div(grayHistogram, size);
}
/**
* Incremets the coocurrence matrix at the specified positions (g1,g2) and
* (g2,g1).
*
* #param g1 the gray value of the first pixel
* #param g2 the gray value of the second pixel
*/
private void increment(int g1, int g2) {
cooccurrenceMatrices[g1][g2]++;
cooccurrenceMatrices[g2][g1]++;
}
}
//</editor-fold>
Here you have the source.
Thanks in advance=)
I created a applet using threads. When i run it and change the size of the window I see a few copies of "Applet started" string. I wonder why is that and how to fix that?
When exactly does this strin starts?
here is my code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Random;
import javax.swing.JApplet;
public class app extends javax.swing.JApplet {
/**
*
*/
Random generator = new Random();
public int n = 15;
public int m = 15;
public int k = 200;
public int size = 25;
public kwadrat[][] watki;
public double p = 0.98;
public boolean sth = true ;
/**
* Function initializes threads by given data
* #exception NumberFormatException when there is no data from html code
*
*/
public void init(){
try{n = Integer.parseInt(getParameter("n"));}
catch( NumberFormatException e){
System.out.println("Nieprawidłowy parametr: n");
}
catch( NullPointerException e){}
try{m = Integer.parseInt(getParameter("m"));}
catch( NumberFormatException e){
System.out.println("Nieprawidłowy parametr: m");
}
catch( NullPointerException e){}
try{k = Integer.parseInt(getParameter("k"));}
catch( NumberFormatException e){
System.out.println("Nieprawidłowy parametr: k");
}
catch( NullPointerException e){}
try{ p = Double.parseDouble(getParameter("p"));}
catch( NumberFormatException e){
System.out.println("Nieprawidłowy parametr: k");
}
catch( NullPointerException e){}
watki = new kwadrat[n][m];
for (int i = 0 ; i < n ; ++i)
for (int j = 0 ; j < m ; ++j){
watki[i][j] = new kwadrat(10+i*size,
10+j*size,
i,
j,
size,
(int)(k*(generator.nextDouble()+0.5)),
new java.awt.Color(generator.nextInt(255),
generator.nextInt(255),
generator.nextInt(255)
)
);
}
}
/**
* start method start the threads
*/
public void start(){
for (int i = 0 ; i < n ; ++i)
for (int j = 0 ; j < m ; ++j){
Thread t;
t = new Thread( new MovingRunnable(watki[i][j]));
t.start();
}
}
/**
* Paint method is responsible for drawing the rectangles(threads)
*/
public void paint(Graphics g){
//super.paint(g);
//g.fillRect(0, 0, 1000, 1000);
repaint();
for (int i = 0 ; i < n ; ++i)
for (int j = 0 ; j < m ; ++j){
g.setColor(watki[i][j].kwadratColor);
g.fillRect(watki[i][j].x, watki[i][j].y, size, size);
}
}
/**
*
* #author Seba
* Class MovingRunnable implements Runnable includes rectangles as threads
* #param b it is object of kwadrat class
* #param run() main method of the class. Changes color of rectangles
* #exception InterruptedException when something is wrong with sleeping thread
*/
private class MovingRunnable implements Runnable{
private final kwadrat b;
private MovingRunnable(kwadrat b){this.b=b;}
public void run(){
for(;;){
if(generator.nextDouble()<p){
int c1 = 0,c2 = 0,c3 = 0;
if(b.nrx>0){
c1 += watki[b.nrx-1][b.nry].kwadratColor.getRed();
c2 += watki[b.nrx-1][b.nry].kwadratColor.getGreen();
c3 += watki[b.nrx-1][b.nry].kwadratColor.getBlue();
}
if(b.nrx<n-1) {
c1 += watki[b.nrx+1][b.nry].kwadratColor.getRed();
c2 += watki[b.nrx+1][b.nry].kwadratColor.getGreen();
c3 += watki[b.nrx+1][b.nry].kwadratColor.getBlue();
}
if(b.nry>0) {
c1 += watki[b.nrx][b.nry-1].kwadratColor.getRed();
c2 += watki[b.nrx][b.nry-1].kwadratColor.getGreen();
c3 += watki[b.nrx][b.nry-1].kwadratColor.getBlue();
}
if(b.nry<m-1) {
c1 += watki[b.nrx][b.nry+1].kwadratColor.getRed();
c2 += watki[b.nrx][b.nry+1].kwadratColor.getGreen();
c3 += watki[b.nrx][b.nry+1].kwadratColor.getBlue();
}
b.changeColor(new java.awt.Color(c1/4,c2/4,c3/4));
}
else
//b.changeColor(Color.GRAY);
b.changeColor(generator);
repaint();
try {
Thread.sleep(b.wait);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
/**
*
* #author Seba
* #param x position in x
* #param y position in y
* #param nrx x position in watki[][] array
* #param nry y position in watki[][] array
* #param wait time of sleeping thread
* #param size size of side
* #param kwadratColor - color of the ractangle
* #param kwadrat(int,int,int,int,int,int,Color) main constructor
* #param changeColor(Random) changing color by generating Random
* #param changeColor(Color) changing color to given color
*/
class kwadrat{
public int x;
public int y;
public int nrx;
public int nry;
public int wait;
public int size;
Color kwadratColor;
public kwadrat( int x, int y, int nrx, int nry, int size , int wait, Color kwadratColor){
this.x = x;
this.y = y;
this.nrx = nrx;
this.nry = nry;
this.size = size;
this.kwadratColor = kwadratColor;
this.wait = wait;
}
public void changeColor(Random gen){
kwadratColor = new java.awt.Color(gen.nextInt(255),
gen.nextInt(255),
gen.nextInt(255)
);
}
public void changeColor(Color x){
kwadratColor = x;
}
}
I have constructed this array: Organism cells[][]; I fill the array with ants and doodlebugs (both classes inherit Organism), and leave most of the spots null to represent empty spots. Then I attempt to move all of the ants and doodlebugs. To move them, I first find an empty space for a target, then change the targeted cell to the Organism that needs to move. After that, I kill (set to null) the Organism at the x/y of where the moved Organism was. So if I was moving cell[1][1] and cell[2][2] was my target, I would: set cell[2][2] = cell[1][1] and then set cell[1][1] = null.
My problem is, after doing this process a second time, the code no longer moves the organisms. Although all the organisms move the first time, I need this process to be repeatable.
How can i fix this? Thank you for your help.
There is a lot of code but I was asked to post the important parts. Sorry if it is quite lengthy, I tried to simplify it.
World Class:
public class World {
private final int HEIGHT = 20;
private final int WIDTH = 20;
private Organism cells[][]; // (0,0) is considered the upper left corner
public static Random generator = new Random(1000L); // Use of a Random generator lets us provide same
// sequence of "random" numbers. Consequently, the
// simulation will be identical each run, aiding debugging.
//public static Random generator = new Random(); // Once your program works properly, comment out the statement
// above, and uncomment this one. This will make your program run differently
// every time you run it.
/**
* #param x horizontal grid coordinate
* #param y vertical grid coordinate.
*
* #return If (x,y) are not legal coords, returns null. Else returns value of the that cell.
* This will eiher be an Organism or null.
*/
public Organism getCell(int y, int x){
if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT){
return null;
}
return cells[y][x];
}
/**
* #param x horizontal grid coordinate
* #param y vertical grid coordinate.
* #param org Organism to place in the world
*/
public void setCell(int x, int y, Organism org){
cells[y][x]=org;
}
/**
* #param x horizontal grid coordinate
* #param y vertical grid coordinate.
* #return Return false if cell at given coords is not empty, or if coordinates are
* "off the grid." Else return true.
*/
public boolean isEmptyCell(int y, int x){
// YOUR CODE HERE...
if(getCell(y,x) != null){
return false;
}
return true;
}
/**
* Construct a World.
* If you don't want repeatable simulations (i.e., you want each to be unique),
* remove the "seed" value from the Random() constructor.
* #param numAnts The number of Ants to place randomly in the grid.
* #param numDoodles The number of Doodlebuggs to place randomly in the grid.
*/
public World(int numAnts, int numDoodles){
int x=0, y=0, count1=0, count2=0;
cells = new Organism[getHEIGHT()][getWIDTH()];
// YOUR CODE HERE to randomly place ants and doodlebugs.
while(count1<numAnts){
y = myRand(getHEIGHT());
x = myRand(WIDTH);
if(isEmptyCell(y,x)){
cells[y][x] = new Ant(y,x,this);
count1++;
//System.out.println("MAKING ANT at x=" + x +" and y= " + y);
}
}
while(count2<numDoodles){
y = myRand(getHEIGHT());
x = myRand(WIDTH);
if(isEmptyCell(y,x)){
cells[y][x] = new Doodlebug(y,x,this);
count2++;
}
}
}
/**
* #param x
* #param y
* #param org
* #return Return true if a new organism was added to the World, else return false.
* If at least one of the adjacent cells to [x,y] is empty, randomly select one of the
* empty ones and place org there.
* [You might do this by first checking if there's at least one empty adjacent cell.
* If so, use a loop to successively randomly select an adjacent cell until you find
* an empty one, then place org there.]
*
* [Oh, and this might be a good place to use a "switch" statement to deal with the
* four possible directions N,S,E,W.]
*/
public boolean addAdjacent(int x, int y, Organism org) {
// YOUR CODE HERE....
System.out.println("World.addAdjacent() not yet implemented.\n");
return true; // MODIFY SO RETURNS TRUE ONLY WHEN APPROPRIATE
}
/**
* Move all the ants.
*/
public void moveAllAnts() {
clearAntFlags();
for(int y=0; y<cells.length; y++){
for(int x=0; x<cells[y].length;x++){
if (getCell(x,y) instanceof Ant){
//System.out.println("Ant found at: y=" + x + " and x="+ y +"\t\tmoved? " + getCell(x,y).hasMoved);
getCell(x,y).move();
}
}
}
}
/**
* Move all the doodlebugs.
*/
public void moveAllDoodles() {
clearDoodleFlags();
for(int y=0; y<cells.length; y++){
for(int x=0; x<cells[y].length;x++){
if (getCell(x,y) instanceof Doodlebug){
//System.out.println("Doodle found at: y=" + x + " and x="+ y);
getCell(x,y).move();
}
}
}
}
public static void main(String[] args) {
World w;
w= new World(10,10);
System.out.println("A thinly populated world:\n"+w);
w.moveAllAnts();
w.moveAllDoodles();
System.out.println("A thinly populated world:\n"+w);
}
public int getHEIGHT() {
return HEIGHT;
}
public int getWIDTH() {
return WIDTH;
}
/**
* #param x,y takes the location of the ant and attempts to find an adjacent empty cell.
* #return Return a point if an adjacent cell is empty, otherwise return null.
*/
public Point getAdjaEmpty(int y, int x){
Point p = new Point(0,0);
boolean up = false, down = false, left = false, right = false;
int numTrue = 0;
if(isEmptyCell(y-1,x) && y-1>=0){ // can go left
left = true;
numTrue++;
}
if(isEmptyCell(y+1,x) && y+1<cells.length){ // can go right
right = true;
numTrue++;
}
if(isEmptyCell(y,x-1) && x-1>=0){ // can go up
up = true;
numTrue++;
}
if(isEmptyCell(y,x+1) && x+1<cells[0].length){ // can go down
down = true;
numTrue++;
}
if(numTrue >0){
if(numTrue==1){
if(left){
p.x = x;
p.y= y-1;
}else if(right){
p.x = x;
p.y= y+1;
}else if(up){
p.x = x-1;
p.y= y-1;
}else if(down){
p.x = x+1;
p.y= y;
}else{
System.err.println("Error in adjacEmpty function!");
}
}else if(numTrue>=2){
//make direction random
int dir = 0;
while(true){ //looks for a random spot that is empty and accessible
dir = generator.nextInt(4);
if(left && dir == 0){
p.x = x;
p.y= y-1;
//System.out.println("left");
break;
}else if(right && dir == 1){
p.x = x;
p.y= y+1;
//System.out.println("right");
break;
}else if(up && dir == 2){
p.x = x-1;
p.y= y;
//System.out.println("up");
break;
}else if(down && dir == 3){
p.x = x+1;
p.y= y;
//System.out.println("down");
break;
}
}
}
}else{
return null;
}
return p;
}
/* Moves the Organism to the random location given by getAdjaEmpty
* Also kills the old organism.
*
*/
public void killAndMove(int y, int x) {
Point p = getAdjaEmpty(y,x);
if(cells[y][x] != null){
setCell(p.x,p.y, getCell(y,x));
cells[y][x].kill();
}
}
}
Organism Class:
abstract public class Organism {
protected int locX, locY; // Coords of organism in its World.
protected boolean hasMoved; // Movement flag: true if has already moved this turn [Can you see why this is needed?]
abstract public void move(); // Move the critter to an adjacent space
protected World myMap; // Need this so each organism has access to its World.
/**
* As this is an abstract class, this constructor is invoked via super() by its
* subclasses. Takes care of initializing the fields they inherit from this class.
* #param x
* #param y
* #param m
*/
public Organism(int x, int y, World m) {
// Initialize instance variables, including
myMap = m;
locX = x;
locY = y;
// YOUR CODE HERE! What other instance variables?
}
/**
* Clear the move flag.
*/
public void clearMoveFlag() {
hasMoved = false;
}
/**
* Remove the organism from the world.
*/
public void kill() {
myMap.setCell(locY, locX, null);
}
/**
* Choose a random direction. If that cell is empty, move there.
* Make sure to set the movement flag so there is no possibility of moving the
* same organism again this turn.
* #see clearMoveFlag
*/
public void moveToEmpty() {
// Remember to avoid moving a critter that has already moved this turn....
// If you want a random number to choose a direction, try
// int dir = World.myRand(4);
// to generate an integer 0-3.
// YOUR CODE HERE!
if(!hasMoved){
myMap.killAndMove(locX, locY);
//System.out.println("LocX = " +locX + " and locY = " + locY);
hasMoved = true;
}
}
/**
* Set the location of the organism to the given coordinates.
* #param x
* #param y
*/
public void setLoc(int x, int y){
locX = x;
locY = y;
}
/**
* #return Return a single character representing the organism. To be
* used in constructing the printed representation of a World.
*/
public abstract String singleCharRepresenting();
}
My task is to create an OpenGL Java program which will load a dataset, and then display an orthogonal slice of said data on the X, Y and Z axis. I'm new to OpenGL and I've been having trouble with plotting the data. The class to load the dataset has been provided for me:
public class VolumetricDataSet {
private final int[] dimensions;
private int maxValue;
private int minValue;
private final int[][][] volumeData;
/**
* Construct a new dataset from a File.
*
* #param in
* the file to read the data from.
* #param xSize
* the maximal x dimension to use.
* #param ySize
* the maximal y dimension to use.
* #param zSize
* the maximal z dimension to use.
* #throws IOException
* if the underlying reader encounters an error.
* #throws FileNotFoundException
* if the file cannot be found.
*/
public VolumetricDataSet(final File in, final int xSize, final int ySize,
final int zSize) throws IOException, FileNotFoundException {
this(new FileInputStream(in), xSize, ySize, zSize);
}
/**
* Construct a new dataset.
*
* #param in
* the stream to read the data from.
* #param xSize
* the maximal x dimension to use.
* #param ySize
* the maximal y dimension to use.
* #param zSize
* the maximal z dimension to use.
* #throws IOException
* if the underlying reader encounters an error.
*/
public VolumetricDataSet(final InputStream in, final int xSize,
final int ySize, final int zSize) throws IOException {
int value = 0, xCur = 0, yCur = 0, zCur = 0;
volumeData = new int[xSize][ySize][zSize];
while ((value = in.read()) != -1) {
volumeData[xCur][yCur][zCur] = value;
if (value > maxValue)
maxValue = value;
if (value < minValue)
minValue = value;
if (++xCur == xSize) {
xCur = 0;
if (++yCur == ySize) {
yCur = 0;
zCur++;
}
}
}
dimensions = new int[] { xSize, ySize, zSize };
}
/**
* Retrieve the length of the x y z dimensions of the data set. 3 element array
*
* #return the dimensions.
*/
public int[] getDimensions()
{
return dimensions;
}
/**
* #return the maximal value
*/
public int getMaxValue()
{
return maxValue;
}
/**
* #return the minimal value.
*/
public int getMinValue()
{
return minValue;
}
/**
* #return the entire data set as a 3-D array. x is the 1st dimension, y the
* 2nd and z the 3rd.
*/
public int[][][] getVolumeData()
{
return volumeData;
}
}
My code to display the data:
VolumetricDataSet ds = new VolumetricDataSet(new File("C:\\Users\\Me\\Desktop\\Work\\Comp Graphics\\marschnerlobb.raw.gz"), 41, 41, 41);
int[][][] volumeData = ds.getVolumeData();
int[] dimensions = ds.getDimensions();
for(int i = 0; i < dimensions[0]; i++)
{
for(int j = 0; j < dimensions[1]; j++)
{
if(volumeData[i][j][0] < 1)
{
gl.glColor3f(0.0f,0.0f,0.0f);
gl.glPointSize(10);
gl.glBegin(GL.GL_POINTS);
gl.glVertex2i(i, j);
}
else if(volumeData[i][j][0] < 40)
{
gl.glColor3f(0.0f,0.0f,0.1f);
gl.glPointSize(10);
gl.glBegin(GL.GL_POINTS);
gl.glVertex2i(i, j);
}
else if(volumeData[i][j][0] < 80)
{
gl.glColor3f(0.0f,0.0f,0.2f);
gl.glPointSize(10);
gl.glBegin(GL.GL_POINTS);
gl.glVertex2i(i, j);
}
else if(volumeData[i][j][0] < 120)
{
gl.glColor3f(0.0f,0.0f,0.3f);
gl.glPointSize(10);
gl.glBegin(GL.GL_POINTS);
gl.glVertex2i(i, j);
}
else if(volumeData[i][j][0] < 160)
{
gl.glColor3f(0.0f,0.0f,0.4f);
gl.glPointSize(10);
gl.glBegin(GL.GL_POINTS);
gl.glVertex2i(i, j);
}
else if(volumeData[i][j][0] < 200)
{
gl.glColor3f(0.0f,0.0f,0.5f);
gl.glPointSize(10);
gl.glBegin(GL.GL_POINTS);
gl.glVertex2i(i, j);
}
else if(volumeData[i][j][0] < 240)
{
gl.glColor3f(0.0f,0.0f,0.6f);
gl.glPointSize(10);
gl.glBegin(GL.GL_POINTS);
gl.glVertex2i(i, j);
}
else if(volumeData[i][j][0] < 280)
{
gl.glColor3f(0.0f,0.0f,0.7f);
gl.glPointSize(10);
gl.glBegin(GL.GL_POINTS);
gl.glVertex2i(i, j);
}
}
}
marschnerlobb.raw.gz is the dataset that I am currently using to test my program which can be found at http://www.volvis.org/
When I run the program at first I thought it was correct as it looked like it may be a a slice from the dataset I used (which resembles a square). But when I tried it with a different dataset (a skull) the result being displayed was still a square image.