Skip to content

Introduction to OpenCV for FTC

Updated: at 09:12 AM (4 min read) Suggest Changes

Table of contents

Open Table of contents

Frontmatter

OpenCV is currently the most widely used computer vision library in FTC. We will be making use of the Java version of the library via OpenFTC’s EasyOpenCV library.

As opposed to Vuforia, openCV contains many useful functions that make image processing and object detection a simple task. Moreover, it allows for the implementation of advanced computer vision concepts as well, such as object detection. The documentation for OpenCV is far superior to that of Vuforia’s making it the best CV tool for most teams.

Here are some important definitions you should understand:

An OpenCV workflow would look like the following:

Example banner

Implementation

You can implement an easy-to-use camera class like this:

:::info

Pipeline Class

public class samplePipeline1 extends OpenCvPipeline {
   
  private String output = "nothing";

  public samplePipeline1() {
    
  }
  
  // Mat is the image matrix that should be processed. 
  @Override
  public Mat processFrame(Mat input) {
    output = "Sample Pipeline Is Running!"; 
    return input;
  }

  public String getOutput() {
    return output;
  }
}

Camera Class

public class Camera {
  private OpenCvWebcam webcam;
  private HardwareMap hardwareMap;
  private samplePipeline1 p1; // sample pipeline
  private samplePipeline2 p2; // another sample pipeline

  public Camera(HardwareMap hw) { // hardware map from the base class is a parameter
    p1 = new samplePipeline1(); // initialize your pipeline classes
    p2 = new samplePipeline2();

    this.hardwareMap = hw;    //Configure the Camera in hardwaremap
    int cameraMonitorViewId =
        hardwareMap
            .appContext
            .getResources()
            .getIdentifier("cameraMonitorViewId", "id", hardwareMap.appContext.getPackageName());
    // Get camera from hardware map, replace 'camera' with what is in your controlhub
    webcam =
        OpenCvCameraFactory.getInstance()
            .createWebcam(hardwareMap.get(WebcamName.class, "camera"), cameraMonitorViewId);
    
    webcam.setPipeline(p1); // Setting the intial pipeline
    
    webcam.setMillisecondsPermissionTimeout(2500);
    
    // Streaming Frames
    webcam.openCameraDeviceAsync(
        new OpenCvCamera.AsyncCameraOpenListener() {
          @Override
          public void onOpened() {
            webcam.startStreaming(320, 240, OpenCvCameraRotation.UPRIGHT);
          }

          @Override
          public void onError(int errorCode) {}
        });
  }
  
  // Switching Between Pipelines
  public void switchToSecondPipeline(){
      webcam.setPipeline(p2);
  }
  
  public void switchToFirstPipeline(){
      webcam.setPipeline(p1);
  }
  
  // Get information from pipeline 
  public String getPipeline1Output(){ 
      return p1.getOutput(); 
  }
  
  // call stop at the end of the opMode. 
  public void stop() {
    webcam.stopStreaming();
  }
}

OpMode

@TeleOp(name = "Sample_TeleOP", group = "robot")
public class Test_teleop extends LinearOpMode {
  Camera camera = new Camera(hardwareMap);

  @Override
  public void runOpMode() throws InterruptedException {
    camera.switchToFirstPipeline();
    telemetry.addLine("Status: Initialized");
    waitForStart();

    while (opModeIsActive()) {
      // OpMode receives the information transmitted from the pipeline class
      // to the camera module class. 
      telemetry.addLine(camera.getPipeline1Output()); 
      telemetry.update();
    }
  }
}

Previous Post
Color Thresholding
Next Post
Introduction to Vuforia