首先要下载OpenCV(去官网下载就行,可能会比较慢),下载对应版本,windows版本是个exe执行文件
直接运行exe安装文件安装(注意自己自己选择的安装路径,后面会用到)
我的安装在了D盘下,安装目录 build\java文件夹下有对应的jar包调用摄像头的dll动态库文件
java中使用openCV
demo项目结构
1、使用百度人脸识别api,编写AuthService类,参考https://ai.baidu.com/tech/face/compare文档
注册账号,与创建应用获取API ID与Secret Key
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
/**
* 获取token类
*/
public class AuthService {
public static void main(String[] args) {
System.out.println(getAuth());
}
/**
* 获取权限token
* @return 返回示例:
* {
* "access_token": "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567",
* "expires_in": 2592000
* }
*/
public static String getAuth() {
// 官网获取的 API Key 更新为你注册的
String clientId = "*************";
// 官网获取的 Secret Key 更新为你注册的
String clientSecret = "***************";
return getAuth(clientId, clientSecret);
}
/**
* 获取API访问token
* 该token有一定的有效期,需要自行管理,当失效时需重新获取.
* @param ak - 百度云官网获取的 API Key
* @param sk - 百度云官网获取的 Securet Key
* @return assess_token 示例:
* "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
*/
public static String getAuth(String ak, String sk) {
// 获取token地址
String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
String getAccessTokenUrl = authHost
// 1. grant_type为固定参数
+ "grant_type=client_credentials"
// 2. 官网获取的 API Key
+ "&client_id=" + ak
// 3. 官网获取的 Secret Key
+ "&client_secret=" + sk;
try {
URL realUrl = new URL(getAccessTokenUrl);
// 打开和URL之间的连接
HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
connection.setRequestMethod("GET");
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.err.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String result = "";
String line;
while ((line = in.readLine()) != null) {
result += line;
}
/**
* 返回结果示例
*/
System.err.println("result:" + result);
JSONObject jsonObject = new JSONObject(result);
String access_token = jsonObject.getString("access_token");
return access_token;
} catch (Exception e) {
System.err.printf("获取token失败!");
e.printStackTrace(System.err);
}
return null;
}
}
2、测试类
import com.itywh.utils.Base64Util;
import com.itywh.utils.FileUtil;
import com.itywh.utils.GsonUtils;
import com.itywh.utils.HttpUtil;
import java.util.*;
/**
* 人脸对比
*/
public class FaceMatch {
/**
* 重要提示代码中所需工具类
* FileUtil,Base64Util,HttpUtil,GsonUtils请从
* https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
* https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
* https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
* https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
* 下载
*/
public static String faceMatch() {
// 请求url
String url = "https://aip.baidubce.com/rest/2.0/face/v3/match";
try {
byte[] bytes1 = FileUtil.readFileByBytes("C:\\Users\\Administrator.SC-202006201051\\Desktop\\Picture\\张一山1.jpeg");
// byte[] bytes2 = FileUtil.readFileByBytes("C:\\Users\\Administrator.SC-202006201051\\Desktop\\Picture\\夏雨1.jpeg");
byte[] bytes2 = FileUtil.readFileByBytes("C:\\Users\\Administrator.SC-202006201051\\Desktop\\Picture\\张一山2.jpeg");
String image1 = Base64Util.encode(bytes1);
String image2 = Base64Util.encode(bytes2);
List<Map<String,Object>> imagesList = new ArrayList<>();
HashMap<String, Object> map1 = new HashMap<>();
map1.put("image",image1);
map1.put("image_type","BASE64");
map1.put("face_type","LIVE");
map1.put("quality_control","LOW");
map1.put("liveness_control","NONE");//活体检测控制
HashMap<String, Object> map2 = new HashMap<>();
map2.put("image",image2);
map2.put("image_type","BASE64");
map2.put("face_type","LIVE");
map2.put("quality_control","LOW");
map2.put("liveness_control","NONE");//活体检测控制
imagesList.add(map1);
imagesList.add(map2);
String param = GsonUtils.toJson(imagesList);
// 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
//[调用鉴权接口获取的token]
String accessToken = AuthService.getAuth();
//25.e55427baef037f8c8e61b28c7bf0708a.315360000.1925624675.282335-23521358
System.out.println("token = "+accessToken);
String result = HttpUtil.post(url, accessToken, "application/json", param);
System.out.println(result);
return result;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
FaceMatch.faceMatch();
}
}
3、编写CaptureBasic类用来检测人脸
import com.itywh.baidu.FaceMatch;
import org.opencv.core.Point;
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;
import org.opencv.videoio.Videoio;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
public class CaptureBasic extends JPanel {
private BufferedImage mImg;
/**
* 转换图像
*
* @param mat
* @return
*/
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;
}
public void paintComponent(Graphics g) {
if (mImg != null) {
g.drawImage(mImg, 0, 0, mImg.getWidth(), mImg.getHeight(), this);
}
}
/**
* 显示视频
*/
public static boolean showVido(VideoCapture capture) {
try {
// 创建矩阵
Mat capImg = new Mat();
// 设置摄像头高度
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!");
}
//使用Swing生成GUI
JFrame frame = new JFrame("人脸识别");
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
CaptureBasic panel = new CaptureBasic();
//设置中心显示
frame.setContentPane(panel);
frame.setVisible(true);
frame.setSize(width + frame.getInsets().left + frame.getInsets().right,
height + frame.getInsets().top + frame.getInsets().bottom);
frame.setLocationRelativeTo(null);
int n = 0;
// 创建一个临时矩阵
Mat temp = new Mat();
while (frame.isShowing() && n < 100000) {
//从摄像头读取一帧数据,保存到capImg矩阵中。
capture.read(capImg);
//转换为彩色图
Imgproc.cvtColor(capImg, temp, Imgproc.COLOR_RGBA2BGRA);
//调用人脸识别
capImg = detectFace(capImg);
//转为图像显示
panel.mImg = panel.mat2BI(capImg);
Imgcodecs.imwrite("D:\\renlian\\Capture\\1.jpg",capImg);
panel.repaint();
String result = FaceMatch.faceMatch();
if(result.equals("1")){
capture.release();
frame.dispose();
return true;
}
}
capture.release();
frame.dispose();
} catch (Exception e) {
System.out.println("例外:" + e);
} finally {
System.out.println("--done--");
}
return false;
}
/**
* 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:\\opencv\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
CascadeClassifier faceDetector = new CascadeClassifier("D:\\openCV\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
// 在图片中检测人脸
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(img, faceDetections);
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, 255, 0), 2);
}
}
return img;
}
}
4、编写Test测试类
System.out.println(System.getProperties().getProperty("java.library.path"));
//1、加载openCV类库
System.loadLibrary("opencv_java450");
//2、打开摄像头获取视频流
VideoCapture vc = new VideoCapture(0);
//3、检查是否支持摄像头,true代表摄像头可以打开,false代表不可以打开
System.out.println(vc.isOpened());
//4、调用摄像头显示
CaptureBasic.showVido(vc);
出现no opencv_java450 in java.library.path的解决办法如下
在vm一栏加上openCV所在目录下位置 -Djava.library.path=D:\\openCV\\opencv\\build\\java\\x64;D:\\openCV\\opencv\\build\\x64\\vc15\\bin(这个要根据自己安装位置来配置)