Vectors in one plot in ImageJ (Java) - java

I write a plugin in ImageJ, and I need some idea.
I have a plugin which generate plots for every image in a stack. So if I have 4 image in a stack, it will generate 4 plot from a vector.
But I need to be one plot with 4 curve. Please help me. `
This is the code.
public void run(String arg){
openImage();
if (cancel==false){
options();
}
if (cancel==false){
for (int k=0;k<imp.getStackSize();k++){
imp.setSlice(k+1);
generateESFArray("ESF Plot",imp,roi);
generateLSFArray("LSF Plot",ESFArray);
calculateMax();
ESFArrayF=alignArray(ESFArray);
if (cancel==false){
LSFArrayF=alignArray(LSFArray);
}
if (cancel==false){
ESFVector=averageVector(ESFArrayF);
}
if (cancel==false){
LSFVector=averageVector(LSFArrayF);
int aura = (LSFVector.length * 2);
LSFDVector = new double [aura];
int j = 0;
int aura2 = (LSFVector.length);
for(i=0;i<(LSFDVector.length-3); i++){
if(i % 2 == 0) {
LSFDVector[i]= LSFVector[j];
j=j+1;
}else {
LSFDVector[i]= ((0.375*LSFVector[(j-1)]) + (0.75*LSFVector[(j)]) - (0.125*LSFVector[(j+1)]));
}
}
LSFDVector[i] = ((LSFVector[j-1] + LSFVector[j])*0.5);
LSFDVector[i+1] = LSFVector[j];
LSFDVector[i+2] = LSFVector[j];
int indexMax = 0;
double valorMax = LSFDVector[0];
for(int i=0;i<LSFDVector.length;i++){
if(valorMax < LSFDVector[i]){
indexMax = i;
valorMax = LSFDVector[i];
}
}
i=indexMax;
LSFDVector[i-1]=((LSFDVector[i-2] + LSFDVector[i])*0.5);
MTFVector=fftConversion(LSFDVector, "MTF");
Max=obtenerMax();
SPPVector=fftConversion(Max,"SPP");
LSFArrayF=alignArray(LSFArray);
if (MTFButton.isSelected()){
generatePlot (MTFVector,"MTF");
...
}
void generatePlot(double[] Vector, String plot){
double[]xValues;
String ejeX="pixel";
String ejeY="";
String allTitle="";
ImageProcessor imgProc;
xValues=calculateXValues(Vector,plot);
//plot titles
if (plot=="ESF"){
ejeY="Grey Value";
...
allTitle=plot + "_" + title;
plotResult = new Plot(allTitle, ejeX, ejeY, xValues, Vector);
//plot limits
if (plot=="ESF"){
plotResult.setLimits(1,Vector.length,0,yMax);
}
plotResult.draw();
plotResult.show();
}
`

The ij.gui.Plot class has an addPoints method allowing you to add multiple data series to a plot. The Groovy script below illustrates its usage. Just paste the code into ImageJ's script editor, choose Language > Groovy and press Run to try it.
import ij.gui.Plot
plot = new Plot("Multiple Line Plot", "x values", "y values", (double[])[0,1,2,3,4], (double[])[0.1,0.3,0.5,0.6,0.7])
plot.addPoints((double[])[0,1,2,3,4], (double[])[0.2,0.15,0.1,0.05,0.05], Plot.LINE)
plot.setLimits(0, 4, 0, 1)
plot.draw()
plot.show()
For any further questions regarding the usage of the ImageJ API, you might get better help on the ImageJ forum.

Related

Java for loop not stopping. what is wrong with the code

