I have a task to write program with 1 camera, 1 kinect, a lot of video processing and then controlling a robot.
This code just shows captured video frames without processing, but I only have 20 frames/s approximately. The same simple frames displaying program in Matlab gave me 29 frames/s. I was hoping that I will win some speed in Java, but it doesn't look like that, am I doing sth wrong? If not, how I can increase the speed?
public class Video implements Runnable {
//final int INTERVAL=1000;///you may use interval
IplImage image;
CanvasFrame canvas = new CanvasFrame("Web Cam");
public Video() {
canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
}
#Override
public void run() {
FrameGrabber grabber = new VideoInputFrameGrabber(0); // 1 for next camera
int i=0;
try {
grabber.start();
IplImage img;
int g = 0;
long start2 = 0;
long stop = System.nanoTime();
long diff = 0;
start2 = System.nanoTime();
while (true) {
img = grabber.grab();
if (img != null) {
// cvFlip(img, img, 1);// l-r = 90_degrees_steps_anti_clockwise
// cvSaveImage((i++)+"-aa.jpg", img);
// show image on window
canvas.showImage(img);
}
g++;
if(g%200 == 0){
stop = System.nanoTime();
diff = stop - start2;
double d = (float)diff;
double dd = d/1000000000;
double dv = dd/g;
System.out.printf("frames = %.2f\n",1/dv);
}
//Thread.sleep(INTERVAL);
}
} catch (Exception e) {
}
}
public static void main(String[] args) {
Video gs = new Video();
Thread th = new Thread(gs);
th.start();
}
}
Related
I'm new to coding environment, I'm working in an imaging processing project - I have a video file of n size and I'm trying to find a mean and standard deviation of (Height, width and number of frames)that file . the image file(imgfile_500) is in MAT
here is my code
public class Image_conv {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
String filePath = "C:\\Video_500.h264";
if (!Paths.get(filePath).toFile().exists()){
System.out.println("File " + filePath + " does not exist!");
return;
}
VideoCapture video500 = new VideoCapture(filePath);
if (!video500.isOpened()) {
System.out.println("Error! video500 can't be opened!");
return;
}
int ntime=20;
int fps= 60;
int ds_fac=4;
int nf = (ntime*fps);
int wd_ds = 480/ds_fac;
int hg_ds = 640/ds_fac;
int vsize = wd_ds*hg_ds*nf;
Mat frame = new Mat(480,640,CvType.CV_64FC3);
Mat frame500 = new Mat(480,640,CvType.CV_64FC3);
Mat imgfile_500 = new Mat();
if (video500.isOpened()) {
while(true){
if (video500.read(frame))
{
Imgproc.cvtColor(frame, frame500, Imgproc.COLOR_RGB2GRAY);
//System.out.println(frame500.size());
Imgproc.pyrDown( frame500, frame500, new Size( frame500.cols()/2, frame500.rows()/2 ) );
Imgproc.pyrDown( frame500, frame500, new Size( frame500.cols()/2, frame500.rows()/2 ) );
// Imgcodecs.imwrite(i+"led500.jpg", frame500);
// Push a Mat back into MatVector
imgfile_500.push_back(frame500);
}else break;
}
}
//System.out.println(imgfile_500.size());
}
}
my question is about : how to record and save with the time specified like after two hours this app must done record and save in one folder.
public class per1 {
public static void main(String[] args) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Scanner scan = new Scanner(System.in);
VideoCapture camera = new VideoCapture(0);
String cc = String.valueOf(camera.get(Videoio.CAP_PROP_FOURCC));
int fps = (int) camera.get(Videoio.CAP_PROP_FPS);
int width = (int) camera.get(Videoio.CAP_PROP_FRAME_WIDTH);
int height = (int) camera.get(Videoio.CAP_PROP_FRAME_HEIGHT);
final Size frameSize = new Size((int) camera.get(Videoio.CAP_PROP_FRAME_WIDTH), (int) camera.get(Videoio.CAP_PROP_FRAME_HEIGHT));
VideoWriter save = new VideoWriter("D:/video.mpg", Videoio.CAP_PROP_FOURCC, fps, frameSize, true);
if (camera.isOpened()) {
System.out.println("ON");
Mat framecam = new Mat();
boolean cekframe = camera.read(framecam);
System.out.println("cekframe " + cekframe);
try {
while (cekframe) {
camera.read(framecam);
save.write(framecam);
}
Thread.sleep(4000);
} catch (Exception e) {
System.out.println("OFF \n" + e);
}
camera.release();
save.release();
System.exit(1);
System.out.println("DOne");
}
}
I am using this code https://stackoverflow.com/questions/23432398/audio-recorder-in-android-process-the-audio-bytes to capture the mic audio but I am writing the data to a ByteArrayOutputStream. After I finish the record I want to demodule the signal captured by using Goertzel Algorithm. The FSK signal consists out of 2 frequencies, 800Hz for '1' and 400Hz for '0' each bit is moduled using 100 samples. I am using this class of Goertzel: http://courses.cs.washington.edu/courses/cse477/projectwebs04sp/cse477m/code/public/Goertzel.java I am trying to use a bin size of 150.
Here is what I try to do:
the code, after I finish the recording:
private void stopRecording()
{
if(recorder != null)
{
isRecording= false;
recorder.stop();
recorder.release();
recorder = null;
recordingThread = null;
int BlockSize = 150;
float HighToneFrequency = 800;
float LowToneFrequency = 400;
byte[] byteArrayData = ByteArrayAudioData.toByteArray();
/*final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
8000, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, byteArrayData.length,
AudioTrack.MODE_STATIC);
audioTrack.write(byteArrayData, 0, byteArrayData.length);
audioTrack.play();*/
double[] daOriginalSine = convertSample2Sine(byteArrayData);
int i = 0;
while(i < daOriginalSine.length)
{
double t1 = testSpecificFrequency(i, HighToneFrequency,BlockSize, daOriginalSine);
double t2 = testSpecificFrequency(i, LowToneFrequency,BlockSize, daOriginalSine);
i+=BlockSize;
}
}
}
And the function testSpecificFrequency:
private double testSpecificFrequency(int startIndex, float ToneFreq, int BlockSize, double[] sample)
{
Goertzel g = new Goertzel(RECORDER_SAMPLERATE, ToneFreq, BlockSize, false);
g.initGoertzel();
for(int j=startIndex ; j<startIndex+BlockSize ; j++)
{
g.processSample(sample[j]);
}
double res= Math.sqrt(g.getMagnitudeSquared());
return res;
}
I just tried to see what will be the results, by sending 800Hz to the constructor and afterwars sending 400Hz,don't really know how to proceed from this point =\
Any ideas?
I am trying to delay my live mjpeg video feed by 10 seconds.
I am trying to modify this code and but I am unable to incorporate the mjpg url.
It keeps on saying 'The constructor CaptureMJPEG(String, int, int, int) is undefined' when I try to put the url in.
The original line said:
capture = new CaptureMJPEG(this, capture_xsize, capture_ysize, capture_frames);
I changed it to:
capture = new CaptureMJPEG ("http:/url.com/feed.mjpg", capture_xsize, capture_ysize, capture_frames);
import processing.video.*;
import it.lilik.capturemjpeg.*;
Capture myCapture;
CaptureMJPEG capture;
VideoBuffer monBuff;
int display_xsize = 800; // display size
int display_ysize = 600;
int capture_xsize = 320; // capture size
int capture_ysize = 240;
int delay_time = 10; // delay in seconds
int capture_frames = 20; // capture frames per second
void setup() {
size(display_xsize,display_ysize, P3D);
// Warning: VideoBuffer must be initiated BEFORE capture- or movie-events start
monBuff = new VideoBuffer(delay_time*capture_frames, capture_xsize,capture_ysize);
capture = new CaptureMJPEG ("http:/url.com/feed.mjpg", capture_xsize, capture_ysize, capture_frames);
}
void captureEvent(Capture capture) {
capture.read();
monBuff.addFrame( capture );
}
void draw() {
PImage bufimg = monBuff.getFrame();
PImage tmpimg = createImage(bufimg.width,bufimg.height,RGB);
tmpimg.copy(bufimg,0,0,bufimg.width,bufimg.height,0,0,bufimg.width,bufimg.height);
tmpimg.resize(display_xsize,display_ysize);
image( tmpimg, 0, 0 );
}
class VideoBuffer
{
PImage[] buffer;
int inputFrame = 0;
int outputFrame = 0;
int frameWidth = 0;
int frameHeight = 0;
/*
parameters:
frames - the number of frames in the buffer (fps * duration)
width - the width of the video
height - the height of the video
*/
VideoBuffer( int frames, int width, int height )
{
buffer = new PImage[frames];
for(int i = 0; i < frames; i++)
{
this.buffer[i] = new PImage(width, height);
}
this.inputFrame = frames - 1;
this.outputFrame = 0;
this.frameWidth = width;
this.frameHeight = height;
}
// return the current "playback" frame.
PImage getFrame()
{
int frr;
if(this.outputFrame>=this.buffer.length)
frr = 0;
else
frr = this.outputFrame;
return this.buffer[frr];
}
// Add a new frame to the buffer.
void addFrame( PImage frame )
{
// copy the new frame into the buffer.
System.arraycopy(frame.pixels, 0, this.buffer[this.inputFrame].pixels, 0, this.frameWidth * this.frameHeight);
// advance the input and output indexes
this.inputFrame++;
this.outputFrame++;
// wrap the values..
if(this.inputFrame >= this.buffer.length)
{
this.inputFrame = 0;
}
if(this.outputFrame >= this.buffer.length)
{
this.outputFrame = 0;
}
}
}
Reading the reference docs:
https://bytebucket.org/nolith/capturemjpeg/wiki/api/index.html
These are the only two constructors:
CaptureMJPEG(PApplet parent, String url)
Creates a CaptureMJPEG without HTTP Auth credential
CaptureMJPEG(PApplet parent, String url, String username, String password)
Creates a CaptureMJPEG with HTTP Auth credential
So the first argument must always point to your processing applet instance. So
capture = new CaptureMJPEG (this, "http:/url.com/feed.mjpg", capture_xsize, capture_ysize, capture_frames);
I'm trying to implement animated textures into an OpenGL game seamlessly. I made a generic ImageDecoder class to translate any BufferedImage into a ByteBuffer. It works perfectly for now, though it doesn't load animated images.
I'm not trying to load an animated image as an ImageIcon. I need the BufferedImage to get an OpenGL-compliant ByteBuffer.
How can I load every frames as a BufferedImage array in an animated image ?
On a similar note, how can I get the animation rate / period ?
Does Java handle APNG ?
The following code is an adaption from my own implementation to accommodate the "into array" part.
The problem with gifs is: There are different disposal methods which have to be considered, if you want this to work with all of them. The code below tries to compensate for that. For example there is a special implementation for "doNotDispose" mode, which takes all frames from start to N and paints them on top of each other into a BufferedImage.
The advantage of this method over the one posted by chubbsondubs is that it does not have to wait for the gif animation delays, but can be done basically instantly.
BufferedImage[] array = null;
ImageInputStream imageInputStream = ImageIO.createImageInputStream(new ByteArrayInputStream(data)); // or any other source stream
Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(imageInputStream);
while (imageReaders.hasNext())
{
ImageReader reader = (ImageReader) imageReaders.next();
try
{
reader.setInput(imageInputStream);
frames = reader.getNumImages(true);
array = new BufferedImage[frames];
for (int frameId : frames)
{
int w = reader.getWidth(0);
int h = reader.getHeight(0);
int fw = reader.getWidth(frameId);
int fh = reader.getHeight(frameId);
if (h != fh || w != fw)
{
GifMeta gm = getGifMeta(reader.getImageMetadata(frameId));
// disposalMethodNames: "none", "doNotDispose","restoreToBackgroundColor","restoreToPrevious",
if ("doNotDispose".equals(gm.disposalMethod))
{
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) image.getGraphics();
for (int f = 0; f <= frameId; f++)
{
gm = getGifMeta(reader.getImageMetadata(f));
if ("doNotDispose".equals(gm.disposalMethod))
{
g.drawImage(reader.read(f), null, gm.imageLeftPosition, gm.imageTopPosition);
}
else
{
// XXX "Unimplemented disposalMethod (" + getName() + "): " + gm.disposalMethod);
}
}
g.dispose();
}
else
{
image = reader.read(frameId);
// XXX "Unimplemented disposalMethod (" + getName() + "): " + gm.disposalMethod;
}
}
else
{
image = reader.read(frameId);
}
if (image == null)
{
throw new NullPointerException();
}
array[frame] = image;
}
}
finally
{
reader.dispose();
}
}
return array;
private final static class GifMeta
{
String disposalMethod = "none";
int imageLeftPosition = 0;
int imageTopPosition = 0;
int delayTime = 0;
}
private GifMeta getGifMeta(IIOMetadata meta)
{
GifMeta gm = new GifMeta();
final IIOMetadataNode gifMeta = (IIOMetadataNode) meta.getAsTree("javax_imageio_gif_image_1.0");
NodeList childNodes = gifMeta.getChildNodes();
for (int i = 0; i < childNodes.getLength(); ++i)
{
IIOMetadataNode subnode = (IIOMetadataNode) childNodes.item(i);
if (subnode.getNodeName().equals("GraphicControlExtension"))
{
gm.disposalMethod = subnode.getAttribute("disposalMethod");
gm.delayTime = Integer.parseInt(subnode.getAttribute("delayTime"));
}
else if (subnode.getNodeName().equals("ImageDescriptor"))
{
gm.imageLeftPosition = Integer.parseInt(subnode.getAttribute("imageLeftPosition"));
gm.imageTopPosition = Integer.parseInt(subnode.getAttribute("imageTopPosition"));
}
}
return gm;
}
I don't think Java supports APNG by default, but you can use an 3rd party library to parse it:
http://code.google.com/p/javapng/source/browse/trunk/javapng2/src/apng/com/sixlegs/png/AnimatedPngImage.java?r=300
That might be your easiest method. As for getting the frames from an animated gif you have to register an ImageObserver:
new ImageIcon( url ).setImageObserver( new ImageObserver() {
public void imageUpdate( Image img, int infoFlags, int x, int y, int width, int height ) {
if( infoFlags & ImageObserver.FRAMEBITS == ImageObserver.FRAMEBITS ) {
// another frame was loaded do something with it.
}
}
});
This loads asynchronously on another thread so imageUpdate() won't be called immediately. But it will be called for each frame as it parses it.
http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/image/ImageObserver.html