-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use CS Core on supported platforms for USB cameras (#956)
* Update jpackage to release 64 Existing version was deleted * Use CS Core on supported platforms for USB cameras Can be more reliable then OpenCV, and handles disconnects properly * Fix unused imports
- Loading branch information
Showing
3 changed files
with
212 additions
and
108 deletions.
There are no files selected for viewing
198 changes: 101 additions & 97 deletions
198
...ip/core/sources/CSCameraFrameGrabber.java → ...ore/sources/CSHttpCameraFrameGrabber.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,97 +1,101 @@ | ||
package edu.wpi.grip.core.sources; | ||
|
||
import edu.wpi.cscore.CameraServerJNI; | ||
import edu.wpi.cscore.HttpCamera; | ||
import org.bytedeco.javacpp.Loader; | ||
import org.bytedeco.javacpp.opencv_core.Mat; | ||
import org.bytedeco.javacv.Frame; | ||
import org.bytedeco.javacv.FrameConverter; | ||
import org.bytedeco.javacv.FrameGrabber; | ||
import org.bytedeco.javacv.OpenCVFrameConverter; | ||
|
||
import java.io.IOException; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
import static com.google.common.base.Preconditions.checkNotNull; | ||
|
||
// This is here because FrameGrabber has an exception called Exception which triggers PMD | ||
@SuppressWarnings({"PMD.AvoidThrowingRawExceptionTypes", "all"}) | ||
public class CSCameraFrameGrabber extends FrameGrabber { | ||
|
||
private static Exception loadingException = null; | ||
|
||
private final String url; | ||
private final double readTimeout; | ||
|
||
private Mat decoded = null; | ||
private FrameConverter<Mat> converter = new OpenCVFrameConverter.ToMat(); | ||
|
||
private JavaCvSink javaCvSink; | ||
private HttpCamera httpCamera; | ||
|
||
public CSCameraFrameGrabber(String urlstr, int readTimeout, TimeUnit unit) { | ||
super(); | ||
this.url = checkNotNull(urlstr, "urlstr"); | ||
this.readTimeout = TimeUnit.MILLISECONDS.convert(readTimeout, unit) / 1000.0; | ||
} | ||
|
||
public static void tryLoad() throws Exception { | ||
if (loadingException != null) { | ||
throw loadingException; | ||
} else { | ||
try { | ||
Loader.load(org.bytedeco.javacpp.opencv_highgui.class); | ||
CameraServerJNI.Helper.setExtractOnStaticLoad(false); | ||
CameraServerJNI.forceLoad(); | ||
} catch (Throwable t) { | ||
throw loadingException = new Exception("Failed to load " + CSCameraFrameGrabber.class, t); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void start() throws Exception { | ||
javaCvSink = new JavaCvSink("InputCamera"); | ||
httpCamera = new HttpCamera("InputHttp", url); | ||
javaCvSink.setSource(httpCamera); | ||
} | ||
|
||
public void stop() throws Exception { | ||
if (javaCvSink != null) { | ||
javaCvSink.close(); | ||
} | ||
|
||
if (httpCamera != null) { | ||
httpCamera.close(); | ||
} | ||
|
||
if (decoded != null) { | ||
decoded.close(); | ||
} | ||
} | ||
|
||
@Override | ||
public void trigger() throws Exception { | ||
} | ||
|
||
@Override | ||
public Frame grab() throws Exception { | ||
try { | ||
if (decoded == null) { | ||
decoded = new Mat(); | ||
} | ||
long frameTime = javaCvSink.grabFrame(decoded, readTimeout); | ||
if (frameTime > 0) { | ||
return converter.convert(decoded); | ||
} else { | ||
throw new IOException("Frame not read: " + frameTime); | ||
} | ||
} catch (IOException e) { | ||
throw new Exception(e.getMessage(), e); | ||
} | ||
} | ||
|
||
@Override | ||
public void release() throws Exception { | ||
} | ||
} | ||
package edu.wpi.grip.core.sources; | ||
|
||
import edu.wpi.cscore.CameraServerJNI; | ||
import edu.wpi.cscore.HttpCamera; | ||
import org.bytedeco.javacpp.Loader; | ||
import org.bytedeco.javacpp.opencv_core.Mat; | ||
import org.bytedeco.javacv.Frame; | ||
import org.bytedeco.javacv.FrameConverter; | ||
import org.bytedeco.javacv.FrameGrabber; | ||
import org.bytedeco.javacv.OpenCVFrameConverter; | ||
|
||
import java.io.IOException; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
import static com.google.common.base.Preconditions.checkNotNull; | ||
|
||
// This is here because FrameGrabber has an exception called Exception which triggers PMD | ||
@SuppressWarnings({"PMD.AvoidThrowingRawExceptionTypes", "all"}) | ||
public class CSHttpCameraFrameGrabber extends FrameGrabber { | ||
|
||
private static Exception loadingException = null; | ||
|
||
private final String url; | ||
private final double readTimeout; | ||
|
||
private Mat decoded = null; | ||
private FrameConverter<Mat> converter = new OpenCVFrameConverter.ToMat(); | ||
|
||
private JavaCvSink javaCvSink; | ||
private HttpCamera httpCamera; | ||
|
||
public CSHttpCameraFrameGrabber(String urlstr, int readTimeout, TimeUnit unit) { | ||
super(); | ||
this.url = checkNotNull(urlstr, "urlstr"); | ||
this.readTimeout = TimeUnit.MILLISECONDS.convert(readTimeout, unit) / 1000.0; | ||
} | ||
|
||
public static void tryLoad() throws Exception { | ||
if (loadingException != null) { | ||
throw loadingException; | ||
} else { | ||
try { | ||
Loader.load(org.bytedeco.javacpp.opencv_highgui.class); | ||
CameraServerJNI.Helper.setExtractOnStaticLoad(false); | ||
CameraServerJNI.forceLoad(); | ||
} catch (Throwable t) { | ||
throw loadingException = new Exception("Failed to load " + CSHttpCameraFrameGrabber.class, t); | ||
} | ||
} | ||
} | ||
|
||
public HttpCamera getCamera() { | ||
return this.httpCamera; | ||
} | ||
|
||
@Override | ||
public void start() throws Exception { | ||
javaCvSink = new JavaCvSink("InputCamera"); | ||
httpCamera = new HttpCamera("InputHttp", url); | ||
javaCvSink.setSource(httpCamera); | ||
} | ||
|
||
public void stop() throws Exception { | ||
if (javaCvSink != null) { | ||
javaCvSink.close(); | ||
} | ||
|
||
if (httpCamera != null) { | ||
httpCamera.close(); | ||
} | ||
|
||
if (decoded != null) { | ||
decoded.close(); | ||
} | ||
} | ||
|
||
@Override | ||
public void trigger() throws Exception { | ||
} | ||
|
||
@Override | ||
public Frame grab() throws Exception { | ||
try { | ||
if (decoded == null) { | ||
decoded = new Mat(); | ||
} | ||
long frameTime = javaCvSink.grabFrame(decoded, readTimeout); | ||
if (frameTime > 0) { | ||
return converter.convert(decoded); | ||
} else { | ||
throw new IOException("Frame not read: " + frameTime); | ||
} | ||
} catch (IOException e) { | ||
throw new Exception(e.getMessage(), e); | ||
} | ||
} | ||
|
||
@Override | ||
public void release() throws Exception { | ||
} | ||
} |
99 changes: 99 additions & 0 deletions
99
core/src/main/java/edu/wpi/grip/core/sources/CSUsbCameraFrameGrabber.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package edu.wpi.grip.core.sources; | ||
|
||
import edu.wpi.cscore.CameraServerJNI; | ||
import edu.wpi.cscore.UsbCamera; | ||
import org.bytedeco.javacpp.Loader; | ||
import org.bytedeco.javacpp.opencv_core.Mat; | ||
import org.bytedeco.javacv.Frame; | ||
import org.bytedeco.javacv.FrameConverter; | ||
import org.bytedeco.javacv.FrameGrabber; | ||
import org.bytedeco.javacv.OpenCVFrameConverter; | ||
|
||
import java.io.IOException; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
// This is here because FrameGrabber has an exception called Exception which triggers PMD | ||
@SuppressWarnings({"PMD.AvoidThrowingRawExceptionTypes", "all"}) | ||
public class CSUsbCameraFrameGrabber extends FrameGrabber { | ||
|
||
private static Exception loadingException = null; | ||
|
||
private final int deviceId; | ||
private final double readTimeout; | ||
|
||
private Mat decoded = null; | ||
private FrameConverter<Mat> converter = new OpenCVFrameConverter.ToMat(); | ||
|
||
private JavaCvSink javaCvSink; | ||
private UsbCamera usbCamera; | ||
|
||
public CSUsbCameraFrameGrabber(int deviceId, int readTimeout, TimeUnit unit) { | ||
super(); | ||
this.deviceId = deviceId; | ||
this.readTimeout = TimeUnit.MILLISECONDS.convert(readTimeout, unit) / 1000.0; | ||
} | ||
|
||
public static void tryLoad() throws Exception { | ||
if (loadingException != null) { | ||
throw loadingException; | ||
} else { | ||
try { | ||
Loader.load(org.bytedeco.javacpp.opencv_highgui.class); | ||
CameraServerJNI.Helper.setExtractOnStaticLoad(false); | ||
CameraServerJNI.forceLoad(); | ||
} catch (Throwable t) { | ||
throw loadingException = new Exception("Failed to load " + CSUsbCameraFrameGrabber.class, t); | ||
} | ||
} | ||
} | ||
|
||
public UsbCamera getCamera() { | ||
return this.usbCamera; | ||
} | ||
|
||
@Override | ||
public void start() throws Exception { | ||
javaCvSink = new JavaCvSink("InputCamera"); | ||
usbCamera = new UsbCamera("InputUsb", deviceId); | ||
javaCvSink.setSource(usbCamera); | ||
} | ||
|
||
public void stop() throws Exception { | ||
if (javaCvSink != null) { | ||
javaCvSink.close(); | ||
} | ||
|
||
if (usbCamera != null) { | ||
usbCamera.close(); | ||
} | ||
|
||
if (decoded != null) { | ||
decoded.close(); | ||
} | ||
} | ||
|
||
@Override | ||
public void trigger() throws Exception { | ||
} | ||
|
||
@Override | ||
public Frame grab() throws Exception { | ||
try { | ||
if (decoded == null) { | ||
decoded = new Mat(); | ||
} | ||
long frameTime = javaCvSink.grabFrame(decoded, readTimeout); | ||
if (frameTime > 0) { | ||
return converter.convert(decoded); | ||
} else { | ||
throw new IOException("Frame not read: " + frameTime); | ||
} | ||
} catch (IOException e) { | ||
throw new Exception(e.getMessage(), e); | ||
} | ||
} | ||
|
||
@Override | ||
public void release() throws Exception { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters