use of org.bytedeco.opencv.opencv_core.Mat in project qupath by qupath.
the class OpenCVTools method watershedIntensitySplit.
/**
* Apply a watershed transform to refine a binary image, guided either by a distance transform or a supplied intensity image.
*
* @param matBinary thresholded, 8-bit unsigned integer binary image
* @param matWatershedIntensities optional intensity image for applying watershed transform; if not set, distance transform of binary will be used
* @param threshold
* @param maximaRadius
*/
public static void watershedIntensitySplit(Mat matBinary, Mat matWatershedIntensities, double threshold, int maximaRadius) {
// Separate by intensity using the watershed transform
// Find local maxima
Mat matTemp = new Mat();
Mat strel = getCircularStructuringElement(maximaRadius);
opencv_imgproc.dilate(matWatershedIntensities, matTemp, strel);
opencv_core.compare(matWatershedIntensities, matTemp, matTemp, opencv_core.CMP_EQ);
opencv_imgproc.dilate(matTemp, matTemp, getCircularStructuringElement(2));
Mat matWatershedSeedsBinary = matTemp;
// Remove everything outside the thresholded region
opencv_core.min(matWatershedSeedsBinary, matBinary, matWatershedSeedsBinary);
// Create labels for watershed
Mat matLabels = new Mat(matWatershedIntensities.size(), opencv_core.CV_32F, Scalar.ZERO);
labelImage(matWatershedSeedsBinary, matLabels, opencv_imgproc.RETR_CCOMP);
// Do watershed
// 8-connectivity is essential for the watershed lines to be preserved - otherwise OpenCV's findContours could not be used
ProcessingCV.doWatershed(matWatershedIntensities, matLabels, threshold, true);
// Update the binary image to remove the watershed lines
opencv_core.multiply(matBinary, matLabels, matBinary, 1, matBinary.type());
}
use of org.bytedeco.opencv.opencv_core.Mat in project qupath by qupath.
the class OpenCVTools method findRegionalMaxima.
/**
* Get the regional maxima within a Mat, providing the output as a labeled image.
* @param mat image containing maxima; must be 2D and single-channel
* @return
* @implNote the labels are not guaranteed to be consecutive; the behavior of this function may change in a future release.
*/
public static Mat findRegionalMaxima(Mat mat) {
checkSingleChannel(mat);
int connectivity = 8;
// Apply 3x3 maximum filter & check equality
var matMax = new Mat();
var kernel = Mat.ones(3, 3, opencv_core.CV_32FC1).asMat();
opencv_imgproc.dilate(mat, matMax, kernel);
kernel.close();
matMax.put(opencv_core.equals(mat, matMax));
// Find connected components
var matLabels = label(matMax, connectivity);
// Calculate stats for labels
int nLabels = (int) Math.ceil(maximum(matLabels));
MaxLabelStat[] stats = updateMaxLabelStats(mat, matLabels, nLabels, connectivity);
// If boundaries labels are >= inner labels, they can't correspond to regional max - so remove them
var nonMaxima = Arrays.stream(stats).filter(s -> s.maxBoundary >= s.maxInside).map(s -> s.label).collect(Collectors.toSet());
if (!nonMaxima.isEmpty()) {
// TODO: Make this more efficient...
for (var nonMax : nonMaxima) replaceValues(matLabels, nonMax, 0);
}
return matLabels;
}
use of org.bytedeco.opencv.opencv_core.Mat in project qupath by qupath.
the class OpenCVTools method addNoise.
/**
* Add Gaussian noise with specified mean and standard deviation to all channels of a Mat.
* This is similar to {@link opencv_core#randn(Mat, Mat, Mat)}, but supports any number of channels.
* @param mat image to which noise should be added
* @param mean noise mean
* @param stdDev noise standard deviation
*/
public static void addNoise(Mat mat, double mean, double stdDev) {
if (!Double.isFinite(mean) || !Double.isFinite(stdDev)) {
throw new IllegalArgumentException("Noise mean and standard deviation must be finite (specified " + mean + " and " + stdDev + ")");
}
if (stdDev < 0) {
throw new IllegalArgumentException("Noise standard deviation must be >= 0, but specified value is " + stdDev);
}
var matMean = new Mat(1, 1, opencv_core.CV_32FC1, Scalar.all(mean));
var matStdDev = new Mat(1, 1, opencv_core.CV_32FC1, Scalar.all(stdDev));
int nChannels = mat.channels();
if (nChannels == 1)
opencv_core.randn(mat, matMean, matStdDev);
else
OpenCVTools.applyToChannels(mat, m -> opencv_core.randn(m, matMean, matStdDev));
matMean.close();
matStdDev.close();
}
use of org.bytedeco.opencv.opencv_core.Mat in project qupath by qupath.
the class OpenCVTools method scalarMatWithType.
/**
* Create a 1x1 Mat with a specific value, with 1 or more channels.
* If necessary, clipping or rounding is applied.
*
* @param value the value to include in the Mat
* @param type type of the image; this may contain additional channels if required.
* @return a Mat with one pixel containing the closest value supported by the type
*/
public static Mat scalarMatWithType(double value, int type) {
if (opencv_core.CV_MAT_CN(type) <= 4)
return new Mat(1, 1, type, Scalar.all(value));
var mat = new Mat(1, 1, type);
fill(mat, value);
return mat;
}
use of org.bytedeco.opencv.opencv_core.Mat in project qupath by qupath.
the class OpenCVTools method extractPixels.
/**
* Extract pixels as a double array.
* @param mat
* @param pixels
* @return
*/
public static double[] extractPixels(Mat mat, double[] pixels) {
if (pixels == null)
pixels = new double[(int) totalPixels(mat)];
Mat mat2 = null;
if (mat.depth() != opencv_core.CV_64F) {
mat2 = new Mat();
mat.convertTo(mat2, opencv_core.CV_64F);
ensureContinuous(mat2, true);
} else
mat2 = ensureContinuous(mat, false);
DoubleIndexer idx = mat2.createIndexer();
idx.get(0L, pixels);
idx.release();
if (mat2 != mat)
mat2.close();
// assert mat.total() == pixels.length;
return pixels;
}
Aggregations