コード例 #1
0
/**
 * An {@link edu.wpi.grip.core.Operation} that converts a color image into a binary image based on
 * the HSL threshold ranges
 */
public class HSLThresholdOperation extends ThresholdOperation {
  private static final Logger logger = Logger.getLogger(HSLThresholdOperation.class.getName());
  private final SocketHint<Mat> inputHint = SocketHints.Inputs.createMatSocketHint("Input", false);
  private final SocketHint<List> hueHint =
      SocketHints.Inputs.createNumberListRangeSocketHint("Hue", 0.0, 180.0);
  private final SocketHint<List> saturationHint =
      SocketHints.Inputs.createNumberListRangeSocketHint("Saturation", 0.0, 255.0);
  private final SocketHint<List> luminanceHint =
      SocketHints.Inputs.createNumberListRangeSocketHint("Luminance", 0.0, 255.0);

  private final SocketHint<Mat> outputHint = SocketHints.Outputs.createMatSocketHint("Output");

  @Override
  public String getName() {
    return "HSL Threshold";
  }

  @Override
  public String getDescription() {
    return "Segment an image based on hue, saturation, and luminance ranges.";
  }

  @Override
  public InputSocket<?>[] createInputSockets(EventBus eventBus) {
    return new InputSocket<?>[] {
      new InputSocket<>(eventBus, inputHint),
      new InputSocket<>(eventBus, hueHint),
      new InputSocket<>(eventBus, saturationHint),
      new InputSocket<>(eventBus, luminanceHint),
    };
  }

  @Override
  public OutputSocket<?>[] createOutputSockets(EventBus eventBus) {
    return new OutputSocket<?>[] {new OutputSocket<>(eventBus, outputHint)};
  }

  @Override
  public void perform(InputSocket<?>[] inputs, OutputSocket<?>[] outputs, Optional<?> data) {
    final Mat[] dataArray =
        (Mat[]) data.orElseThrow(() -> new IllegalStateException("Data was not provided"));

    final Mat input = ((InputSocket<Mat>) inputs[0]).getValue().get();
    final List<Number> channel1 = ((InputSocket<List<Number>>) inputs[1]).getValue().get();
    final List<Number> channel2 = ((InputSocket<List<Number>>) inputs[2]).getValue().get();
    final List<Number> channel3 = ((InputSocket<List<Number>>) inputs[3]).getValue().get();

    final OutputSocket<Mat> outputSocket = (OutputSocket<Mat>) outputs[0];
    final Mat output = outputSocket.getValue().get();

    // Intentionally 1, 3, 2. This maps to the HLS open cv expects
    final Scalar lowScalar =
        new Scalar(
            channel1.get(0).doubleValue(),
            channel3.get(0).doubleValue(),
            channel2.get(0).doubleValue(),
            0);

    final Scalar highScalar =
        new Scalar(
            channel1.get(1).doubleValue(),
            channel3.get(1).doubleValue(),
            channel2.get(1).doubleValue(),
            0);

    final Mat low = reallocateMatIfInputSizeOrWidthChanged(dataArray, 0, lowScalar, input);
    final Mat high = reallocateMatIfInputSizeOrWidthChanged(dataArray, 1, highScalar, input);
    final Mat hls = dataArray[2];

    try {
      cvtColor(input, hls, COLOR_BGR2HLS);
      inRange(hls, low, high, output);
      outputSocket.setValue(output);
    } catch (RuntimeException e) {
      logger.log(Level.WARNING, e.getMessage(), e);
    }
  }
}