Streaming a webcam at 60 fps
hi everybody
i have a problem with capturing a webcam (logitech c922) video stream. the webcam provides a stream at 60fps at a resolution of 720p.
right now i initialize a capture convert it from BGR2toGray send the frame to an ImageView object.
here is my code.
public void startCapture(ImageView realView, int frameWidth, int frameHeight){
moveCoordSystemToCenter(frameWidth/2, frameHeight/2);
if (!this.capture.isOpened()){
capture.open(0);
int fourcc = VideoWriter.fourcc('M', 'J', 'P', 'G');
capture.set(Videoio.CAP_PROP_FOURCC, fourcc);
capture.set(Videoio.CAP_PROP_FRAME_WIDTH,1280);
capture.set(Videoio.CAP_PROP_FRAME_HEIGHT,720);
System.out.println(capture.get(Videoio.CAP_PROP_FRAME_WIDTH));
TimerTask frameGrabber = new TimerTask(){
public void run(){
long time = System.currentTimeMillis();
Image tmp = grabFrame();
Platform.runLater(new Runnable(){
int Counter = 1;
long res = 1;
public void run(){
realView.setImage(tmp);
res = res + System.currentTimeMillis()-time;
System.out.println("Fps = " + 1000 / (res/Counter)) ;
Counter++;
}
});
}
};
this.timer = new Timer();
timer.scheduleAtFixedRate(frameGrabber, 0, 1); // has no effect
}
else
{
if (this.timer != null){
this.timer.cancel();
this.timer = null;
}
this.capture.release();
}
}
private Image grabFrame() {
Image imageToShow = null;
Mat frame = new Mat();
if ( this.capture.isOpened()){
try
{
this.capture.read(frame);
if (!frame.empty()){
imageToShow = mat2Image(frame);
}
}
catch (Exception e){
}
}
return imageToShow;
}
private Image mat2Image (Mat frame){
MatOfByte buffer = new MatOfByte();
Mat frameGray = new Mat();
Imgproc.cvtColor(frame, frameGray, Imgproc.COLOR_BGR2GRAY);
Imgcodecs.imencode(".png",frameGray, buffer);
return new Image (new ByteArrayInputStream(buffer.toArray()));
}
i use opencv3.1 Java, Eclipse neon, JavaFx
my problem is i can´t get more than 30 fps out of this thing i Need the 60 fps for my application. to set the codec to M J P G brings up speed from 15 fps to 30fps and MJPG is the only Codec which holds my resolution all others fall back to 640 / 480
so i play with some formats of video- and Picture codecs stuff.
Jpg an Png is simular stable at 30 fps bmp is a little faster but not so stable 28- 36 fps
i already tried to set the fps via capture.set(CAP_PROP_FPS,60) which has no effect for values above 30.
I read some stuff about ffmpeg but i don´t understand how the pipeline should work.
can anyone help.
greetz
i can only guess (no java here), but i'd try first to profile the
mat2Image()
function, which is most likely your bottleneck. do you have to use javafx here ? encoding an image to png is expensive, and your imageview also has to decode it again, seems to be pretty wasteful.also, you might need to process at 60 fps, but do you need to draw at the same framerate ?