it-swarm-eu.dev

Jaký je nejlepší způsob snímání obrazů ze živého videozařízení pro použití aplikací založených na jazyku Java?

Hledám problém zpracování obrazu pro detekci některých scénářů v reálném čase. Mým cílem je, aby živé video přišlo v mém kódu Java nějakým způsobem .

Jsem obeznámen s Java Media Framework a bohužel si myslím, že to můžeme považovat za skutečně mrtvé API. Také jsem obeznámen s boxy osy a, i když se mi líbí jejich řešení, ocenil bych jakoukoli kritickou zpětnou vazbu o mých specifických bodech zájmu.

Takto definuji "nejlepší" pro účely této diskuse:

  • Latence - pokud ovládám kameru pomocí tohoto video streamu, chtěl bych, pokud je to možné, zachovat latenci za okruhy kratší než 100 milisekund. To je měřeno jako doba mezi mým kontrolním vstupem a časem, kdy vidím viditelnou změnu. EDIT o něco později: další věc, kterou je třeba mít na paměti, je, že ovládání kamery je pravděpodobně kombinací manuálních a automatických (spouštěčů událostí). Tyto fotografie musíme vidět hned, i když je vysoce kvalitní krmivo archivováno odděleně.
  • Cena - zdarma/open source je lepší než ne svobodný.
  • Nastavitelné parametry kodeků - Musím být schopen naladit kodek pro určité situace. Někdy je vysokorychlostní tok s nízkým rozlišením ve skutečnosti snazší zpracovat.
  • "Integrace" s jazykem Java - kolik je problém spojit toto řešení s mým kódem? Posílám pakety přes soket? Zasažení adres URL? Instalace kombinace Direct3D/JNI?
  • Windows/Linux/obojí? - Chtěl bych dát přednost operačnímu systému agnostic řešení, protože musím dodat na několik chutí OS, ale může být řešení, které je optimální pro jednoho, ale ne druhého.

POZNÁMKA: Jsem si vědom jiných kodeků pro snímání obrazu a videa, což není předmětem této otázky. Jsem specificky ne zajímající se o streamování API (např. MPEG4) v důsledku ztráty přesnosti rámce. Nicméně, pokud existuje řešení mé otázky, která přináší další rám-přesný datový proud, prosím, zvonění dovnitř.

Následné kroky k této otázce: v tomto bodě jsem silně nakloněn kupovat spotřebiče, jako jsou video kodéry Axis spíše než snažit se přímo zachytit video v softwaru nebo v počítači. Nicméně, pokud někdo má alternativy, rád bych je slyšel.

23
Bob Cross

Tato implementace JavaCV funguje dobře.

KÓD:

import com.googlecode.javacv.OpenCVFrameGrabber;

import com.googlecode.javacv.cpp.opencv_core.IplImage;
import static com.googlecode.javacv.cpp.opencv_highgui.*;

public class CaptureImage {
    private static void captureFrame() {
        // 0-default camera, 1 - next...so on
        final OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
        try {
            grabber.start();
            IplImage img = grabber.grab();
            if (img != null) {
                cvSaveImage("capture.jpg", img);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        captureFrame();
    }
}

K dispozici je také post na prohlížení živého videa z kamery .A konfigurace pro JavaCV:

Myslím, že to splní vaše požadavky.

7
gtiwari333

FMJ může určitě zachytit video a proměnit ho v rámce MJPEG.

3
Ken Larson

Pokud jde o mrtvotu JMF, víte o implementaci FMJ ? Nevím, zda se kvalifikuje jako "nejlepší" řešení, ale pravděpodobně stojí za to přidat do diskuse.

2
Greg Mattes

Níže je ukázána velmi jednoduchá implementace pomocí Marvin Framework . Pomocí Marvinu můžete snadno přidat zpracování videa v reálném čase. 

import javax.swing.JFrame;
import marvin.gui.MarvinImagePanel;
import marvin.image.MarvinImage;
import marvin.video.MarvinJavaCVAdapter;
import marvin.video.MarvinVideoInterface;

public class SimpleVideoTest extends JFrame implements Runnable{

    private MarvinVideoInterface    videoAdapter;
    private MarvinImage             image;
    private MarvinImagePanel        videoPanel;

    public SimpleVideoTest(){
        super("Simple Video Test");

        // Create the VideoAdapter and connect to the camera
        videoAdapter = new MarvinJavaCVAdapter();
        videoAdapter.connect(0);

        // Create VideoPanel
        videoPanel = new MarvinImagePanel();
        add(videoPanel);

        // Start the thread for requesting the video frames 
        new Thread(this).start();

        setSize(800,600);
        setVisible(true);
    }

    public static void main(String[] args) {
        SimpleVideoTest t = new SimpleVideoTest();
        t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    @Override
    public void run() {
        while(true){
            // Request a video frame and set into the VideoPanel
            image = videoAdapter.getFrame();
            videoPanel.setImage(image);
        }
    }
}

Další příklad použití více algoritmů pro zpracování videa v reálném čase.

Toto je moje implementace JavaCV s výstupem videa s vysokým rozlišením a bez znatelného poklesu rychlosti snímku než jiná řešení (pouze když moje webová kamera opětovně zaostří, zaznamenám mírný pokles, jen na chvíli).

import Java.awt.image.BufferedImage;
import Java.io.File;

import javax.swing.JFrame;

import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.OpenCVFrameRecorder;
import com.googlecode.javacv.cpp.opencv_core.IplImage;

public class Webcam implements Runnable {

    IplImage image;
    static CanvasFrame frame = new CanvasFrame("Web Cam");
    public static boolean running = false;

    public Webcam()
    {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    @Override
    public void run()
    {
        try
        {
            grabber.setImageWidth(800);
            grabber.setImageHeight(600);
            grabber.start();
            while (running)
            {
                IplImage cvimg = grabber.grab();
                BufferedImage image;
                if (cvimg != null)
                {
                    // opencv_core.cvFlip(cvimg, cvimg, 1); // mirror
                    // show image on window
                    image = cvimg.getBufferedImage();
                    frame.showImage(image);
                }
            }
            grabber.stop();
            frame.dispose();
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void main(String... args)
    {
        Webcam webcam = new Webcam();
        webcam.start();
    }

    public void start()
    {
        new Thread(this).start();
        running = true;
    }

    public void stop()
    {
        running = false;
    }
}
0
syb0rg