@Override @SuppressWarnings("unchecked") public void perform(InputSocket<?>[] inputs, OutputSocket<?>[] outputs, Optional<?> data) { final Mat input = ((InputSocket<Mat>) inputs[0]).getValue().get(); final Mat tmp = ((Optional<Mat>) data).get(); final boolean externalOnly = ((InputSocket<Boolean>) inputs[1]).getValue().get(); if (input.empty()) { return; } // findContours modifies its input, so we pass it a temporary copy of the input image input.copyTo(tmp); // OpenCV has a few different things it can return from findContours, but for now we only use // EXTERNAL and LIST. // The other ones involve hierarchies of contours, which might be useful in some situations, but // probably only // when processing the contours manually in code (so, not in a graphical pipeline). MatVector contours = new MatVector(); findContours( tmp, contours, externalOnly ? CV_RETR_EXTERNAL : CV_RETR_LIST, CV_CHAIN_APPROX_TC89_KCOS); final OutputSocket<ContoursReport> contoursSocket = (OutputSocket<ContoursReport>) outputs[0]; contoursSocket.setValue(new ContoursReport(contours, input.rows(), input.cols())); }