It seems like the for loop in my code is not stopping after it iterated througt the counter. it seems to restart, checked with the print function and the length of the directory list seems to be recognized but then it restarts from 0 and so on. First time coding with java and in general i do not have much experience in coding, logic experience comes from visual coding and little bit of python. if somebody can help it would be great.
here is the code,
to run it you need will need processing (https://processing.org/download) and some images in the input folder. thougth this is an easy problem, thats why i still post it here.
I know its not pretty so pls dont hate on it
int dim = 1024;
PImage img;
String inDir;
import java.util.*;
import java.text.DecimalFormat;
String outDir;
String nameSpace;
String nameSpaceOut;
PGraphics pg;
void setup() {
size(1024, 1024);
inDir = "C:/Users/Fynn/Desktop/processing-3.5.4/Resizematte/data/Input 1/";
outDir = "C:/Users/Fynn/Desktop/processing-3.5.4/Resizematte/data/Output 3/";
nameSpace = "ImageToResize";
pg = createGraphics(dim, dim);
nameSpaceOut = "Resized";
}
void draw () {
background(0);
pg.beginDraw();
File dir = new File(inDir);
String[] filenames = dir.list();
for (int i = 0; i < filenames.length; i++) {
background(255, 255, 255);
String fName = inDir + filenames[i];
img = loadImage(fName);
if (img != null) {
float w = img.width;
float h = img.height;
float m = w;
float f = h;
if (h > w) { //change to < for crop > for matte
m = h;
f = w;
}
float factor = (dim/m);
if(h > w){
img.resize(int(f*factor), int(m*factor));
}
else {
img.resize(int(m*factor), int(f*factor));
}
image(img, width/2-img.width/2, height/2-img.height/2);
String outName1 = outDir + nameSpaceOut + "_" + i +".png";
save(outName1);
}
}
}
i try to format pictures which i want to use as a data set input for a GAN machine learnign algorithm.

Printing g.Drawstring on a new line when for loop is run?

I have been set an assignment and I have been working on this applet for days now, trying to figure out a solution myself but no amount of searching has brought up an answer which I can find to fit quite what I need.
The problem is I need to create a java applet which tell you how many words of a certain length there are. So if I type "Hi There" it will say:
1 word of length 2
1 word of length 5
I am using g.DrawString to output the result of the entered text. If I enter more than one word and all the words entered are the same length it will output one line with the correct information. If I enter two words of different lengths however it will still only output one line and totally ignore anything before the last word entered. I just can't seem to figure out how to get g.Drawstring to move down a line. Here is the code I have so far:
import java.util.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class assignmentneat extends Applet implements ActionListener {
String pr_name;
TextField pr_input;
public void init()
{
pr_input = new TextField(50);
add(pr_input);
pr_input.addActionListener(this);
}
public void start()
{
pr_name = " ";
}
public void actionPerformed(ActionEvent e)
{
int a = 0;
int b;
pr_name = e.getActionCommand();
String[] words = pr_name.split(" ");
for (String word : words)
if (a < word.length())
a = word.length();
int pr_count[] = new int[a+1];
for (String word : words) {
pr_count[word.length()]++; }
for (b = 0; b < pr_count.length; b++){
if (pr_count[b] > 0) {
pr_name = ("There are " + pr_count[b] + " words of length " + b);
repaint();
}
}
}
public void paint(Graphics g)
{
g.drawString(pr_name,100,100);
}
}
The whole program works perfectly when its just run inside something like DrJava, it just doesn't want to work when it's in applet form.
update
I should mention, I realise using a Jlabel etc would be easier, but I haven't been taught anything to do with this, I've only been studying java for a very very short time and I don't want to use anything I haven't been taught so far.
What you want to do is have List of Strings. Hopefully you have learned about Lists, you can use arrays but adding to them dynamically sucks.
Using a list you could do something like this in your last loop
public class assignment... {
private List<String> list = new ArrayList<>();
....
public void actionPerfomed(ActionEvent e) {
....
// instead of this
//for (b = 0; b < pr_count.length; b++){
//if (pr_count[b] > 0) {
//pr_name = ("There are " + pr_count[b] + " words of length " + b);
//repaint();
//}
// do this
for (b = 0; b < pr_count.length; b++){
if (pr_count[b] > 0) {
list.add("There are " + pr_count[b] + " words of length " + b);
}
}
repaint(); // repaint after all is added to the list.
}
}
In your paint method you could then loop through the list. What you need to do though, for each line, you need to update the y position since its moving to the next line. Since you can't use things you haven't learned, I won't suggest FontMetrics which lets you measure the height of letters. Instead just guess the height and increment the y for each line. Something like this
public void paint(Graphics g) {
int y = 20;
for (String s : list) {
g.drawString(s, 20, y);
y += 15; // 15 is just a guess. Play with it til you get it right
}
}

weka GUI and Java code give different results

I'm using weka java API to do a grid search in order to find the optimal parameters for MultilayerPerceptron. However, the RMSE (I'm doing regression here) given by my java code is different from that given by weka GUI. Here is the code:
public class ANN {
/**
* #param args
*/
public static void main(String[] args) throws Exception{
DataSource source = new DataSource("/home/yongfeng/ML/Project/choose_openning_price/holdout.arff");
Instances raw = source.getDataSet();
int trainSize = (int) Math.round(raw.numInstances()*0.666666666);
int testSize = raw.numInstances() - trainSize;
Instances train = new Instances(raw, 0, trainSize);
Instances test = new Instances(raw, trainSize, testSize);
train.setClassIndex(0);
test.setClassIndex(0);
final int sizeOfSearch = 15;
double[][] resultsArray = new double[sizeOfSearch][sizeOfSearch];
for (int i=0;i < sizeOfSearch;i++){
for (int j=0;j < sizeOfSearch;j++){
double m = i;
double k = j;
double learningRate = (m+1)/1000;
double momentum = (k+1)/100;
MultilayerPerceptron ann = new MultilayerPerceptron();
String options = String.format("-L %f -M %f -N 500 -V 0 -S 0 -E 20 -H a", learningRate, momentum);
ann.setOptions(weka.core.Utils.splitOptions(options));
ann.buildClassifier(train);
Evaluation eval = new Evaluation(train);
eval.evaluateModel(ann, test);
double error = eval.rootMeanSquaredError();
System.out.println("learningRate: " + learningRate + "\tMomentum: " + momentum + "\tError: " + error);
printOptions(ann.getOptions());
resultsArray[i][j] = error;
ann = null;
eval = null;
}
}
}
}
I even printed out the options in each iteration and they turned out to be the same as those in weka GUI. The attribute to be predicted is the first one, so setClassIndex(0); And used train-test set split to do the evaluation. Can anybody help? Many thanks!
Use weka.jar in weka installation folder in your java code.

