44import edu .wpi .grip .core .*;
55
66import java .io .InputStream ;
7+ import java .util .List ;
78import java .util .Optional ;
89
910import static org .bytedeco .javacpp .opencv_core .*;
@@ -41,6 +42,9 @@ public class FilterContoursOperation implements Operation {
4142 private final SocketHint <Number > maxHeightHint =
4243 SocketHints .Inputs .createNumberSpinnerSocketHint ("Max Height" , 1000 , 0 , Integer .MAX_VALUE );
4344
45+ private final SocketHint <List > solidityHint =
46+ SocketHints .Inputs .createNumberListRangeSocketHint ("Solidity" , 0 , 100 );
47+
4448 @ Override
4549 public String getName () {
4650 return "Filter Contours" ;
@@ -66,6 +70,7 @@ public InputSocket<?>[] createInputSockets(EventBus eventBus) {
6670 new InputSocket <>(eventBus , maxWidthHint ),
6771 new InputSocket <>(eventBus , minHeightHint ),
6872 new InputSocket <>(eventBus , maxHeightHint ),
73+ new InputSocket <>(eventBus , solidityHint ),
6974 };
7075 }
7176
@@ -84,22 +89,31 @@ public void perform(InputSocket<?>[] inputs, OutputSocket<?>[] outputs) {
8489 final double maxWidth = ((Number ) inputs [4 ].getValue ().get ()).doubleValue ();
8590 final double minHeight = ((Number ) inputs [5 ].getValue ().get ()).doubleValue ();
8691 final double maxHeight = ((Number ) inputs [6 ].getValue ().get ()).doubleValue ();
92+ final double minSolidity = ((List <Number >) inputs [7 ].getValue ().get ()).get (0 ).doubleValue ();
93+ final double maxSolidity = ((List <Number >) inputs [7 ].getValue ().get ()).get (1 ).doubleValue ();
8794
8895 final MatVector inputContours = inputSocket .getValue ().get ().getContours ();
8996 final MatVector outputContours = new MatVector (inputContours .size ());
97+ final Mat hull = new Mat ();
9098
9199 // Add contours from the input vector to the output vector only if they pass all of the criteria (minimum
92- // area, minimum perimeter, width, and height)
100+ // area, minimum perimeter, width, and height, etc... )
93101 int filteredContourCount = 0 ;
94102 for (int i = 0 ; i < inputContours .size (); i ++) {
95103 final Mat contour = inputContours .get (i );
96- final Rect bb = boundingRect (contour );
97104
98- if (contourArea (contour ) < minArea ) continue ;
99- if (arcLength (contour , true ) < minPerimeter ) continue ;
105+ final Rect bb = boundingRect (contour );
100106 if (bb .width () < minWidth || bb .width () > maxWidth ) continue ;
101107 if (bb .height () < minHeight || bb .height () > maxHeight ) continue ;
102108
109+ final double area = contourArea (contour );
110+ if (area < minArea ) continue ;
111+ if (arcLength (contour , true ) < minPerimeter ) continue ;
112+
113+ convexHull (contour , hull );
114+ final double solidity = 100 * area / contourArea (hull );
115+ if (solidity < minSolidity || solidity > maxSolidity ) continue ;
116+
103117 outputContours .put (filteredContourCount ++, contour );
104118 }
105119
0 commit comments