Java 調用 OpenCV (可獲取到圖像)


前言

感謝 年輕的老魏 Java實現opencv 調用本地攝像頭,實現人臉識別、人形識別、人眼識別,在此基礎上做的一點點優化

1.首先下載opencv

2.沒有用System.loadLibrary(Core.NATIVE_LIBRARY_NAME);配置比較繁瑣,采用了System.load(ClassLoader.getSystemResource("lib/opencv_java440.dll").getPath());這種方式不用那么多配置,簡單實用

簡化版

package com.callOpencv;

import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.Videoio;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

public class CallOpenCv {
    private static String rtsp_64 = "rtsp://賬號:密碼@192.168.0.64:554/stream0";
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
    private static String dir = "D:/VideoRec/Img";
    private static Integer sleepCount = 0;

    public static void main(String[] args) {
        openVideo();
    }

    private static void openVideo() {
        VideoCapture capture = null;
        try {
            System.load("D:/Program/opencv/build/java/x64/opencv_java440.dll");
            capture = new VideoCapture();
            capture.open(rtsp_64);
            int height = (int) capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
            int width = (int) capture.get(Videoio.CAP_PROP_FRAME_WIDTH);
            if (height == 0 || width == 0) {
                throw new Exception("camera not found!");
            }
            Mat capImg = new Mat();
            Mat temp = new Mat();
            while (true) {
                capture.read(capImg);
                //opencv是1s讀取24張圖片(大概),想要1s處理一次,【先讀取再扔掉】
                if (++sleepCount <= 25) {
                    continue;
                }
                sleepCount = 0;
                Imgproc.cvtColor(capImg, temp, Imgproc.COLOR_RGB2GRAY);
                Imgcodecs.imwrite(dir + "/" + sdf.format(new Date()) + ".jpg", temp);
            }
        } catch (Exception e) {
            System.out.println("異常:" + e.getMessage() + " --- " + Arrays.toString(e.getStackTrace()));
        } finally {
            if (capture != null && capture.isOpened()) {
                System.out.println("-----capture--done--");
                capture.release();
            }
        }
    }
}
package com;

import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.Arrays;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfDouble;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.ml.SVM;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.objdetect.HOGDescriptor;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.Videoio;

public class CaptureBasic extends JPanel {
    private BufferedImage mImg;

    public static void main(String[] args) {
        try {
            //加載本地native庫  配置較繁瑣,不用
            // System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
            //獲取opencv.dll絕對路徑  推薦
            URL url = ClassLoader.getSystemResource("lib/opencv_java440.dll");
            System.load(url.getPath());

            //獲取本地攝像頭
            // VideoCapture capture = new VideoCapture(0);

            //獲取網絡攝像頭
            VideoCapture capture = new VideoCapture();
            capture.open("rtsp://賬號:密碼@192.168.0.64:554/stream0");

            int height = (int) capture.get(Videoio.CAP_PROP_FRAME_HEIGHT);
            int width = (int) capture.get(Videoio.CAP_PROP_FRAME_WIDTH);
            if (height == 0 || width == 0) {
                throw new Exception("camera not found!");
            }

            //Java窗口容器
            JFrame frame = new JFrame("camera");
            frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            //Java畫板容器
            CaptureBasic panel = new CaptureBasic();
            addMouseListener(panel);
            //配置關系
            frame.setContentPane(panel);
            frame.setVisible(true);
            frame.setSize(width + frame.getInsets().left + frame.getInsets().right, height + frame.getInsets().top + frame.getInsets().bottom);
            int n = 0;
            Mat capImg = new Mat();
            Mat temp = new Mat();
            while (frame.isShowing() && ++n < 500) {
                //把攝像頭數據讀到Mat
                capture.read(capImg);
                //彩色空間轉換,把圖像轉換為灰度的、占用空間小的
                Imgproc.cvtColor(capImg, temp, Imgproc.COLOR_RGB2GRAY);
                // temp = capImg.clone();
                //保存
                Imgcodecs.imwrite("D:/VideoRec/Img/back" + n + ".png", temp);
                //進行人臉識別
                Mat mat = detectFace(capImg);
                //把識別畫框圖像放在畫板上
                panel.mImg = panel.mat2BI(mat);
                //繪制
                panel.repaint();
            }
            capture.release();
            frame.dispose();
        } catch (Exception e) {
            System.out.println("異常:" + e.getMessage() + " --- " + Arrays.toString(e.getStackTrace()));
        } finally {
            System.out.println("--done--");
        }
    }