libsvm classifying - at bad stage so far

Problem: I have certain set of data to be classified - Useful(1)/Useless(0). I will provide full set of data as input for training purpose of the classifier. and test with different data set.
For this, I am trying to convert my data to LIBSVM format. before doing anything, I thought of providing numeric input of one vector and check the result.
Input:
Training: 1 1 2 (the first 1 indicates useful Class in this vector followed by numeric input)
Testing: 1 1 2(I am not sure of input data format)
Output:
(0:0.9982708183417436)(1:0.0017291816582564153)(Actual:1.0 Prediction:0.0)
I dont have class 0 in training set, but it has probEstimated for class 0.
I am not really sure of how to convert my data to numeric vector input and fetch the data from the numeric test data set to equivalent Data as supplied. ANY HELP IN THIS REGARD IS HIGHLY APPRECIATED.
Planned tasks:
1. Load all the data to Hash tables and get the keys to be saved in data sets with respective classifier - USEFUL(1).
2. Supply the data set to the svmTrain and get the model.
3. Prepare test data set(Convert each word/phrase to respective numeric value saved training set, if found. Else, assign a new value).
4. Supply the test set and model to the SVM's EVALUATE method.
5. Get the resultant vectors from the USEFUL class and re-map to the data.
Code: used from different sources.
public class Datatosvmformat {
static double[][] train = new double[1000][3];
public static void main(String[] args) {
// TODO Auto-generated method stub
HashMap<String, Integer> dataSet = new HashMap<String, Integer>();
double[][] test = new double[10][3];
train[1][0] = 1;
train[1][1] = 1;
train[1][2] = 2;
svm_model model = svmTrain();
//Test Data Set
double[] test1 = new double[3];
test1[0] = 1;
test1[1] = 1;
test1[2] = 2;
evaluate(test1,model);
}
private static svm_model svmTrain() {
svm_problem prob = new svm_problem();
int dataCount = train.length;
prob.y = new double[dataCount];
prob.l = dataCount;
prob.x = new svm_node[dataCount][];
for (int i = 0; i <dataCount; i++){
double[] features = train[i];
//ystem.out.println("Features "+features[i]);
prob.x[i] = new svm_node[features.length-1];
for (int j = 1; j < features.length; j++){
svm_node node = new svm_node();
node.index = j;
node.value = features[j];
prob.x[i][j-1] = node;
}
prob.y[i] = features[0];
}
svm_parameter param = new svm_parameter();
param.probability = 1;
param.gamma = 0.5;
param.nu = 0.5;
param.C = 1;
param.svm_type = svm_parameter.C_SVC;
param.kernel_type = svm_parameter.LINEAR;
param.cache_size = 20000;
param.eps = 0.001;
svm_model model = svm.svm_train(prob, param);
return model;
}
public static double evaluate(double[] features, svm_model model)
{
svm_node[] nodes = new svm_node[features.length-1];
for (int i = 1; i < features.length; i++)
{
svm_node node = new svm_node();
node.index = i;
node.value = features[i];
nodes[i-1] = node;
}
int totalClasses = 2;
int[] labels = new int[totalClasses];
svm.svm_get_labels(model,labels);
double[] prob_estimates = new double[totalClasses];
double v = svm.svm_predict_probability(model, nodes, prob_estimates);
for (int i = 0; i < totalClasses; i++){
System.out.print("(" + labels[i] + ":" + prob_estimates[i] + ")");
}
System.out.println("(Actual:" + features[0] + " Prediction:" + v + ")");
return v;
}
}
I'm not completely sure, but the problem could be due to the fact that you need to mark positive examples with +1 and negative examples with -1.
Otherwise, the libsvm software could asssign an arbitraty class (e.g. 0) to the training vector 1 1 2, since it iterprets the first elem of the feature vector as a feature value (and not the label class).
So try to change the class label 1 in +1 for positive examples (and -1 for negative examples).
Usually, for data format for libsvm is the following:
<label> <index1>:<value1> <index2>:<value2>
where:
label is the class label (e.g. +1/-1)
indexN is the feature Id (i.e. the number that identified a certain feature)
valueN is the feature value (i.e. the value assigned to the specified feature: 0/1 for binary features or 0,1,2,... for categorical features)
An example of the data format accepted by the libsvm tool can be found at this page:
LIBSVM Data: Classification (Binary Class)
There are many datasets that you can explore in order to understand the data format accepted by the libsvm tool.

