使用opencv版本2.4.1.1,java项目是springboot
https://opencv.org/releases/page/4/
一、windows中使用
下载openCV-2.4.1.1windows版本,得到一个.exe文件,电脑中打开运行会生成一个opencv文件夹目录,打开目录中找到java使用的jar文件和.dll库文件(x86或x64文件中)
接下来项目中引入jar文件,可以创建一个文件夹存放
gradle中引用
compile fileTree(dir:'openCv',include:['*.jar'])
项目中初始化库文件
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author zhy
* @date 2019/8/1 15:27
*/
@Configuration
@ConfigurationProperties(prefix = "opencv.lib")
public class OpenCvLibConfig {
@Value("${opencv.lib.path}")
private String path;
@Bean
public void init() {
System.load(path);
}
}
application.properties
opencv.lib.path=D:/test/opencv_java2411.dll
创建工具类
import lombok.extern.slf4j.Slf4j;
import org.opencv.calib3d.Calib3d;
import org.opencv.core.*;
import org.opencv.features2d.*;
import org.opencv.highgui.Highgui;
import java.util.LinkedList;
import java.util.List;
/**
* 图像识别
*
* @author zhy
* @date 2019/7/31 14:56
*/
@Slf4j
public class ImageRecognition {
private ImageRecognition() {
throw new IllegalStateException("Utility class");
}
/**
* 匹配图像
*
* @param templateFilePath 模板文件路径
* @param originalFilePath 原始文件路径
* @return 匹配的像素点总数
*/
public static int matchImage(String templateFilePath, String originalFilePath, String processDiagram) {
float nndrRatio = 0.7f;
//读取图片文件
Mat templateImage = Highgui.imread(templateFilePath, Highgui.CV_LOAD_IMAGE_COLOR);
Mat originalImage = Highgui.imread(originalFilePath, Highgui.CV_LOAD_IMAGE_COLOR);
if (templateImage.cols() == 0 || originalImage.cols() == 0 || templateImage.rows() == 0 || originalImage.rows() == 0) {
log.error("图片文件路径异常,获取的图片大小为0,无法读取");
return 0;
}
MatOfKeyPoint templateKeyPoints = new MatOfKeyPoint();
//指定特征点算法SURF
FeatureDetector featureDetector = FeatureDetector.create(FeatureDetector.SURF);
//获取模板图的特征点
featureDetector.detect(templateImage, templateKeyPoints);
//提取模板图的特征点
MatOfKeyPoint templateDescriptors = new MatOfKeyPoint();
DescriptorExtractor descriptorExtractor = DescriptorExtractor.create(DescriptorExtractor.SURF);
log.info("提取模板图的特征点");
descriptorExtractor.compute(templateImage, templateKeyPoints, templateDescriptors);
Mat outputImage = new Mat(templateImage.rows(), templateImage.cols(), Highgui.CV_LOAD_IMAGE_COLOR);
log.info("在图片上显示提取的特征点");
Features2d.drawKeypoints(templateImage, templateKeyPoints, outputImage, new Scalar(255, 0, 0), 0);
MatOfKeyPoint originalKeyPoints = new MatOfKeyPoint();
MatOfKeyPoint originalDescriptors = new MatOfKeyPoint();
featureDetector.detect(originalImage, originalKeyPoints);
log.info("提取原图的特征点");
descriptorExtractor.compute(originalImage, originalKeyPoints, originalDescriptors);
List<MatOfDMatch> matches = new LinkedList<>();
DescriptorMatcher descriptorMatcher = DescriptorMatcher.create(DescriptorMatcher.FLANNBASED);
log.info("寻找最佳匹配");
descriptorMatcher.knnMatch(templateDescriptors, originalDescriptors, matches, 2);
log.info("计算匹配结果");
LinkedList<DMatch> goodMatchesList = new LinkedList<>();
matches.forEach(match -> {
DMatch[] dmatcharray = match.toArray();
DMatch m1 = dmatcharray[0];
DMatch m2 = dmatcharray[1];
if (m1.distance <= m2.distance * nndrRatio) {
goodMatchesList.addLast(m1);
}
});
if (processDiagram != null && goodMatchesList.size() > 4) {
matchPointOutput(templateKeyPoints, originalKeyPoints
, goodMatchesList, templateImage, originalImage, processDiagram);
}
return goodMatchesList.size();
}
/**
* 输出特征点匹配过程
*
* @param templateKeyPoints MatOfKeyPoint
* @param originalKeyPoints MatOfKeyPoint
* @param goodMatchesList LinkedList<DMatch>
* @param templateImage Mat
* @param originalImage Mat
*/
private static void matchPointOutput(MatOfKeyPoint templateKeyPoints, MatOfKeyPoint originalKeyPoints
, List<DMatch> goodMatchesList, Mat templateImage, Mat originalImage, String processDiagram) {
List<KeyPoint> templateKeyPointList = templateKeyPoints.toList();
List<KeyPoint> originalKeyPointList = originalKeyPoints.toList();
LinkedList<Point> objectPoints = new LinkedList<>();
LinkedList<Point> scenePoints = new LinkedList<>();
goodMatchesList.forEach(goodMatch -> {
objectPoints.addLast(templateKeyPointList.get(goodMatch.queryIdx).pt);
scenePoints.addLast(originalKeyPointList.get(goodMatch.trainIdx).pt);
});
MatOfPoint2f objMatOfPoint2f = new MatOfPoint2f();
objMatOfPoint2f.fromList(objectPoints);
MatOfPoint2f scnMatOfPoint2f = new MatOfPoint2f();
scnMatOfPoint2f.fromList(scenePoints);
Mat homography = Calib3d.findHomography(objMatOfPoint2f, scnMatOfPoint2f, Calib3d.RANSAC, 3);
Mat templateCorners = new Mat(4, 1, CvType.CV_32FC2);
Mat templateTransformResult = new Mat(4, 1, CvType.CV_32FC2);
templateCorners.put(0, 0, 0, 0);
templateCorners.put(1, 0, templateImage.cols(), 0);
templateCorners.put(2, 0, templateImage.cols(), templateImage.rows());
templateCorners.put(3, 0, 0, templateImage.rows());
//使用 perspectiveTransform 将模板图进行透视变以矫正图象得到标准图片
Core.perspectiveTransform(templateCorners, templateTransformResult, homography);
MatOfDMatch goodMatches = new MatOfDMatch();
goodMatches.fromList(goodMatchesList);
Mat matchOutput = new Mat(originalImage.rows() * 2, originalImage.cols() * 2, Highgui.CV_LOAD_IMAGE_COLOR);
Features2d.drawMatches(templateImage, templateKeyPoints, originalImage, originalKeyPoints, goodMatches
, matchOutput, new Scalar(0, 255, 0), new Scalar(255, 0, 0), new MatOfByte(), 2);
Highgui.imwrite(processDiagram, matchOutput);
}
}
测试使用
@Test
public void zhy() {
String templateFilePath = "D:/test/wd2.jpg";
String originalFilePath = "D:/test/wd4.jpg";
int i = ImageRecognition.matchImage(templateFilePath, originalFilePath, "D:/test/zhy.jpg");
System.out.println("匹配的像素点总数:" + i);
}
效果
二,部署到linux
下载opencv源码压缩包
上传到linux服务器,并解压
安装依赖包,采用yum命令安装,在终端机输入以下指令
yum install cmake gcc gcc-c++ gtk+-devel gimp-devel gimp-devel-tools gimp-help-browser zlib-devel libtiff-devel libjpeg-devel libpng-devel gstreamer-devel libavc1394-devel libraw1394-devel libdc1394-devel jasper-devel jasper-utils swig python libtool nasm build-essential ant
进入文件夹新建build
cd opencv-2.4.11
mkdir build
cd build
编译
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
make
sudo make install
生成jar
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTS=OFF ..
最后运行
make -j8
sudo make install
得到.so库文件和jar
cd /usr/local/share/OpenCV/java/