use of qupath.lib.objects.classes.PathClass in project qupath by qupath.
the class DelaunayTriangulation method updateNodeMap.
void updateNodeMap(Subdiv2D subdiv, final double pixelWidth, final double pixelHeight) {
if (subdiv == null)
return;
int[] firstEdgeArray = new int[1];
// double distanceThreshold = 0;
boolean ignoreDistance = Double.isNaN(distanceThreshold) || Double.isInfinite(distanceThreshold) || distanceThreshold <= 0;
DelaunayNodeFactory factory = new DelaunayNodeFactory(pixelWidth, pixelHeight);
nodeMap = new HashMap<>(vertexMap.size(), 1f);
for (Entry<Integer, PathObject> entry : vertexMap.entrySet()) {
int v = entry.getKey();
PathObject pathObject = entry.getValue();
PathClass pathClass = pathObject.getPathClass() == null ? null : pathObject.getPathClass().getBaseClass();
// // TODO: CHECK INTENSITY DIFFERENT THRESHOLD
// String measurementName = "Nucleus: DAB OD mean";
// double measurementDiffThreshold = 0.1;
// double od = pathObject.getMeasurementList().getMeasurementValue(measurementName);
subdiv.getVertex(v, firstEdgeArray);
int firstEdge = firstEdgeArray[0];
int edge = firstEdge;
DelaunayNode node = factory.getNode(pathObject);
while (true) {
int edgeDest = subdiv.edgeDst(edge);
PathObject destination = vertexMap.get(edgeDest);
if (destination == null)
break;
boolean distanceOK = ignoreDistance || distance(getROI(pathObject), getROI(destination)) < distanceThreshold;
boolean classOK = !limitByClass || pathClass == destination.getPathClass() || (destination.getPathClass() != null && destination.getPathClass().getBaseClass() == pathClass);
if (distanceOK && classOK) {
// Intensity test (works, but currently commented out)
// if (Math.abs(od - destination.getMeasurementList().getMeasurementValue(measurementName)) < measurementDiffThreshold)
DelaunayNode destinationNode = factory.getNode(destination);
node.addEdge(destinationNode);
destinationNode.addEdge(node);
}
// Unused code exploring how a similarity test could be included
// if (ignoreDistance || distance(pathObject.getROI(), destination.getROI()) < distanceThreshold) {
// MeasurementList m1 = pathObject.getMeasurementList();
// MeasurementList m2 = destination.getMeasurementList();
// double d2 = 0;
// for (String name : new String[]{"Nucleus: Area", "Nucleus: DAB OD mean", "Nucleus: Eccentricity"}) {
// double t1 = m1.getMeasurementValue(name);
// double t2 = m2.getMeasurementValue(name);
// double temp = ((t1 - t2) / (t1 + t2)) * 2;
// d2 += temp*temp;
// }
// if (d2 < 1)
// // System.out.println(d2);
// node.addEdge(factory.getNode(destination));
// }
edge = subdiv.getEdge(edge, Subdiv2D.NEXT_AROUND_ORG);
if (edge == firstEdge)
break;
}
Object previous = nodeMap.put(pathObject, node);
assert previous == null;
}
}
use of qupath.lib.objects.classes.PathClass in project qupath by qupath.
the class OpenCvClassifier method readExternal.
@SuppressWarnings("unchecked")
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
long version = in.readLong();
if (version < 1 || version > 2)
throw new IOException("Unsupported version!");
timestamp = in.readLong();
pathClasses = (List<PathClass>) in.readObject();
// Ensure we have correct, single entries
if (pathClasses != null) {
for (int i = 0; i < pathClasses.size(); i++) {
pathClasses.set(i, PathClassFactory.getSingletonPathClass(pathClasses.get(i)));
}
}
normScale = (double[]) in.readObject();
normOffset = (double[]) in.readObject();
measurements = (List<String>) in.readObject();
arrayTraining = (float[]) in.readObject();
arrayResponses = (int[]) in.readObject();
if (version == 2) {
String method = (String) in.readObject();
for (Normalization n : Normalization.values()) {
if (n.toString().equals(method)) {
normalization = n;
break;
}
}
// normalization = Normalization.valueOf((String)in.readObject());
}
if (arrayTraining != null && arrayResponses != null) {
createAndTrainClassifier();
}
}
use of qupath.lib.objects.classes.PathClass in project qupath by qupath.
the class OpenCvClassifier method setPredictedClass.
/**
* Default prediction method. Makes no attempt to populate results matrix or to provide probabilities.
* (Results matrix only given as a parameter in case it is needed)
*
* Subclasses may choose to override this method if they can do a better prediction, e.g. providing probabilities as well.
*
* Upon returning, it is assumed that the PathClass of the PathObject will be correct, but it is not assumed that the results matrix will
* have been updated.
*
* @param classifier
* @param pathClasses
* @param samples
* @param results
* @param pathObject
*/
protected void setPredictedClass(final T classifier, final List<PathClass> pathClasses, final Mat samples, final Mat results, final PathObject pathObject) {
float prediction = classifier.predict(samples);
PathClass pathClass = pathClasses.get((int) prediction);
pathObject.setPathClass(pathClass);
}
use of qupath.lib.objects.classes.PathClass in project qupath by qupath.
the class OpenCvClassifier method getDescription.
// @Override
// public int classifyPathObjects(Collection<PathObject> pathObjects) {
//
//
// int counter = 0;
// Mat samples = new Mat(1, measurements.size(), CvType.CV_32FC1);
//
// for (PathObject pathObject : pathObjects) {
// MeasurementList measurementList = pathObject.getMeasurementList();
// int idx = 0;
// for (String m : measurements) {
// double value = measurementList.getMeasurementValue(m);
// samples.put(0, idx, value);
// idx++;
// }
//
// float prediction = trees.predict(samples);
//
// // if (computeProbabilities) {
// // double prediction = svm.svm_predict_probability(model, nodes, probabilities);
// // int index = (int)prediction;
// // pathObject.setPathClass(pathClasses.get(index), probabilities[index]);
// // } else {
// // double prediction = svm.svm_predict(model, nodes);
// pathObject.setPathClass(pathClasses.get((int)prediction));
// // }
// counter++;
// }
//
// return counter;
// }
@Override
public String getDescription() {
if (classifier == null)
return "No classifier set!";
StringBuilder sb = new StringBuilder();
String mainString = getName() + (!isValid() ? " (not trained)" : "");
;
sb.append("Classifier:\t").append(mainString).append("\n\n");
sb.append("Classes:\t[");
Iterator<PathClass> iterClasses = getPathClasses().iterator();
while (iterClasses.hasNext()) {
sb.append(iterClasses.next());
if (iterClasses.hasNext())
sb.append(", ");
else
sb.append("]\n\n");
}
sb.append("Normalization:\t").append(normalization).append("\n\n");
if (this instanceof Parameterizable) {
ParameterList params = ((Parameterizable) this).getParameterList();
String paramString = ParameterList.getParameterListJSON(params, "\n ");
sb.append("Main parameters:\n ").append(paramString);
sb.append("\n\n");
}
List<String> measurements = getRequiredMeasurements();
sb.append("Required measurements (").append(measurements.size()).append("):\n");
Iterator<String> iter = getRequiredMeasurements().iterator();
while (iter.hasNext()) {
sb.append(" ");
sb.append(iter.next());
sb.append("\n");
}
return sb.toString();
// return getName() + (!isValid() ? " (not trained)" : "");
}
use of qupath.lib.objects.classes.PathClass in project qupath by qupath.
the class QuPathGUI method setProject.
/**
* Set the active project, triggering any necessary GUI updates.
*
* @param project
*/
public void setProject(final Project<BufferedImage> project) {
var currentProject = this.projectProperty.get();
if (currentProject == project)
return;
// Ensure we save the current project
if (currentProject != null) {
try {
currentProject.syncChanges();
} catch (IOException e) {
logger.error("Error syncing project", e);
if (!Dialogs.showYesNoDialog("Project error", "A problem occurred while saving the last project - do you want to continue?"))
return;
}
}
// Check if we want to save the current image; we could still veto the project change at this point
for (var viewer : getViewers()) {
if (viewer == null || !viewer.hasServer())
continue;
var imageData = viewer.getImageData();
if (imageData != null) {
// if (entry != null) {
if (!checkSaveChanges(imageData))
return;
viewer.setImageData(null);
// } else
// ProjectImportImagesCommand.addSingleImageToProject(project, imageData.getServer(), null);
}
}
// Confirm the URIs for the new project
if (project != null) {
try {
// Show URI manager dialog if we have any missing URIs
if (!ProjectCommands.promptToCheckURIs(project, true))
return;
} catch (IOException e) {
Dialogs.showErrorMessage("Update URIs", e);
return;
}
}
// Store in recent list, if needed
URI uri = project == null ? null : project.getURI();
if (uri != null) {
ObservableList<URI> list = PathPrefs.getRecentProjectList();
if (list.contains(uri)) {
if (!uri.equals(list.get(0))) {
list.remove(uri);
list.add(0, uri);
}
} else
list.add(0, uri);
}
this.projectProperty.set(project);
if (!this.projectBrowser.setProject(project)) {
this.projectProperty.set(null);
this.projectBrowser.setProject(null);
}
// Update the PathClass list, if necessary
if (project != null) {
List<PathClass> pathClasses = project.getPathClasses();
if (pathClasses.isEmpty()) {
// Update the project according to the specified PathClasses
project.setPathClasses(getAvailablePathClasses());
} else {
// Update the available classes
if (!pathClasses.contains(PathClassFactory.getPathClassUnclassified())) {
pathClasses = new ArrayList<>(pathClasses);
pathClasses.add(0, PathClassFactory.getPathClassUnclassified());
}
getAvailablePathClasses().setAll(pathClasses);
}
}
// Ensure we have the required directories
// getProjectClassifierDirectory(true);
// getProjectScriptsDirectory(true);
logger.info("Project set to {}", project);
}
Aggregations