赞
踩
今天就来记录一下在Java中使用Opencv得配置吧,至于OpenCV的使用很简单,现成API的调用,查查文档就好了,但是关于OpenCV 这些API背后的原理就需要去学习一下数字图像处理的知识了。推荐冈萨雷斯的《数字图像处理》,这本书真的很棒棒呢
一、OpenCV官网下载opencv到本地,比如我下载到本地目录:F:\opencv3
二、新建一个Java项目,然后在其Project Structure中加入我们下载的OpenCV .jar文件。
三、从本地文件中加载动态库
- 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<Mat> 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的调用很简单,但是要游刃有余还是需要学习一下数字图像处理的基本知识。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。