Skip to content

Instantly share code, notes, and snippets.

@JLLeitschuh
Last active May 19, 2016 20:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JLLeitschuh/7661e0a3081dc7fa353bae52efa8ff5a to your computer and use it in GitHub Desktop.
Save JLLeitschuh/7661e0a3081dc7fa353bae52efa8ff5a to your computer and use it in GitHub Desktop.
Large list of openCV operations converted into GRIP.
package edu.wpi.grip.core.operations;
import com.google.common.collect.ImmutableList;
import com.google.common.eventbus.EventBus;
import com.google.inject.Inject;
import edu.wpi.grip.core.OperationMetaData;
import edu.wpi.grip.core.events.OperationAddedEvent;
import edu.wpi.grip.core.operations.opencv.CVOperation;
import edu.wpi.grip.core.operations.opencv.enumeration.FlipCode;
import edu.wpi.grip.core.operations.templated.*;
import edu.wpi.grip.core.sockets.InputSocket;
import edu.wpi.grip.core.sockets.OutputSocket;
import edu.wpi.grip.core.sockets.SocketHint;
import edu.wpi.grip.core.sockets.SocketHints;
import edu.wpi.grip.generated.opencv_core.enumeration.BorderTypesEnum;
import edu.wpi.grip.generated.opencv_core.enumeration.CmpTypesEnum;
import edu.wpi.grip.generated.opencv_core.enumeration.LineTypesEnum;
import edu.wpi.grip.generated.opencv_imgproc.enumeration.*;
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_core.Mat;
import org.bytedeco.javacpp.opencv_core.Point;
import org.bytedeco.javacpp.opencv_core.Scalar;
import org.bytedeco.javacpp.opencv_core.Size;
import org.bytedeco.javacpp.opencv_imgproc;
/**
* A list of all of the raw opencv operations
*/
public class CVOperations {
private final EventBus eventBus;
private final ImmutableList<OperationMetaData> coreOperations;
private final ImmutableList<OperationMetaData> imgprocOperation;
@Inject
CVOperations(EventBus eventBus, InputSocket.Factory isf, OutputSocket.Factory osf) {
this.eventBus = eventBus;
this.coreOperations = ImmutableList.of(
new OperationMetaData(CVOperation.defaults("CV absdiff", "Calculate the per-element absolute difference of two images."),
() -> new MatTwoSourceOneDestinationOperation(isf, osf, opencv_core::absdiff)),
new OperationMetaData(CVOperation.defaults("CV add", "Calculate the per-pixel sum of two images."),
() -> new MatTwoSourceOneDestinationOperation(isf, osf, opencv_core::add)),
new OperationMetaData(CVOperation.defaults("CV addWeighted", "Calculate the weighted sum of two images."),
() -> new FiveSourceOneDestinationOperation<>(isf, osf,
(src1, alpha, src2, beta, gamma, dst) -> {
opencv_core.addWeighted(src1, alpha.doubleValue(), src2, beta.doubleValue(), gamma.doubleValue(), dst);
},
SocketHints.Inputs.createMatSocketHint("src1", false),
SocketHints.Inputs.createNumberSpinnerSocketHint("alpha", 0),
SocketHints.Inputs.createMatSocketHint("src2", false),
SocketHints.Inputs.createNumberSpinnerSocketHint("beta", 0),
SocketHints.Inputs.createNumberSpinnerSocketHint("gamma", 0),
SocketHints.Outputs.createMatSocketHint("dst"))),
new OperationMetaData(CVOperation.defaults("CV bitwise_and", "Calculate the per-element bitwise conjunction of two images."),
() -> new MatTwoSourceOneDestinationOperation(isf, osf, opencv_core::bitwise_and)),
new OperationMetaData(CVOperation.defaults("CV bitwise_not", "Calculate per-element bit-wise inversion of an image."),
() -> new OneSourceOneDestinationOperation<>(isf, osf, opencv_core::bitwise_not, Mat.class, Mat.class)),
new OperationMetaData(CVOperation.defaults("CV bitwise_or", "Calculate the per-element bit-wise disjunction of two images."),
() -> new MatTwoSourceOneDestinationOperation(isf, osf, opencv_core::bitwise_or)),
new OperationMetaData(CVOperation.defaults("CV bitwise_xor", "Calculate the per-element bit-wise \"exclusive or\" on two images."),
() -> new MatTwoSourceOneDestinationOperation(isf, osf, opencv_core::bitwise_xor)),
new OperationMetaData(CVOperation.defaults("CV compare", "Compare each pixel in two images using a given rule."),
() -> new ThreeSourceOneDestinationOperation<>(isf, osf,
(src1, src2, cmp, dst) -> {
opencv_core.compare(src1, src2, dst, cmp.value);
},
SocketHints.Inputs.createMatSocketHint("src1", false),
SocketHints.Inputs.createMatSocketHint("src2", false),
SocketHints.createEnumSocketHint("cmpop", CmpTypesEnum.CMP_EQ),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV divide", "Perform per-pixel division of two images."),
() -> new ThreeSourceOneDestinationOperation<>(isf, osf,
(src1, src2, scale, dst) -> {
opencv_core.divide(src1, src2, dst, scale.doubleValue(), -1);
},
SocketHints.Inputs.createMatSocketHint("src1", false),
SocketHints.Inputs.createMatSocketHint("src2", false),
SocketHints.Inputs.createNumberSpinnerSocketHint("scale", 1.0, -Double.MAX_VALUE, Double.MAX_VALUE),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV extractChannel", "Extract a single channel from a image."),
() -> new TwoSourceOneDestinationOperation<>(isf, osf,
(src1, coi, dst) -> {
opencv_core.extractChannel(src1, dst, coi.intValue());
},
SocketHints.Inputs.createMatSocketHint("src", false),
SocketHints.Inputs.createNumberSpinnerSocketHint("channel", 0, 0, Integer.MAX_VALUE),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV flip", "Flip image around vertical, horizontal, or both axes."),
() -> new TwoSourceOneDestinationOperation<>(isf, osf,
(src, flipCode, dst) -> {
opencv_core.flip(src, dst, flipCode.value);
},
SocketHints.Inputs.createMatSocketHint("src", false),
SocketHints.createEnumSocketHint("flipCode", FlipCode.Y_AXIS),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV max", "Calculate per-element maximum of two images."),
() -> new MatTwoSourceOneDestinationOperation(isf, osf, opencv_core::max)),
new OperationMetaData(CVOperation.defaults("CV min", "Calculate the per-element minimum of two images."),
() -> new MatTwoSourceOneDestinationOperation(isf, osf, opencv_core::min)),
new OperationMetaData(CVOperation.defaults("CV multiply", "Calculate the per-pixel scaled product of two images."),
() -> new ThreeSourceOneDestinationOperation<>(isf, osf,
(src1, src2, scale, dst) -> {
opencv_core.multiply(src1, src2, dst, scale.doubleValue(), -1);
},
SocketHints.Inputs.createMatSocketHint("src1", false),
SocketHints.Inputs.createMatSocketHint("src2", false),
SocketHints.Inputs.createNumberSpinnerSocketHint("scale", 1.0, Integer.MIN_VALUE, Integer.MAX_VALUE),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV scaleAdd", "Calculate the sum of two images where one image is multiplied by a scalar."),
() -> new ThreeSourceOneDestinationOperation<>(isf, osf,
(src1, alpha, src2, dst) -> {
opencv_core.scaleAdd(src1, alpha.doubleValue(), src2, dst);
},
SocketHints.Inputs.createMatSocketHint("src1", false),
SocketHints.Inputs.createNumberSpinnerSocketHint("scale", 1.0),
SocketHints.Inputs.createMatSocketHint("src2", false),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV subtract", "Calculate the per-pixel difference between two images."),
() -> new MatTwoSourceOneDestinationOperation(isf, osf, opencv_core::subtract)),
new OperationMetaData(CVOperation.defaults("CV transpose", "Calculate the transpose of an image."),
() -> new OneSourceOneDestinationOperation<>(isf, osf, opencv_core::transpose, Mat.class, Mat.class))
);
// For some reason the IntelliJ compiler complains unless I do this.
final SocketHint<AdaptiveThresholdTypesEnum> adaptiveThresholdType = SocketHints.createEnumSocketHint("adaptiveMethod", AdaptiveThresholdTypesEnum.ADAPTIVE_THRESH_MEAN_C);
this.imgprocOperation = ImmutableList.of(
new OperationMetaData(CVOperation.defaults("CV adaptiveThreshold", "Transforms a grayscale image to a binary image)."),
() -> new SixSourceOneDestinationOperation<>(isf, osf,
(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst) -> {
opencv_imgproc.adaptiveThreshold(src, dst, maxValue.doubleValue(), adaptiveMethod.value, thresholdType.value, blockSize.intValue(), C.doubleValue());
},
SocketHints.Inputs.createMatSocketHint("src", false),
SocketHints.Inputs.createNumberSpinnerSocketHint("maxValue", 0.0),
adaptiveThresholdType,
SocketHints.createEnumSocketHint("thresholdType", ThresholdTypesEnum.THRESH_BINARY),
SocketHints.Inputs.createNumberSpinnerSocketHint("blockSize", 0.0),
SocketHints.Inputs.createNumberSpinnerSocketHint("C", 0.0),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV applyColorMap", "Apply a MATLAB equivalent colormap to an image."),
() -> new TwoSourceOneDestinationOperation<>(isf, osf,
(src, colormap, dst) -> {
opencv_imgproc.applyColorMap(src, dst, colormap.value);
},
SocketHints.Inputs.createMatSocketHint("src", false),
SocketHints.createEnumSocketHint("colormap", ColormapTypesEnum.COLORMAP_AUTUMN),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV Canny", "Apply a \"canny edge detection\" algorithm to an image."),
() -> new FiveSourceOneDestinationOperation<>(isf, osf,
(image, threshold1, threshold2, apertureSize, L2gradient, edges) -> {
opencv_imgproc.Canny(image, edges, threshold1.doubleValue(), threshold2.doubleValue(), apertureSize.intValue(), L2gradient);
},
SocketHints.Inputs.createMatSocketHint("image", false),
SocketHints.Inputs.createNumberSpinnerSocketHint("threshold1", 0.0),
SocketHints.Inputs.createNumberSpinnerSocketHint("threshold2", 0.0),
SocketHints.Inputs.createNumberSpinnerSocketHint("apertureSize", 3),
SocketHints.Inputs.createCheckboxSocketHint("L2gradient", false),
SocketHints.Outputs.createMatSocketHint("edges")
)),
new OperationMetaData(CVOperation.defaults("CV cvtColor", "Convert an image from one color space to another."),
() -> new TwoSourceOneDestinationOperation<>(isf, osf,
(src, code, dst) -> {
opencv_imgproc.cvtColor(src, dst, code.value);
},
SocketHints.Inputs.createMatSocketHint("src", false),
SocketHints.createEnumSocketHint("code", ColorConversionCodesEnum.COLOR_BGR2BGRA),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV dilate", "Expands areas of higher values in an image."),
() -> new SixSourceOneDestinationOperation<>(isf, osf,
(src, kernel, anchor, iterations, borderType, borderValue, dst) -> {
opencv_imgproc.dilate(src, kernel, dst, anchor, iterations.intValue(), borderType.value, borderValue);
},
SocketHints.Inputs.createMatSocketHint("src", false),
SocketHints.Inputs.createMatSocketHint("kernel", true),
new SocketHint.Builder<>(Point.class).identifier("anchor").initialValueSupplier(Point::new).build(),
SocketHints.Inputs.createNumberSpinnerSocketHint("iterations", 1),
SocketHints.createEnumSocketHint("borderType", BorderTypesEnum.BORDER_CONSTANT),
new SocketHint.Builder<>(Scalar.class).identifier("borderValue").initialValueSupplier(opencv_imgproc::morphologyDefaultBorderValue).build(),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV GaussianBlur", "Apply a Gaussian blur to an image."),
() -> new FiveSourceOneDestinationOperation<>(isf, osf,
(src, ksize, sigmaX, sigmaY, borderType, dst) -> {
opencv_imgproc.GaussianBlur(src, dst, ksize, sigmaX.doubleValue(), sigmaY.doubleValue(), borderType.value);
},
SocketHints.Inputs.createMatSocketHint("src", true),
new SocketHint.Builder<>(Size.class).identifier("ksize").initialValueSupplier(() -> new Size(1, 1)).build(),
SocketHints.Inputs.createNumberSpinnerSocketHint("sigmaX", 0.0),
SocketHints.Inputs.createNumberSpinnerSocketHint("sigmaY", 0.0),
SocketHints.createEnumSocketHint("borderType", BorderTypesEnum.BORDER_DEFAULT),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV Laplacian", "Find edges by calculating the Laplacian for the given image."),
() -> new FiveSourceOneDestinationOperation<>(isf, osf,
(src, ksize, scale, delta, borderType, dst) -> {
opencv_imgproc.Laplacian(src, dst, 0, ksize.intValue(), scale.doubleValue(), delta.doubleValue(), borderType.value);
},
SocketHints.Inputs.createMatSocketHint("src", false),
SocketHints.Inputs.createNumberSpinnerSocketHint("ksize", 1),
SocketHints.Inputs.createNumberSpinnerSocketHint("scale", 1.0),
SocketHints.Inputs.createNumberSpinnerSocketHint("delta", 0.0),
SocketHints.createEnumSocketHint("borderType", BorderTypesEnum.BORDER_DEFAULT),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV medianBlur", "Apply a Median blur to an image."),
() -> new TwoSourceOneDestinationOperation<>(isf, osf,
(src, ksize, dst) -> {
opencv_imgproc.medianBlur(src, dst, ksize.intValue());
},
SocketHints.Inputs.createMatSocketHint("src", false),
SocketHints.Inputs.createNumberSpinnerSocketHint("ksize", 1, 1, Integer.MAX_VALUE),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV rectangle", "Draw a rectangle (outline or filled) on an image."),
() -> new SevenSourceOneDestinationOperation<>(isf, osf,
(src, pt1, pt2, color, thickness, lineType, shift, dst) -> {
src.copyTo(dst); // Rectangle only has one input and it modifies it so we have to copy the input image to the dst
opencv_imgproc.rectangle(dst, pt1, pt2, color, thickness.intValue(), lineType.value, shift.intValue());
},
SocketHints.Inputs.createMatSocketHint("src", false),
SocketHints.Inputs.createPointSocketHint("pt1", 0, 0),
SocketHints.Inputs.createPointSocketHint("pt2", 0, 0),
new SocketHint.Builder<>(Scalar.class).identifier("color").initialValueSupplier(() -> Scalar.BLACK).build(),
SocketHints.Inputs.createNumberSpinnerSocketHint("thickness", 0, Integer.MIN_VALUE, Integer.MAX_VALUE),
SocketHints.createEnumSocketHint("lineType", LineTypesEnum.LINE_8),
SocketHints.Inputs.createNumberSpinnerSocketHint("shift", 0),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV resize", "Resizes the image to the specified size"),
() -> new FiveSourceOneDestinationOperation<>(isf, osf,
(src, dsize, fx, fy, interpolation, dst) -> {
opencv_imgproc.resize(src, dst, dsize, fx.doubleValue(), fy.doubleValue(), interpolation.value);
},
SocketHints.Inputs.createMatSocketHint("src", false),
new SocketHint.Builder<>(Size.class).identifier("dsize").initialValueSupplier(() -> new Size(0, 0)).build(),
SocketHints.Inputs.createNumberSpinnerSocketHint("fx", .5),
SocketHints.Inputs.createNumberSpinnerSocketHint("fx", .5),
SocketHints.createEnumSocketHint("interpolation", InterpolationFlagsEnum.INTER_LINEAR),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV Sobel", "Find edges by calculating the requested derivative order for the given image."),
() -> new SevenSourceOneDestinationOperation<>(isf, osf,
(src, dx, dy, ksize, scale, delta, borderType, dst) -> {
opencv_imgproc.Sobel(src, dst, 0, dx.intValue(), dy.intValue(), ksize.intValue(), scale.doubleValue(), delta.doubleValue(), borderType.value);
},
SocketHints.Inputs.createMatSocketHint("src", false),
SocketHints.Inputs.createNumberSpinnerSocketHint("dx", 0),
SocketHints.Inputs.createNumberSpinnerSocketHint("dy", 0),
SocketHints.Inputs.createNumberSpinnerSocketHint("ksize", 3),
SocketHints.Inputs.createNumberSpinnerSocketHint("scale", 1),
SocketHints.Inputs.createNumberSpinnerSocketHint("delta", 0),
SocketHints.createEnumSocketHint("borderType", BorderTypesEnum.BORDER_DEFAULT),
SocketHints.Outputs.createMatSocketHint("dst")
)),
new OperationMetaData(CVOperation.defaults("CV Threshold", "Apply a fixed-level threshold to each array element in an image."),
() -> new FourSourceOneDestinationOperation<>(isf, osf,
(src, thresh, maxval, type, dst) -> {
opencv_imgproc.threshold(src, dst, thresh.doubleValue(), maxval.doubleValue(), type.value);
},
SocketHints.Inputs.createMatSocketHint("src", false),
SocketHints.Inputs.createNumberSpinnerSocketHint("thresh", 0),
SocketHints.Inputs.createNumberSpinnerSocketHint("maxval", 0),
SocketHints.createEnumSocketHint("type", ThresholdTypesEnum.THRESH_BINARY),
SocketHints.Outputs.createMatSocketHint("dst")
))
);
}
public void addOperations() {
coreOperations.stream()
.map(OperationAddedEvent::new)
.forEach(eventBus::post);
imgprocOperation.stream()
.map(OperationAddedEvent::new)
.forEach(eventBus::post);
}
}
package edu.wpi.grip.core.operations.templated;
import com.google.common.collect.ImmutableList;
import edu.wpi.grip.core.Operation;
import edu.wpi.grip.core.sockets.InputSocket;
import edu.wpi.grip.core.sockets.OutputSocket;
import edu.wpi.grip.core.sockets.SocketHint;
import java.util.List;
public class FiveSourceOneDestinationOperation<T1, T2, T3, T4, T5, R> implements Operation {
private final InputSocket<T1> input1;
private final InputSocket<T2> input2;
private final InputSocket<T3> input3;
private final InputSocket<T4> input4;
private final InputSocket<T5> input5;
private final OutputSocket<R> output;
private final Performer<T1, T2, T3, T4, T5, R> performer;
@FunctionalInterface
public interface Performer<T1, T2, T3, T4, T5, R> {
void perform(T1 src1, T2 src2, T3 src3, T4 src4, T5 src5, R dst);
}
public FiveSourceOneDestinationOperation(
InputSocket.Factory inputSocketFactory,
OutputSocket.Factory outputSocketFactory,
Performer<T1, T2, T3, T4, T5, R> performer,
SocketHint<T1> t1SocketHint,
SocketHint<T2> t2SocketHint,
SocketHint<T3> t3SocketHint,
SocketHint<T4> t4SocketHint,
SocketHint<T5> t5SocketHint,
SocketHint<R> rSocketHint) {
this.performer = performer;
this.input1 = inputSocketFactory.create(t1SocketHint);
this.input2 = inputSocketFactory.create(t2SocketHint);
this.input3 = inputSocketFactory.create(t3SocketHint);
this.input4 = inputSocketFactory.create(t4SocketHint);
this.input5 = inputSocketFactory.create(t5SocketHint);
this.output = outputSocketFactory.create(rSocketHint);
}
public FiveSourceOneDestinationOperation(
InputSocket.Factory inputSocketFactory,
OutputSocket.Factory outputSocketFactory,
Performer<T1, T2, T3, T4, T5, R> performer,
Class<T1> t1, Class<T2> t2, Class<T3> t3, Class<T4> t4, Class<T5> t5, Class<R> r) {
this(
inputSocketFactory,
outputSocketFactory,
performer,
new SocketHint.Builder<>(t1).identifier("src1").build(),
new SocketHint.Builder<>(t2).identifier("src2").build(),
new SocketHint.Builder<>(t3).identifier("src3").build(),
new SocketHint.Builder<>(t4).identifier("src4").build(),
new SocketHint.Builder<>(t5).identifier("src5").build(),
new SocketHint.Builder<>(r).identifier("dst").build());
}
@Override
public List<InputSocket> getInputSockets() {
return ImmutableList.of(input1, input2, input3, input4, input5);
}
@Override
public List<OutputSocket> getOutputSockets() {
return ImmutableList.of(output);
}
@Override
public void perform() {
performer.perform(input1.getValue().get(), input2.getValue().get(), input3.getValue().get(), input4.getValue().get(), input5.getValue().get(), output.getValue().get());
output.setValue(output.getValue().get());
}
}
package edu.wpi.grip.core.operations.templated;
import com.google.common.collect.ImmutableList;
import edu.wpi.grip.core.Operation;
import edu.wpi.grip.core.sockets.InputSocket;
import edu.wpi.grip.core.sockets.OutputSocket;
import edu.wpi.grip.core.sockets.SocketHint;
import java.util.List;
public class FourSourceOneDestinationOperation<T1, T2, T3, T4, R> implements Operation {
private final InputSocket<T1> input1;
private final InputSocket<T2> input2;
private final InputSocket<T3> input3;
private final InputSocket<T4> input4;
private final OutputSocket<R> output;
private final Performer<T1, T2, T3, T4, R> performer;
@FunctionalInterface
public interface Performer<T1, T2, T3, T4, R> {
void perform(T1 src1, T2 src2, T3 src3, T4 src4, R dst);
}
public FourSourceOneDestinationOperation(
InputSocket.Factory inputSocketFactory,
OutputSocket.Factory outputSocketFactory,
Performer<T1, T2, T3, T4, R> performer,
SocketHint<T1> t1SocketHint,
SocketHint<T2> t2SocketHint,
SocketHint<T3> t3SocketHint,
SocketHint<T4> t4SocketHint,
SocketHint<R> rSocketHint) {
this.performer = performer;
this.input1 = inputSocketFactory.create(t1SocketHint);
this.input2 = inputSocketFactory.create(t2SocketHint);
this.input3 = inputSocketFactory.create(t3SocketHint);
this.input4 = inputSocketFactory.create(t4SocketHint);
this.output = outputSocketFactory.create(rSocketHint);
}
public FourSourceOneDestinationOperation(
InputSocket.Factory inputSocketFactory,
OutputSocket.Factory outputSocketFactory,
Performer<T1, T2, T3, T4, R> performer,
Class<T1> t1, Class<T2> t2, Class<T3> t3, Class<T4> t4, Class<R> r) {
this(
inputSocketFactory,
outputSocketFactory,
performer,
new SocketHint.Builder<>(t1).identifier("src1").build(),
new SocketHint.Builder<>(t2).identifier("src2").build(),
new SocketHint.Builder<>(t3).identifier("src3").build(),
new SocketHint.Builder<>(t4).identifier("src4").build(),
new SocketHint.Builder<>(r).identifier("dst").build());
}
@Override
public List<InputSocket> getInputSockets() {
return ImmutableList.of(input1, input2, input3, input4);
}
@Override
public List<OutputSocket> getOutputSockets() {
return ImmutableList.of(output);
}
@Override
public void perform() {
performer.perform(
input1.getValue().get(),
input2.getValue().get(),
input3.getValue().get(),
input4.getValue().get(),
output.getValue().get()
);
output.setValue(output.getValue().get());
}
}
package edu.wpi.grip.core.operations.templated;
import edu.wpi.grip.core.sockets.InputSocket;
import edu.wpi.grip.core.sockets.OutputSocket;
import edu.wpi.grip.core.sockets.SocketHint;
import org.bytedeco.javacpp.opencv_core.Mat;
public class MatTwoSourceOneDestinationOperation extends TwoSourceOneDestinationOperation<Mat, Mat, Mat> {
public MatTwoSourceOneDestinationOperation(InputSocket.Factory inputSocketFactory, OutputSocket.Factory outputSocketFactory, Performer<Mat, Mat, Mat> performer, SocketHint<Mat> matSocketHint, SocketHint<Mat> matSocketHint2, SocketHint<Mat> matSocketHint3) {
super(inputSocketFactory, outputSocketFactory, performer, matSocketHint, matSocketHint2, matSocketHint3);
}
public MatTwoSourceOneDestinationOperation(InputSocket.Factory inputSocketFactory, OutputSocket.Factory outputSocketFactory, Performer<Mat, Mat, Mat> performer) {
super(inputSocketFactory, outputSocketFactory, performer, Mat.class, Mat.class, Mat.class);
}
}
package edu.wpi.grip.core.operations.templated;
import autovalue.shaded.com.google.common.common.collect.ImmutableList;
import edu.wpi.grip.core.Operation;
import edu.wpi.grip.core.sockets.InputSocket;
import edu.wpi.grip.core.sockets.OutputSocket;
import edu.wpi.grip.core.sockets.SocketHint;
import java.util.List;
public class OneSourceOneDestinationOperation<T1, R> implements Operation {
private final InputSocket<T1> input1;
private final OutputSocket<R> output;
private final Performer<T1, R> performer;
@FunctionalInterface
public interface Performer<T1, R> {
void perform(T1 src1, R dst);
}
public OneSourceOneDestinationOperation(InputSocket.Factory inputSocketFactory,
OutputSocket.Factory outputSocketFactory,
Performer<T1, R> performer,
SocketHint<T1> t1SocketHint,
SocketHint<R> rSocketHint) {
this.input1 = inputSocketFactory.create(t1SocketHint);
this.output = outputSocketFactory.create(rSocketHint);
this.performer = performer;
}
public OneSourceOneDestinationOperation(InputSocket.Factory inputSocketFactory,
OutputSocket.Factory outputSocketFactory,
Performer<T1, R> performer,
Class<T1> t1,
Class<R> r) {
this(inputSocketFactory,
outputSocketFactory,
performer,
new SocketHint.Builder<>(t1).identifier("src1").build(),
new SocketHint.Builder<>(r).identifier("dst").build());
}
@Override
public List<InputSocket> getInputSockets() {
return ImmutableList.of(input1);
}
@Override
public List<OutputSocket> getOutputSockets() {
return ImmutableList.of(output);
}
@Override
public void perform() {
performer.perform(input1.getValue().get(), output.getValue().get());
output.setValue(output.getValue().get());
}
}
package edu.wpi.grip.core;
import edu.wpi.grip.core.sockets.InputSocket;
import edu.wpi.grip.core.sockets.OutputSocket;
import java.util.List;
/**
* The common interface used by <code>Step</code>s in a pipeline to call various operations. Each instance of an
* operation in the pipeline is handled by a unique instance of that {@code Operation} class.
*/
public interface Operation {
/**
* @return A list of sockets for the inputs that the operation expects.
*
* @implNote The returned list should be immutable (i.e. read-only)
*/
List<InputSocket> getInputSockets();
/**
* @return A list of sockets for the outputs that the operation produces.
*
* @implNote The returned list should be immutable (i.e. read-only)
*/
List<OutputSocket> getOutputSockets();
/**
* Performs this {@code Operation}.
*/
void perform();
/**
* Allows the step to clean itself up when removed from the pipeline.
* This should only be called by {@link Step#setRemoved()} to ensure correct synchronization.
*/
default void cleanUp() {
/* no-op */
}
}
package edu.wpi.grip.core.operations.templated;
import com.google.common.collect.ImmutableList;
import edu.wpi.grip.core.Operation;
import edu.wpi.grip.core.sockets.InputSocket;
import edu.wpi.grip.core.sockets.OutputSocket;
import edu.wpi.grip.core.sockets.SocketHint;
import java.util.List;
/**
* An Operation that takes two input values and produces one output value
* @param <T1>
* @param <T2>
* @param <R>
*/
public class TwoSourceOneDestinationOperation<T1, T2, R> implements Operation {
private final InputSocket<T1> input1;
private final InputSocket<T2> input2;
private final OutputSocket<R> output;
private final Performer<T1, T2, R> performer;
@FunctionalInterface
public interface Performer<T1, T2, R> {
void perform(T1 src1, T2 src2, R dst);
}
public TwoSourceOneDestinationOperation(
InputSocket.Factory inputSocketFactory,
OutputSocket.Factory outputSocketFactory,
Performer<T1, T2, R> performer,
SocketHint<T1> t1SocketHint,
SocketHint<T2> t2SocketHint,
SocketHint<R> rSocketHint) {
this.performer = performer;
this.input1 = inputSocketFactory.create(t1SocketHint);
this.input2 = inputSocketFactory.create(t2SocketHint);
this.output = outputSocketFactory.create(rSocketHint);
}
public TwoSourceOneDestinationOperation(
InputSocket.Factory inputSocketFactory,
OutputSocket.Factory outputSocketFactory,
Performer<T1, T2, R> performer,
Class<T1> t1, Class<T2> t2, Class<R> r) {
this(
inputSocketFactory,
outputSocketFactory,
performer,
new SocketHint.Builder<>(t1).identifier("src1").build(),
new SocketHint.Builder<>(t2).identifier("src2").build(),
new SocketHint.Builder<>(r).identifier("dst").build());
}
@Override
public List<InputSocket> getInputSockets() {
return ImmutableList.of(input1, input2);
}
@Override
public List<OutputSocket> getOutputSockets() {
return ImmutableList.of(output);
}
@Override
public void perform() {
performer.perform(input1.getValue().get(), input2.getValue().get(), output.getValue().get());
output.setValue(output.getValue().get());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment