基於JavaCv並發讀取本地視頻流並提取每幀32位dhash特征


1.讀取本地視頻流,pom依賴

依賴於 org.bytedeco下的javacv/opencv/ffmpeg 包

        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.4.3</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>opencv</artifactId>
            <version>3.4.3-1.4.3</version>
            <classifier>linux-x86_64</classifier>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg</artifactId>
            <version>4.0.2-1.4.3</version>
            <classifier>linux-x86_64</classifier>
        </dependency>

2.讀取本地視頻流並解幀為 opencv_core.Mat

File file = new File("/home/lab/javacv/t11.mp4");
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(file);

grabber.start();

// 解幀為opencv_core.Mat
List<opencv_core.Mat> mats = new ArrayList<>();
for (int i = 0; i < grabber.getLengthInFrames(); i++) {
    Frame frame = grabber.grabImage();
    OpenCVFrameConverter.ToMat toMat = new OpenCVFrameConverter.ToMat();
    opencv_core.Mat mat = toMat.convert(frame);
    if (mat != null) {
        mats.add(mat.clone());
    }
}

grabber.stop();

3.獲取32位dhash特征

dhash特征提取思路,圖片Mat轉為單通道的灰度圖,並重置為5*5的Size,最后將其轉儲為長度為 25 的byte數組用以求取32位dhash特征

// 聲明空的灰度圖 Mat
opencv_core.Mat grayImg = new opencv_core.Mat(mat.rows(), mat.cols(), opencv_imgcodecs.IMREAD_GRAYSCALE);
// 轉儲為灰度圖
opencv_imgproc.cvtColor(mat, grayImg, opencv_imgproc.COLOR_RGB2GRAY);
// 修改Mat長寬size
opencv_core.Mat resizedImg = new opencv_core.Mat();
opencv_core.Size size = new opencv_core.Size(5,5);
opencv_imgproc.resize(grayImg,resizedImg,size);
// 轉為 5*5 byte 數組
byte[] bytePixels = new byte[5 * 5];
resizedImg.data().get(bytePixels);
int[] pixels = new int[bytePixels.length];
for (int i=0; i<pixels.length; i++) {
    pixels[i] = bytePixels[i] & 0xff;
}
// 獲取32位dhash特征
int feature = 0;
for (int j=0; j<4; j++) {
    for (int i=0; i<4; i++) {
        int colBit = pixels[i*5+j] > pixels[(i+1)*5+j] ? 1 : 0;
        feature = (feature << 1) + colBit;
        int rowBit = pixels[i*5+j] > pixels[i*5+j+1] ? 1 : 0 ;
        feature = (feature << 1) + rowBit;
    }
}

多線程部分,可參考該博: https://www.cnblogs.com/nyatom/p/10119306.html


免責聲明!

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



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