基于Java语言的OpenCV使用

今天就来记录一下在Java中使用Opencv得配置吧,至于OpenCV的使用很简单,现成API的调用,查查文档就好了,但是关于OpenCV 这些API背后的原理就需要去学习一下数字图像处理的知识了。推荐冈萨雷斯的《数字图像处理》,这本书真的很棒棒呢

一、OpenCV官网下载opencv到本地,比如我下载到本地目录:F:\opencv3

二、新建一个Java项目,然后在其Project Structure中加入我们下载的OpenCV .jar文件。

基于Java语言的OpenCV使用_第1张图片

三、从本地文件中加载动态库

static {
        System.load("F:\\opencv3\\opencv\\build\\java\\x64\\opencv_java455.dll");
    }

四、使用

最后就是使用啦,我用它计算一个图形的重心,思路就是,带有目标物的图像通过背差法减掉背景图,然后通过腐蚀膨胀开运算去除小的噪声,然后Canny边缘检测之后转为二值图,最后加权计算重心位置。有个弊端就是开运算改变了像素点的值,导致重心些微偏移。所以还是采用滤波做噪声消除比较合适。

import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import java.util.ArrayList;
import java.util.List;


public class test {
    static {
        System.load("F:\\opencv3\\opencv\\build\\java\\x64\\opencv_java455.dll");
    }

    public static void main(String[] args) {
        String aimPicture1 = "C:\\Users\\Administrator\\Desktop\\test\\01.jpg";
        
        String backPicture = "C:\\Users\\Administrator\\Desktop\\test\\background.jpg";
        String destPicture = "C:\\Users\\Administrator\\Desktop\\test\\subtract.jpg";
        Mat aim1 = Imgcodecs.imread(aimPicture1);
        Point p1=dotest(aim1, backPicture, destPicture);
        System.out.println("x:"+p1.x);
        System.out.println("y:"+p1.y);

    }

    
    public static Point dotest(Mat aim, String backgroundPicture, String destPath) {
        Mat background = Imgcodecs.imread(backgroundPicture);
        Mat dest = new Mat(aim.size(), aim.type());
        //去除背景
        Core.subtract(aim, background, dest);
        Imgcodecs.imwrite(destPath, dest);
        //腐蚀再膨胀
        Mat openMat = open(dest);
        //拉普拉斯锐化再检测
//        Mat laplacianMat = new Mat(openMat.size(),CvType.CV_64F);
//        Imgproc.Laplacian(openMat,laplacianMat,3);
//        Imgcodecs.imwrite("C:\\Users\\Administrator\\Desktop\\test\\laplacian.jpg",laplacianMat);
//        边缘检测
        Mat edgeMat = new Mat(openMat.size(), CvType.CV_64F);
        List matList = new ArrayList<>();
        Core.split(openMat, matList);
        Imgcodecs.imwrite("C:\\Users\\Administrator\\Desktop\\test\\gray0.jpg", matList.get(0));
        Imgcodecs.imwrite("C:\\Users\\Administrator\\Desktop\\test\\gray1.jpg", matList.get(1));
        Imgcodecs.imwrite("C:\\Users\\Administrator\\Desktop\\test\\gray2.jpg", matList.get(2));
        Imgproc.Canny(matList.get(2), edgeMat, 15, 40);
        Imgcodecs.imwrite("C:\\Users\\Administrator\\Desktop\\test\\canny.jpg", edgeMat);
        
        //水平线检测,垂直线检测
        float[] hori = {-1, -1, -1, 2, 2, 2, -1, -1, -1};
        Mat horiMat = new Mat(3, 3, CvType.CV_32F);
        horiMat.put(0, 0, hori);
        Mat hLineMat = new Mat(openMat.size(), openMat.type());
        Imgproc.filter2D(edgeMat, hLineMat, 3, horiMat);
        Imgcodecs.imwrite("C:\\Users\\Administrator\\Desktop\\test\\hLineMat.jpg", hLineMat);
        float[] veri = {-1, 2, -1, -1, 2, -1, -1, 2, -1};
        Mat veriMat = new Mat(3, 3, CvType.CV_32F);
        veriMat.put(0, 0, veri);
        Mat vLineMat = new Mat(openMat.size(), openMat.type());
        Imgproc.filter2D(edgeMat, vLineMat, 3, veriMat);
        Imgcodecs.imwrite("C:\\Users\\Administrator\\Desktop\\test\\vLineMat.jpg", vLineMat);

        //范围裁剪
        int rows = edgeMat.rows();
        int cols = edgeMat.cols();
        int rows_10 = (int) (rows * 0.2);
        int cols_10 = (int) (cols * 0.2);
        Mat dstClipRange = edgeMat.rowRange((int) (rows * 0.2), rows - (int) (rows * 0.2))
                .colRange((int) (cols * 0.2), cols - (int) (cols * 0.2));
        edgeMat.release();

        //计算xline sumWeight
        int sumWeightx = 0;
        int sumX = 0;
        for (int i = 0; i < dstClipRange.cols(); i++) {
            int sum = 0;
            for (int j = 0; j < dstClipRange.rows(); j++) {
                sum += dstClipRange.get(j, i)[0];
            }
            sumWeightx += (i + 1) * sum;
            sumX += sum;
        }

        int sumWeighty = 0;
        int sumY = 0;
        for (int i = 0; i < dstClipRange.rows(); i++) {
            int sum = 0;
            for (int j = 0; j < dstClipRange.cols(); j++) {
                sum += dstClipRange.get(i, j)[0];
            }
            sumWeighty += (i + 1) * sum;
            sumY += sum;
        }

        double centerX = sumWeightx / sumX;
        double centerY = sumWeighty / sumY;
        centerX = centerX + cols_10;
        centerY = centerY + rows_10;
        Point p = new Point();
        p.x =centerX;
        p.y=centerY;
        System.out.println("x:" + centerX + "y:" + centerY);
        return p;
    }