Collision Detection returning a value derived from the image filename

I'm currently in the process of building a small Asteroids style game which is intended for use by the kids at a local junior school. The aim is to help them with their times-tables.
A randomly generated question is displayed on-screen, (example: 6 * ? = 12), and a number of star images with numbers on them are floating around, waiting to be be shot at! You control a ship and fly around hunting the correct answer.
Bullets collide with the stars and a test needs to be performed to see if the user has shot the correct answer or not.
The star's filenames are simply "1.png", "2.png" etc, and I have a small function to return the first character of the filename, and convert it to an int:
public rightAnswer() {
String filename = "12.png"; //would be passed as parameters
int coefficient = 2; //
int answer = 24; //
char first = filename.charAt(0);
char second = filename.charAt(1);
int target;
if (second != '.') { //dealing only with 1 or 2-digit numbers
String both = String.valueOf(first) + String.valueOf(second);
target = Integer.parseInt(both);
}
else {
target = Character.digit(first, 10);
}
if (target * coefficient == answer) {
System.out.println("Answer is correct! (target = " + target + ")");
}
else {
System.out.println("Wrong! (target = " + target + ")");
}
}
While writing I got struck by a problem. I can't figure out how to retrieve the filename of the collided star to pass it to the above test function.
edit:
taking a shot at Enno Shioji's solution, I've come to this:
//star map
Map<ImageEntity, Integer> star_number = new HashMap<ImageEntity, Integer>();
//later, while loading the images into the game...
for (int n = 0; n < 10; n++) { // 10 loops
stars[n] = new ImageEntity(this);
String filename = (n+2) + ".png"; // 2- 12 range
stars[n].load(filename);
star_number.put(stars[n], n+2);
}
//then later again, run when collision is detected between a bullet and a star...
public boolean correctAnswer(ImageEntity star, int expectedAnswer) {
if (star_number.get(star) == expectedAnswer)
return true;
else return false;
}
Is this looking right?
I would not try to grab the filename. Instead, you should keep track of which star corresponds to which number, in a Map.
// Do this wherever you have easy access to the file name
Map<Star,Integer> star_number = new HashMap<Star,Integer>();
star_number.put(star1,1);
star_number.put(star2,2);
etc...
//Then later...
boolean collided(Star star, Integer expectedAnswer){
Integer answerGiven = star_number.get(star);
return expectedAnswer.equals(answerGiven);
}
or, you could also keep track by defining the Star object as such:
class Star{
Integer number;
StarImage image;
Star(StarImage image, Integer number){
this.number = number;
this.image = image;
}
// then later...
boolean collided(Star star, Integer expectedAnswer){
return star.number.equals(expectedAnswer);
}
Hope this helps. Good luck with your project :)

Categories