From 72d99197d3ac9cc4e60ee403efc0d7ab8e0e7623 Mon Sep 17 00:00:00 2001 From: Tim Winters Date: Thu, 28 Dec 2017 15:26:14 -0500 Subject: [PATCH] Add kernel operation and add both kernel and morphology to code generation --- .../grip/core/operations/CVOperations.java | 20 ++--- .../operations/opencv/NewKernelOperation.java | 89 +++++++++++++++++++ .../cpp/operations/CV_morphologyEx.vm | 14 +++ .../cpp/operations/New_Kernel.vm | 8 ++ .../java/operations/CV_morphologyEx.vm | 24 +++++ .../java/operations/New_Kernel.vm | 8 ++ .../python/operations/CV_morphologyEx.vm | 14 +++ .../python/operations/New_Kernel.vm | 10 +++ 8 files changed, 177 insertions(+), 10 deletions(-) create mode 100644 core/src/main/java/edu/wpi/grip/core/operations/opencv/NewKernelOperation.java create mode 100644 ui/src/main/resources/edu/wpi/grip/ui/codegeneration/cpp/operations/CV_morphologyEx.vm create mode 100644 ui/src/main/resources/edu/wpi/grip/ui/codegeneration/cpp/operations/New_Kernel.vm create mode 100644 ui/src/main/resources/edu/wpi/grip/ui/codegeneration/java/operations/CV_morphologyEx.vm create mode 100644 ui/src/main/resources/edu/wpi/grip/ui/codegeneration/java/operations/New_Kernel.vm create mode 100644 ui/src/main/resources/edu/wpi/grip/ui/codegeneration/python/operations/CV_morphologyEx.vm create mode 100644 ui/src/main/resources/edu/wpi/grip/ui/codegeneration/python/operations/New_Kernel.vm diff --git a/core/src/main/java/edu/wpi/grip/core/operations/CVOperations.java b/core/src/main/java/edu/wpi/grip/core/operations/CVOperations.java index 0124b59259..511cbf5a99 100644 --- a/core/src/main/java/edu/wpi/grip/core/operations/CVOperations.java +++ b/core/src/main/java/edu/wpi/grip/core/operations/CVOperations.java @@ -17,6 +17,7 @@ import edu.wpi.grip.generated.opencv_imgproc.enumeration.ColorConversionCodesEnum; import edu.wpi.grip.generated.opencv_imgproc.enumeration.ColormapTypesEnum; import edu.wpi.grip.generated.opencv_imgproc.enumeration.InterpolationFlagsEnum; +import edu.wpi.grip.generated.opencv_imgproc.enumeration.MorphTypesEnum; import edu.wpi.grip.generated.opencv_imgproc.enumeration.ThresholdTypesEnum; import com.google.common.annotations.VisibleForTesting; @@ -313,8 +314,8 @@ public class CVOperations { "Performs advanced morphological transformations."), templateFactory.create( SocketHints.Inputs.createMatSocketHint("src", false), + SocketHints.createEnumSocketHint("op", MorphTypesEnum.MORPH_OPEN), SocketHints.Inputs.createMatSocketHint("kernel", true), - SocketHints.createEnumSocketHint("op", CVMorphologyTypesEnum.MORPH_OPEN), new SocketHint.Builder<>(Point.class).identifier("anchor").initialValueSupplier( () -> new Point(-1, -1)).build(), SocketHints.Inputs.createNumberSpinnerSocketHint("iterations", 1), @@ -322,7 +323,7 @@ public class CVOperations { new SocketHint.Builder<>(Scalar.class).identifier("borderValue") .initialValueSupplier(opencv_imgproc::morphologyDefaultBorderValue).build(), SocketHints.Outputs.createMatSocketHint("dst"), - (src, kernel, op, anchor, iterations, borderType, borderValue, dst) -> { + (src, op, kernel, anchor, iterations, borderType, borderValue, dst) -> { opencv_imgproc.morphologyEx(src, dst, op.value, kernel, anchor, iterations.intValue(), borderType.value, borderValue); } @@ -447,17 +448,16 @@ public enum CVBorderTypesEnum { } } - public enum CVMorphologyTypesEnum { - MORPH_OPEN(2), - MORPH_CLOSE(3), - MORPH_GRADIENT(4), - MORPH_TOPHAT(5), - MORPH_BLACKHAT(6), - MORPH_HITMISS(7); + public enum CVMorphTypesEnum { + MORPH_OPEN(MorphTypesEnum.MORPH_OPEN.value), + MORPH_CLOSE(MorphTypesEnum.MORPH_CLOSE.value), + MORPH_GRADIENT(MorphTypesEnum.MORPH_GRADIENT.value), + MORPH_TOPHAT(MorphTypesEnum.MORPH_TOPHAT.value), + MORPH_BLACKHAT(MorphTypesEnum.MORPH_BLACKHAT.value); public final int value; - CVMorphologyTypesEnum(int value) { + CVMorphTypesEnum(int value) { this.value = value; } } diff --git a/core/src/main/java/edu/wpi/grip/core/operations/opencv/NewKernelOperation.java b/core/src/main/java/edu/wpi/grip/core/operations/opencv/NewKernelOperation.java new file mode 100644 index 0000000000..17fdcf7825 --- /dev/null +++ b/core/src/main/java/edu/wpi/grip/core/operations/opencv/NewKernelOperation.java @@ -0,0 +1,89 @@ +package edu.wpi.grip.core.operations.opencv; + + +import edu.wpi.grip.core.Description; +import edu.wpi.grip.core.OperationDescription; +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 com.google.inject.Inject; + +import org.bytedeco.javacpp.opencv_core.Mat; +import org.bytedeco.javacpp.opencv_core.Size; +import org.bytedeco.javacpp.opencv_imgproc; +import org.python.google.common.collect.ImmutableList; + +import java.util.List; + +@Description(name = "New Kernel", + summary = "Create a kernel of custom size", + category = OperationDescription.Category.OPENCV, + iconName = "kernel") +public class NewKernelOperation implements CVOperation { + + private final SocketHint typeHint = SocketHints.createEnumSocketHint("kernelType", + KernelEnum.MORPH_RECT); + private final SocketHint widthHint = SocketHints.Inputs + .createNumberSpinnerSocketHint("width", 1, 1, Integer.MAX_VALUE); + private final SocketHint heightHint = SocketHints.Inputs + .createNumberSpinnerSocketHint("height", 1, 1, Integer.MAX_VALUE); + private final SocketHint outputHint = SocketHints.Outputs.createMatSocketHint("kernel"); + + + private final InputSocket widthSocket; + private final InputSocket heightSocket; + private final InputSocket typeSocket; + + private final OutputSocket outputSocket; + + @Inject + @SuppressWarnings("JavadocMethod") + public NewKernelOperation(InputSocket.Factory inputSocketFactory, + OutputSocket.Factory outputSocketFactory) { + this.typeSocket = inputSocketFactory.create(typeHint); + this.widthSocket = inputSocketFactory.create(widthHint); + this.heightSocket = inputSocketFactory.create(heightHint); + this.outputSocket = outputSocketFactory.create(outputHint); + } + + @Override + public List getInputSockets() { + return ImmutableList.of( + typeSocket, + widthSocket, + heightSocket + ); + } + + @Override + public List getOutputSockets() { + return ImmutableList.of( + outputSocket + ); + } + + @Override + public void perform() { + final int widthValue = widthSocket.getValue().get().intValue(); + final int heightValue = heightSocket.getValue().get().intValue(); + final int kernelType = typeSocket.getValue().get().value; + + outputSocket.setValue(opencv_imgproc.getStructuringElement(kernelType, new Size(widthValue, + heightValue))); + } + + public enum KernelEnum { + MORPH_RECT(0), + MORPH_CROSS(1), + MORPH_ELLIPSE(2); + + public final int value; + + KernelEnum(int value) { + this.value = value; + } + } +} + diff --git a/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/cpp/operations/CV_morphologyEx.vm b/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/cpp/operations/CV_morphologyEx.vm new file mode 100644 index 0000000000..68dc4cf4f8 --- /dev/null +++ b/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/cpp/operations/CV_morphologyEx.vm @@ -0,0 +1,14 @@ + /** + * Performs advanced morphology functions. + * @param src the Image to morph. + * @param op the morph operation + * @param kernel the kernel for morphing. + * @param anchor the center of the kernel. + * @param iterations the number of times to perform the morph. + * @param borderType pixel extrapolation method. + * @param borderValue value to be used for a constant border. + * @param dst Output Image. + */ + void $className::#func($step ["src", "op", "kernel", "anchor", "iterations", "borderType", "borderValue", "dst"]) { + cv::morphologyEx(src, dst, op, kernel, anchor, (int)iterations, borderType, borderValue); + } diff --git a/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/cpp/operations/New_Kernel.vm b/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/cpp/operations/New_Kernel.vm new file mode 100644 index 0000000000..7779d54664 --- /dev/null +++ b/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/cpp/operations/New_Kernel.vm @@ -0,0 +1,8 @@ + /** + * Creates kernel of given shape and size + * @param shape the kernels MorphShape. + * @param size the size of the kernel. + */ + void $className::#func($step ["shape", "size"]) { + return cv::getStructuringElement(shape, size)); + } diff --git a/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/java/operations/CV_morphologyEx.vm b/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/java/operations/CV_morphologyEx.vm new file mode 100644 index 0000000000..5a0126f299 --- /dev/null +++ b/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/java/operations/CV_morphologyEx.vm @@ -0,0 +1,24 @@ + /** + * Performs advanced morphology functions. + * @param src the Image to morph. + * @param op the operation to perform. + * @param kernel the kernel for morphing. + * @param anchor the center of the kernel. + * @param iterations the number of times to perform the morph. + * @param borderType pixel extrapolation method. + * @param borderValue value to be used for a constant border. + * @param dst Output Image. + */ + private void $tMeth.name($step.name())(Mat src, MorphType op, Mat kernel, Point anchor, double iterations, + int borderType, Scalar borderValue, Mat dst) { + if (kernel == null) { + kernel = new Mat(); + } + if (anchor == null) { + anchor = new Point(-1,-1); + } + if (borderValue == null) { + borderValue = new Scalar(-1); + } + Imgproc.morphologyEx(src, dst, op, kernel, anchor, (int)iterations, borderType, borderValue); + } \ No newline at end of file diff --git a/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/java/operations/New_Kernel.vm b/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/java/operations/New_Kernel.vm new file mode 100644 index 0000000000..11c0a4ee04 --- /dev/null +++ b/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/java/operations/New_Kernel.vm @@ -0,0 +1,8 @@ + /** + * Creates a kernel of given shape and size. + * @param shape the kernels MorphShape. + * @param size the size of the kernel. + */ + private void $tMeth.name($step.name())(Mat shape, Size size) { + Imgproc.getStructuringElement(shape, size); + } \ No newline at end of file diff --git a/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/python/operations/CV_morphologyEx.vm b/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/python/operations/CV_morphologyEx.vm new file mode 100644 index 0000000000..affb3cfe40 --- /dev/null +++ b/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/python/operations/CV_morphologyEx.vm @@ -0,0 +1,14 @@ + @staticmethod + def $tMeth.name($step.name())(src, op, kernel, anchor, iterations, border_type, border_value): + """Expands area of lower value in an image. + Args: + src: A numpy.ndarray. + kernel: The kernel for erosion. A numpy.ndarray. + iterations: the number of times to erode. + border_type: Opencv enum that represents a border type. + border_value: value to be used for a constant border. + Returns: + A numpy.ndarray after erosion. + """ + return cv2.morphologyEx(src, op, kernel, anchor, iterations = (int) (iterations +0.5), + borderType = border_type, borderValue = border_value) \ No newline at end of file diff --git a/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/python/operations/New_Kernel.vm b/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/python/operations/New_Kernel.vm new file mode 100644 index 0000000000..b27a7bfa66 --- /dev/null +++ b/ui/src/main/resources/edu/wpi/grip/ui/codegeneration/python/operations/New_Kernel.vm @@ -0,0 +1,10 @@ + @staticmethod + def $tMeth.name($step.name())(shape, width, height): + """Creates kernel of given shape and size. + Args: + shape: The kernel MorphShape + size: Size of kernel as a tuple + Returns: + A numpy.ndarray representing the kernel. + """ + return cv2.getStructuringElement(shape, (int(width), int(height))) \ No newline at end of file