    public static double getSumY(Mat singleChannelMat, Mat result) {
        Core.reduce(singleChannelMat, result, 1, Core.REDUCE_SUM);
        Core.MinMaxLocResult max = Core.minMaxLoc(result);
        return max.maxVal;
    }

    public static double getSumX(Mat singleChannelMat, Mat result) {
        Core.reduce(singleChannelMat, result, 0, Core.REDUCE_SUM);
        Core.MinMaxLocResult max = Core.minMaxLoc(result);
        return max.maxVal;
    }

    public static double getSingleValue(Mat singleChannelMat) {
        return getSingleValueFloat(singleChannelMat);
    }

    public static double getSingleValueFloat(Mat singleChannelMat) {
        double sum = 0;
        float[] temp = new float[singleChannelMat.rows() * singleChannelMat.cols() * singleChannelMat.channels()];
        singleChannelMat.get(0, 0, temp);
        for (double v : temp) {
            sum += v;
        }
        return sum;
    }




    public static Mat open(Mat srcImage) {
        Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, (new Size(10, 10)));
        Mat destImage = new Mat(srcImage.size(), CvType.CV_64F);
        Imgproc.erode(srcImage, destImage, element); //腐蚀
        Imgproc.dilate(destImage, destImage, element); //膨胀
        Imgcodecs.imwrite("C:\\Users\\Administrator\\Desktop\\test\\open.jpg", destImage);
        return destImage;
    }

    public static Mat open2(Mat srcImage) {
        Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, (new Size(5, 5)));
        Mat destImage = new Mat(srcImage.size(), CvType.CV_64F);
        Imgproc.erode(srcImage, destImage, element); //腐蚀
        Imgproc.dilate(destImage, destImage, element); //膨胀
        return destImage;
    }
}


效果也还行吧,就整挺好的。API的调用很简单,但是要游刃有余还是需要学习一下数字图像处理的基本知识。

你可能感兴趣的:(OpenCV,opencv,java,计算机视觉)