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

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

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

    amp@java

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      99 隨筆 :: 0 文章 :: 228 評(píng)論 :: 0 Trackbacks
    JMF太老了,各種問(wèn)題得不到解決,Oracle也沒(méi)再升級(jí)過(guò),如果能找到新東西,最好能把它扔掉。
    最近OpenCV比較火,還有人用Java封裝了OpenCV,成立了JavaCV項(xiàng)目,通過(guò)改造VideoInput這個(gè)基于C語(yǔ)言的項(xiàng)目,能夠用Java來(lái)調(diào)用攝像頭,JMF可以扔掉了。
    如果想測(cè)試,非常簡(jiǎn)單,把那些編譯好的jar文件放入Build Path即可,如果是在Windows X86環(huán)境下,則只需要把帶Window和x86的包,以及不帶有任何平臺(tái)信息包放到Build Path即可。測(cè)試的程序可以用項(xiàng)目主頁(yè)上面那個(gè)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();
        }
    }

    不過(guò)這個(gè)代碼包含了人臉識(shí)別,而人臉識(shí)別需要下載一個(gè)xml文件來(lái)定義識(shí)別的模式,代碼中那個(gè)xml鏈接下載下來(lái)的xml文件是會(huì)解析出錯(cuò)的,可能是那個(gè)版本比較新,JavaCV還沒(méi)跟上,所以解析不了。經(jīng)過(guò)搜索,發(fā)現(xiàn)有人提供了一個(gè)老版本的xml文件,能夠順利解析,會(huì)在視頻中把人臉用綠框框住。
    所以,把代碼中的
    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");
    即可順利運(yùn)行。
    運(yùn)行后發(fā)現(xiàn)很多線(xiàn)條和框框,畫(huà)面也是斜的,如下圖所示:


    這是用來(lái)演示JavaCV對(duì)圖像的處理,如果對(duì)這些沒(méi)有興趣,可以簡(jiǎn)單地用以下代碼來(lái)顯示攝像頭的圖像:

    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();
        }
    }

    如下圖所示:


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

    不過(guò),JavaCV默認(rèn)是把圖像顯示在一個(gè)CanvasFrame對(duì)象中,這個(gè)對(duì)象繼承了JFrame,所以只能用作頂層窗口,不能嵌入到其他窗口中。為了能夠把它嵌入到其他窗口,可以修改一下代碼,繼承一個(gè)Canvas對(duì)象:
    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();
        }
    使用的時(shí)候就把這個(gè)ImageCanvas當(dāng)作普通的控件加入到窗口中,然后調(diào)用init()函數(shù)即可。init函數(shù)的作用是在控件顯示出來(lái)后才調(diào)用createBufferStrategy(2)語(yǔ)句,否則會(huì)拋出IllegalStateException異常。
    這個(gè)ImageCanvas使用了雙緩沖機(jī)制來(lái)顯示視頻(實(shí)際上是不間斷地顯示圖像),避免圖像閃爍。在此之前,嘗試了網(wǎng)上找到的雙緩沖代碼,效果都不理想,只有這個(gè)能夠不閃爍。
    不過(guò)用了這個(gè)控件來(lái)顯示視頻,就不能全屏了。
    加入控件后,顯示圖像只需要調(diào)用
    setImg(BufferedImage img)函數(shù)即可。也就是把
    frame.showImage(grabbedImage);
    改為
    canvas.setImg(grabbedImage.getBufferedImage());


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

    評(píng)論

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

    # re: 用JavaVC替換JMF連接攝像頭 2015-03-06 23:50 gaochang
    看標(biāo)題似乎很強(qiáng)大,可是怎么,好像,應(yīng)該會(huì)有點(diǎn)用吧  回復(fù)  更多評(píng)論
      

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

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

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

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

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

    主站蜘蛛池模板: 亚洲a视频在线观看| 亚洲毛片无码专区亚洲乱| 亚洲乱码无限2021芒果| 免费人成又黄又爽的视频在线电影| a级毛片毛片免费观看久潮| 91视频国产免费| 国产AV无码专区亚洲AV漫画| 国产福利视精品永久免费| 亚洲国产精品一区二区第一页免 | 成人人免费夜夜视频观看| 国产亚洲AV手机在线观看| 色天使亚洲综合在线观看| a级在线观看免费| 日韩中文无码有码免费视频 | 亚洲成a人片7777| 国产福利在线观看永久免费| 一个人在线观看视频免费| 丝袜熟女国偷自产中文字幕亚洲| 亚洲中文字幕无码av在线| 99久久免费国产特黄| 国产色婷婷精品免费视频| 久久亚洲AV无码精品色午夜麻豆 | 亚洲精品456播放| 亚洲成年网站在线观看| 久久免费观看国产精品88av| 亚洲av无码成人精品区| 亚洲综合色7777情网站777| 免费国产成人午夜在线观看| 无码欧精品亚洲日韩一区夜夜嗨| 亚洲午夜精品国产电影在线观看| 在线看片免费人成视频福利| 亚洲不卡AV影片在线播放| 亚洲中文字幕乱码熟女在线| 在线观看免费中文视频| 亚洲精品无码av人在线观看| 美女视频黄a视频全免费网站色 | 国产又长又粗又爽免费视频| 亚洲AV无码久久久久网站蜜桃 | 182tv免费观看在线视频| 亚洲精品亚洲人成在线观看| 美女黄网站人色视频免费|