<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    amp@java

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      99 隨筆 :: 0 文章 :: 228 評論 :: 0 Trackbacks
    JMF太老了,各種問題得不到解決,Oracle也沒再升級過,如果能找到新東西,最好能把它扔掉。
    最近OpenCV比較火,還有人用Java封裝了OpenCV,成立了JavaCV項目,通過改造VideoInput這個基于C語言的項目,能夠用Java來調用攝像頭,JMF可以扔掉了。
    如果想測試,非常簡單,把那些編譯好的jar文件放入Build Path即可,如果是在Windows X86環境下,則只需要把帶Window和x86的包,以及不帶有任何平臺信息包放到Build Path即可。測試的程序可以用項目主頁上面那個Demo。代碼如下:

    import java.io.File;
    import java.net.URL;
    import org.bytedeco.javacv.*;
    import org.bytedeco.javacpp.*;
    import org.bytedeco.javacpp.indexer.*;
    import static org.bytedeco.javacpp.opencv_core.*;
    import static org.bytedeco.javacpp.opencv_imgproc.*;
    import static org.bytedeco.javacpp.opencv_calib3d.*;
    import static org.bytedeco.javacpp.opencv_objdetect.*;

    public class Demo {
        
    public static void main(String[] args) throws Exception {
            String classifierName 
    = null;
            
    if (args.length > 0) {
                classifierName 
    = args[0];
            } 
    else {
                URL url 
    = new URL("https://raw.github.com/Itseez/opencv/2.4/data/haarcascades/haarcascade_frontalface_alt.xml");
                File file 
    = Loader.extractResource(url, null"classifier"".xml");
                file.deleteOnExit();
                classifierName 
    = file.getAbsolutePath();
            }

            
    // Preload the opencv_objdetect module to work around a known bug.
            Loader.load(opencv_objdetect.class);

            
    // We can "cast" Pointer objects by instantiating a new object of the desired class.
            CvHaarClassifierCascade classifier = new CvHaarClassifierCascade(cvLoad(classifierName));
            
    if (classifier.isNull()) {
                System.err.println(
    "Error loading classifier file \"" + classifierName + "\".");
                System.exit(
    1);
            }

            
    // The available FrameGrabber classes include OpenCVFrameGrabber (opencv_highgui),
            
    // DC1394FrameGrabber, FlyCaptureFrameGrabber, OpenKinectFrameGrabber,
            
    // PS3EyeFrameGrabber, VideoInputFrameGrabber, and FFmpegFrameGrabber.
            FrameGrabber grabber = FrameGrabber.createDefault(0);
            grabber.start();

            
    // FAQ about IplImage:
            
    // - For custom raw processing of data, createBuffer() returns an NIO direct
            
    //   buffer wrapped around the memory pointed by imageData, and under Android we can
            
    //   also use that Buffer with Bitmap.copyPixelsFromBuffer() and copyPixelsToBuffer().
            
    // - To get a BufferedImage from an IplImage, we may call getBufferedImage().
            
    // - The createFrom() factory method can construct an IplImage from a BufferedImage.
            
    // - There are also a few copy*() methods for BufferedImage<->IplImage data transfers.
            IplImage grabbedImage = grabber.grab();
            
    int width  = grabbedImage.width();
            
    int height = grabbedImage.height();
            IplImage grayImage    
    = IplImage.create(width, height, IPL_DEPTH_8U, 1);
            IplImage rotatedImage 
    = grabbedImage.clone();

            
    // Objects allocated with a create*() or clone() factory method are automatically released
            
    // by the garbage collector, but may still be explicitly released by calling release().
            
    // You shall NOT call cvReleaseImage(), cvReleaseMemStorage(), etc. on objects allocated this way.
            CvMemStorage storage = CvMemStorage.create();

            
    // The OpenCVFrameRecorder class simply uses the CvVideoWriter of opencv_highgui,
            
    // but FFmpegFrameRecorder also exists as a more versatile alternative.
            FrameRecorder recorder = FrameRecorder.createDefault("output.avi", width, height);
            recorder.start();

            
    // CanvasFrame is a JFrame containing a Canvas component, which is hardware accelerated.
            
    // It can also switch into full-screen mode when called with a screenNumber.
            
    // We should also specify the relative monitor/camera response for proper gamma correction.
            CanvasFrame frame = new CanvasFrame("Some Title", CanvasFrame.getDefaultGamma()/grabber.getGamma());

            
    // Let's create some random 3D rotation
            CvMat randomR = CvMat.create(33), randomAxis = CvMat.create(31);
            
    // We can easily and efficiently access the elements of matrices and images
            
    // through an Indexer object with the set of get() and put() methods.
            DoubleIndexer Ridx = randomR.createIndexer(), axisIdx = randomAxis.createIndexer();
            axisIdx.put(
    0, (Math.random()-0.5)/4, (Math.random()-0.5)/4, (Math.random()-0.5)/4);
            cvRodrigues2(randomAxis, randomR, 
    null);
            
    double f = (width + height)/2.0;  Ridx.put(02, Ridx.get(02)*f);
                                              Ridx.put(
    12, Ridx.get(12)*f);
            Ridx.put(
    20, Ridx.get(20)/f); Ridx.put(21, Ridx.get(21)/f);
            System.out.println(Ridx);

            
    // We can allocate native arrays using constructors taking an integer as argument.
            CvPoint hatPoints = new CvPoint(3);

            
    while (frame.isVisible() && (grabbedImage = grabber.grab()) != null) {
                cvClearMemStorage(storage);

                
    // Let's try to detect some faces! but we need a grayscale image
                cvCvtColor(grabbedImage, grayImage, CV_BGR2GRAY);
                CvSeq faces 
    = cvHaarDetectObjects(grayImage, classifier, storage,
                        
    1.13, CV_HAAR_DO_CANNY_PRUNING);
                
    int total = faces.total();
                
    for (int i = 0; i < total; i++) {
                    CvRect r 
    = new CvRect(cvGetSeqElem(faces, i));
                    
    int x = r.x(), y = r.y(), w = r.width(), h = r.height();
                    cvRectangle(grabbedImage, cvPoint(x, y), cvPoint(x
    +w, y+h), CvScalar.RED, 1, CV_AA, 0);

                    
    // To access or pass as argument the elements of a native array, call position() before.
                    hatPoints.position(0).x(x-w/10)   .y(y-h/10);
                    hatPoints.position(
    1).x(x+w*11/10).y(y-h/10);
                    hatPoints.position(
    2).x(x+w/2)    .y(y-h/2);
                    cvFillConvexPoly(grabbedImage, hatPoints.position(
    0), 3, CvScalar.GREEN, CV_AA, 0);
                }

                
    // Let's find some contours! but first some thresholding
                cvThreshold(grayImage, grayImage, 64255, CV_THRESH_BINARY);

                
    // To check if an output argument is null we may call either isNull() or equals(null).
                CvSeq contour = new CvSeq(null);
                cvFindContours(grayImage, storage, contour, Loader.sizeof(CvContour.
    class),
                        CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
                
    while (contour != null && !contour.isNull()) {
                    
    if (contour.elem_size() > 0) {
                        CvSeq points 
    = cvApproxPoly(contour, Loader.sizeof(CvContour.class),
                                storage, CV_POLY_APPROX_DP, cvContourPerimeter(contour)
    *0.020);
                        cvDrawContours(grabbedImage, points, CvScalar.BLUE, CvScalar.BLUE, 
    -11, CV_AA);
                    }
                    contour 
    = contour.h_next();
                }

                cvWarpPerspective(grabbedImage, rotatedImage, randomR);

                frame.showImage(rotatedImage);
                recorder.record(rotatedImage);
            }
            frame.dispose();
            recorder.stop();
            grabber.stop();
        }
    }

    不過這個代碼包含了人臉識別,而人臉識別需要下載一個xml文件來定義識別的模式,代碼中那個xml鏈接下載下來的xml文件是會解析出錯的,可能是那個版本比較新,JavaCV還沒跟上,所以解析不了。經過搜索,發現有人提供了一個老版本的xml文件,能夠順利解析,會在視頻中把人臉用綠框框住。
    所以,把代碼中的
    URL url = new URL("https://raw.github.com/Itseez/opencv/2.4/data/haarcascades/haarcascade_frontalface_alt.xml");
    改為
    URL url = new URL("https://raw.githubusercontent.com/Danukeru/FOUCAM/master/haarcascade_frontalface.xml");
    即可順利運行。
    運行后發現很多線條和框框,畫面也是斜的,如下圖所示:


    這是用來演示JavaCV對圖像的處理,如果對這些沒有興趣,可以簡單地用以下代碼來顯示攝像頭的圖像:

    import org.bytedeco.javacpp.opencv_core.IplImage;
    import org.bytedeco.javacv.CanvasFrame;
    import org.bytedeco.javacv.FrameGrabber;

    public class Demo3 {
        
    public static void main(String[] args) throws Exception {


            
    // The available FrameGrabber classes include OpenCVFrameGrabber (opencv_highgui),
            
    // DC1394FrameGrabber, FlyCaptureFrameGrabber, OpenKinectFrameGrabber,
            
    // PS3EyeFrameGrabber, VideoInputFrameGrabber, and FFmpegFrameGrabber.
            FrameGrabber grabber = FrameGrabber.createDefault(1);
            grabber.start();

            
    // FAQ about IplImage:
            
    // - For custom raw processing of data, createBuffer() returns an NIO direct
            
    //   buffer wrapped around the memory pointed by imageData, and under Android we can
            
    //   also use that Buffer with Bitmap.copyPixelsFromBuffer() and copyPixelsToBuffer().
            
    // - To get a BufferedImage from an IplImage, we may call getBufferedImage().
            
    // - The createFrom() factory method can construct an IplImage from a BufferedImage.
            
    // - There are also a few copy*() methods for BufferedImage<->IplImage data transfers.
            IplImage grabbedImage = grabber.grab();
            CanvasFrame frame 
    = new CanvasFrame("Some Title", CanvasFrame.getDefaultGamma()/grabber.getGamma());

            
    while (frame.isVisible() && (grabbedImage = grabber.grab()) != null) {


                frame.showImage(grabbedImage);
                
            }
            frame.dispose();
            
            grabber.stop();
        }
    }

    如下圖所示:


    當然,這樣只是把攝像頭的圖像顯示出來,沒有任何用處,所以如果你想要處理其中的圖像,就需要增加代碼。例如,如果你需要截取攝像頭的圖像做進一步處理,就可以通過IplImage的getBufferedImage()方法來得到BufferedImage,然后再處理這個BufferedImage,例如解析二維碼。

    不過,JavaCV默認是把圖像顯示在一個CanvasFrame對象中,這個對象繼承了JFrame,所以只能用作頂層窗口,不能嵌入到其他窗口中。為了能夠把它嵌入到其他窗口,可以修改一下代碼,繼承一個Canvas對象:
    public class ImageCanvas extends Canvas {
            
        
    private BufferedImage img;
        
        @Override 
    public void update(Graphics g) {
            paint(g);
        }
        
        @Override 
    public void paint(Graphics g) {
            
            
    // Calling BufferStrategy.show() here sometimes throws
            
    // NullPointerException or IllegalStateException,
            
    // but otherwise seems to work fine.
            try {
                
    if (getWidth() <= 0 || getHeight() <= 0) {
                    
    return;
                }
                BufferStrategy strategy 
    = getBufferStrategy();
                
    do {
                    
    do {
                        g 
    = strategy.getDrawGraphics();
                        
    if (img != null) {                        
                            g.drawImage(img, 
    00, getWidth(), getHeight(), null);
                        }
                        g.dispose();
                    } 
    while (strategy.contentsRestored());
                    strategy.show();
                } 
    while (strategy.contentsLost());
            } 
    catch (NullPointerException e) {
            } 
    catch (IllegalStateException e) { }
        }

        
        
    public BufferedImage getImg() {
            
    return img;
        }

        
    public void setImg(BufferedImage img) {
            
    this.img = img;        
            repaint();                       
        }


        
    public void init(){
            
    new Thread(){
                
    public void run(){
                    
    boolean error = true;
                    
    while(error){
                        
    try{
                            error 
    = false;
                            createBufferStrategy(
    2);
                        }
    catch(IllegalStateException e){
                            error 
    = true;
                            
    try {
                                Thread.sleep(
    100);
                            } 
    catch (InterruptedException e1) {
                                
    // TODO Auto-generated catch block
                                e1.printStackTrace();
                            }
                        }
                    }
                }
            }.start();
        }
    使用的時候就把這個ImageCanvas當作普通的控件加入到窗口中,然后調用init()函數即可。init函數的作用是在控件顯示出來后才調用createBufferStrategy(2)語句,否則會拋出IllegalStateException異常。
    這個ImageCanvas使用了雙緩沖機制來顯示視頻(實際上是不間斷地顯示圖像),避免圖像閃爍。在此之前,嘗試了網上找到的雙緩沖代碼,效果都不理想,只有這個能夠不閃爍。
    不過用了這個控件來顯示視頻,就不能全屏了。
    加入控件后,顯示圖像只需要調用
    setImg(BufferedImage img)函數即可。也就是把
    frame.showImage(grabbedImage);
    改為
    canvas.setImg(grabbedImage.getBufferedImage());


    posted on 2015-02-15 11:41 amp@java 閱讀(10430) 評論(7)  編輯  收藏 所屬分類: Java common

    評論

    # re: 用JavaVC替換JMF連接攝像頭 2015-02-16 14:38 京山游俠
    牛。  回復  更多評論
      

    # re: 用JavaVC替換JMF連接攝像頭 2015-03-06 23:50 gaochang
    看標題似乎很強大,可是怎么,好像,應該會有點用吧  回復  更多評論
      

    # re: 用JavaVC替換JMF連接攝像頭 2015-03-08 13:39 marchalex
    贊一個。
    mark一記。回去研究:)  回復  更多評論
      

    # re: 用JavaVC替換JMF連接攝像頭 2015-10-19 20:28 cruiser
    IplImage grabbedImage = grabber.grab();這一句報錯  回復  更多評論
      

    # re: 用JavaVC替換JMF連接攝像頭 2015-11-13 19:40 ytuio21
    @cruiser
    你使用的是新版本的javacv吧,要這樣獲得IpImage: OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
    IplImage frame = converter.convert(grabber.grab());  回復  更多評論
      

    # re: 用JavaVC替換JMF連接攝像頭 2015-11-19 17:49 clyao
    @ytuio21
    最后一點不太明白,有完整的代碼可以參考一下不?  回復  更多評論
      

    # re: 用JavaVC替換JMF連接攝像頭 2016-01-07 17:35 ll
    @clyao
    你找到使用方法了嗎兄弟  回復  更多評論
      

    主站蜘蛛池模板: 直接进入免费看黄的网站| 国产精品无码亚洲精品2021| 无码AV片在线观看免费| 国产亚洲精品国看不卡| 成人免费视频一区二区| 亚洲国产精品人人做人人爽 | 免费欧洲美女牲交视频| 亚洲成a人无码亚洲成www牛牛| 成人免费无遮挡无码黄漫视频| 亚洲天堂男人影院| 毛片a级三毛片免费播放| 亚洲人成高清在线播放| 毛片免费观看网址| 亚洲中文字幕无码久久2020| 四虎www成人影院免费观看| 色偷偷尼玛图亚洲综合| 又黄又爽的视频免费看| selaoban在线视频免费精品| 国产乱辈通伦影片在线播放亚洲 | 亚洲视频在线观看地址| 国产精品入口麻豆免费观看| 国产成人精品日本亚洲11| 免费做爰猛烈吃奶摸视频在线观看| 亚洲一区二区无码偷拍| 国产精品免费一级在线观看| 爱情岛论坛免费视频| 亚洲国产免费综合| 中文字幕在线免费播放| 亚洲国产第一页www| 99爱在线精品免费观看| 学生妹亚洲一区二区| 国产一级高清免费观看| 本道天堂成在人线av无码免费| 好看的亚洲黄色经典| 最近免费中文字幕大全高清大全1| 亚洲a级片在线观看| 国产老女人精品免费视频| 搜日本一区二区三区免费高清视频| 亚洲欧洲精品无码AV| 7m凹凸精品分类大全免费| 中文字幕在线观看亚洲日韩|