    private BufferedImage mat2BI(Mat mat) {
        int dataSize = mat.cols() * mat.rows() * (int) mat.elemSize();
        byte[] data = new byte[dataSize];
        mat.get(0, 0, data);
        int type = mat.channels() == 1 ? BufferedImage.TYPE_BYTE_GRAY : BufferedImage.TYPE_3BYTE_BGR;
        if (type == BufferedImage.TYPE_3BYTE_BGR) {
            for (int i = 0; i < dataSize; i += 3) {
                byte blue = data[i + 0];
                data[i + 0] = data[i + 2];
                data[i + 2] = blue;
            }
        }
        BufferedImage image = new BufferedImage(mat.cols(), mat.rows(), type);
        image.getRaster().setDataElements(0, 0, mat.cols(), mat.rows(), data);
        return image;
    }

    /**
     * opencv實現人臉識別
     *
     * @param img
     */
    public static Mat detectFace(Mat img) throws Exception {
        System.out.println("Running DetectFace ... ");
        // 從配置文件lbpcascade_frontalface.xml中創建一個人臉識別器,該文件位於opencv安裝目錄中
        // CascadeClassifier faceDetector = new CascadeClassifier("D:\\TDDOWNLOAD\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
        CascadeClassifier faceDetector = new CascadeClassifier("D:/Program/opencv/sources/data/haarcascades/haarcascade_frontalface_alt.xml");

        // 在圖片中檢測人臉
        MatOfRect faceDetections = new MatOfRect();

        faceDetector.detectMultiScale(img, faceDetections);

        //System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));

        Rect[] rects = faceDetections.toArray();
        if (rects != null && rects.length >= 1) {
            for (Rect rect : rects) {
                Imgproc.rectangle(img, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
                        new Scalar(0, 0, 255), 2);
            }
        }
        return img;
    }

    /**
     * opencv實現人型識別,hog默認的分類器。所以效果不好。
     *
     * @param img
     */
    public static Mat detectPeople(Mat img) {
        //System.out.println("detectPeople...");
        if (img.empty()) {
            System.out.println("image is exist");
        }
        HOGDescriptor hog = new HOGDescriptor();
        hog.setSVMDetector(HOGDescriptor.getDefaultPeopleDetector());
        System.out.println(HOGDescriptor.getDefaultPeopleDetector());
        //hog.setSVMDetector(HOGDescriptor.getDaimlerPeopleDetector());
        MatOfRect regions = new MatOfRect();
        MatOfDouble foundWeights = new MatOfDouble();
        //System.out.println(foundWeights.toString());
        hog.detectMultiScale(img, regions, foundWeights);
        for (Rect rect : regions.toArray()) {
            Imgproc.rectangle(img, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 0, 255), 2);
        }
        return img;
    }

    /**
     * 畫到容器
     *
     * @param g
     */
    public void paintComponent(Graphics g) {
        if (mImg != null) {
            g.drawImage(mImg, 0, 0, mImg.getWidth(), mImg.getHeight(), this);
        }
    }

    /**
     * 添加鼠標監聽
     *
     * @param panel
     */
    private static void addMouseListener(CaptureBasic panel) {
        panel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("click");
            }

            @Override
            public void mousePressed(MouseEvent e) {
                System.out.println("mousePressed");
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                System.out.println("mouseReleased");

            }

            @Override
            public void mouseEntered(MouseEvent e) {
                System.out.println("mouseEntered");
            }

            @Override
            public void mouseExited(MouseEvent e) {
                System.out.println("mouseExited");
            }

            @Override
            public void mouseWheelMoved(MouseWheelEvent e) {
                System.out.println("mouseWheelMoved");
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                System.out.println("mouseDragged");
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                System.out.println("mouseMoved");
            }
        });
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM