一、环境准备
1、eclipse
2、jdk1.8
3、opencv-3.4.16
https://opencv.org/releases/
官网下载太慢,找了一个网站,很快:https://www.raoyunsoft.com/opencv/opencv-3.4.16/
二、opencv开发环境搭建
1、安装opencv
双击opencv-3.4.16-vc14_vc15.exe会解压为一个文件夹,将该文件夹拷贝到安装目录。
2、打开eclipse,添加User Libraries
先新增一个opencv-3.4.16,然后再点击Add External JARs 添加刚才opencv目录下的jar,如下图
再选择Native点击Edit选择opencv目录下的build/java/x64(若为32位的eclipse和jdk就选32位的)
3、新建测试项目
新建普通的Java项目OpenCVTest,右键项目Build Path添加Add Librarys->User Library 添加上面加的opencv-3.4.16
4、测试
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
public class HelloWorld {
public static void main(String[] args) {
//调用opencv库文件
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//生成3*3矩阵,矩阵类型为CvType.CV_8UC1
Mat mat = Mat.eye(3,3,CvType.CV_8UC1);
//矩阵数据输出
System.out.println(mat.dump());
}
}
运行,输出结果!
三、简单介绍和使用
1、OpenCV主要模块简介
OpenCV是开源的计算机视觉库,包括了图像处理和计算机视觉方面很多通用的算法,其主要模块及功能如下:
- Core:核心模块,包括基础数据结构、绘图函数、数组操作函数等;
- Imgproc:图像处理模块,包括图像滤波、几何变换、直方图、形态学处理、边缘检测、特征及目标检测等;
- Highgui:顶层GUI模块,包括用户界面、读/写图像及视屏等;
- Video:视频模块,包括运动分析及目标跟踪等;
- 其他模块
- Calib3d:提供基本的多视图几何算法、平面和立体影像校正、物体定位、立体通信算法和三维重建;
- Features2d:显著特征探测器、描述符和描述符匹配器。
- Objectect:检测对象和预定义的类的实例(例如:脸部、眼睛、杯子、人、车等等)。
- GPU:自于不同的OpenCV模块的GPU加速算法。
等等。
2、相关api举例
- OpenCV中的Mat类(Matrix矩阵)
- Java中调用OpenCV函数需要加上模块名称,比如显示图像:Highgui.imgshow(“lena”,src)
- 读取图像:Mat src = Imgcodecs.imread(“lena.jpg”);
- 输出图像:Imgcodecs.imwrite(“lean.jpg”,mat);
- 要创建每个点只有一个通道的简单矩阵,可用三个静态函数:zeros,eye,ones;
- CV_8UC1:8位Unsigned(取值范围0~255);Channel(通道)=1(灰度图);
- CV_8UC3:8位Unsigned(取值范围0~255);Channel(通道)=3(彩色图);
- CV_64FC3:64位浮点数;Channel(通道)=3(彩色图);
- 通道:彩色(RGB三个通道);有时还有alpha通道(透明度);
2-1、读取图像显示
public class Test1 {
public static void main(String[] args) {
//调用opencv库文件
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//读取图像显示
Mat mat = Imgcodecs.imread("ll.jpg");
HighGui.imshow("拉姆雷姆", mat);
HighGui.waitKey(0);
System.out.println("ok");
}
}
HighGui.waitKey方法
在一个给定的时间内(单位ms)等待用户按键触发;如果用户没有按下 键,则接续等待(循环),return:按键值,这个函数只有在至少一个HighGUI窗口存在的情况下才会起作用。通常在 imshow() 函数之后使用
1、waitKey(0)
无限循环,等待用户按键触发跳出循环
2、waitKey(5)
如果用户在5ms中没有触发事件,则5ms后跳出循环
通常用于接收视频信号,每一帧停留5ms,然后进入下一帧
3、if(waitKey(10000) == ‘Q’);
如果用户在10000ms内按键‘Q’,执行if
4、if(waitKey(10000) > 0);
如果用户在10000ms内按下了任何按钮,执行if
注:这里的退出循环并不是关闭GUI,只是程序可以继续往下执行
2-2、读取图像的时候,同时转换成 灰度图
public class Test1 {
public static void main(String[] args) {
//调用opencv库文件
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//读取的时候直接转换成灰度图
Mat mat2 = Imgcodecs.imread("ll.jpg",Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
Imgcodecs.imwrite("12.jpg",mat2);
System.out.println("ok");
}
}
运行完后可以看到目录下面有12.jpg
2-3、zeros,eye,ones
其实就是生成三种矩阵
public class Test1 {
public static void main(String[] args) {
System.out.println("zeros:");
System.out.println(Mat.zeros(3, 3, CvType.CV_8UC1).dump());
System.out.println("eye:");
System.out.println(Mat.eye(3, 3, CvType.CV_8UC1).dump());
System.out.println("ones:");
System.out.println(Mat.ones(3, 3, CvType.CV_8UC1).dump());
}
}
运行结果如下
可以看到zeros生成的是0矩阵,eye生成的是行列相同为1的矩阵,ones生成的是1矩阵.
四、人脸识别案例
这里目前只是简单进行图片的人脸识别demo
public class FaceTest {
public static void main(String[] args) {
//调用opencv库文件
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
//读取图像
Mat mat = Imgcodecs.imread("C:\\Users\\86135\\Desktop\\test.jpg");
//初始化人脸探测器:需要检测opencv的人脸识别xml文件路径
CascadeClassifier dector = new CascadeClassifier("F:\\Software\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
//检测结果,矩形集合
MatOfRect detectResult = new MatOfRect();
//进行检测
dector.detectMultiScale(mat, detectResult);
if(detectResult.toArray().length<=0) {
HighGui.imshow("未检测到人脸", mat);
HighGui.waitKey(0);
}else {
//画出所有矩形
for(Rect rect:detectResult.toArray()) {
Imgproc.rectangle(mat, new Point(rect.x, rect.y),
new Point(rect.x+rect.width, rect.y+rect.height),
new Scalar(255, 0, 0), 2);
}
HighGui.imshow("检测到人脸", mat);
HighGui.waitKey(0);
}
}
}
可以看,有一张没有识别出来,代码还是很简单的。
我们可以看下opencv安装目录
还有好多识别的xml,比如眼睛,身体啊,这些后续再研究。