在Windows下编译OpenCV(如在其他系统下编译,请自行搜索)
CMake:
- 下载zip版本“cmake-3.xx-win64-x64.zip”
- 解压到指定目录并添加bin所在目录到环境变量。
- 在终端输入“cmake –help”或 “cmake –version”查看是否配置成功。
MinGW:
https://sourceforge.net/projects/mingw-w64/files/
- 推荐下载 离线版本“x86_64-posix-seh”
- 解压到指定目录并将bin目录加入到环境变量
- 在终端输入 “gcc –version”。查看是否安装成功。
OpenCV
本次 Windows 环境的安装,因此下载OpenCV-4.6.0 Windows 版。
双击下载好的exe文件,程序会生成 opencv 文件夹。
这个 opencv 文件夹就是我们后面的编译源文件。
新建一个文件夹 build_for_vscode ,用于存放我们后面的编译结果。
下载OpenCV运行库
下载OpenCV – 4.7.0的Windows版本,运行并制定解压目录。
(注意,如果这里选择其他版本,请务必在后面的项目依赖用也配置对应的4.7.0版本。)
然后配置系统的环境变量Path,添加“opencv/build/java/x86/opencv_java470.dll”。
否则会报类似如下的错误:
Exception in thread "JavaFX Application Thread" java.lang.UnsatisfiedLinkError: no opencv_java470 in java.library.path: D:\Java\jdk-17.0.8\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files (x86)\VMware\VMware Workstation\bin\;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;C:\Program Files\Git\cmd;C:\Program Files\TortoiseGit\bin;C:\Program Files (x86)\Microsoft SQL Server\160\Tools\Binn\;C:\Program Files\Microsoft SQL Server\160\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\Program Files\Microsoft SQL Server\160\DTS\Binn\;C:\Program Files\Docker\Docker\resources\bin;D:\Java\jdk-1.8\bin;C:\Program Files\JetBrains\IntelliJ IDEA 2021.2\plugins\maven\lib\maven3\bin;C:\Program Files\nodejs\;C:\Windows\System32\Wbem;D:\Redis-x64-3.2.100;C:\Program Files\Go\bin;C:\Program Files\Go\bin;C:\Program Files\OpenSSL-Win64\bin;D:\MinGW-12.2.0\bin;D:\gradle-8.5\bin;D:\hkbea\20231201.PBWMS Enhancement\RmTool\opencv\build\java\x64;C:\Program Files\Tesseract-OCR;C:\Users\cp0612\AppData\Local\Microsoft\WindowsApps;C:\Users\cp0612\AppData\Roaming\npm;C:\Windows\System32\Wbem;C:\Users\cp0612\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\cp0612\go\bin;C:\Program Files\CMake\bin;. at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2429) at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:818) at java.base/java.lang.System.loadLibrary(System.java:1989) at com.hkbea.pbwms.rmtool.MainApp$1.run(MainApp.java:151) at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run$$$capture(InvokeLaterDispatcher.java:96) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184) at java.base/java.lang.Thread.run(Thread.java:833)
在项目中引入依赖
依赖版本可以查看这里:https://mvnrepository.com/artifact/org.bytedeco/opencv
// https://mvnrepository.com/artifact/org.bytedeco/opencv implementation group: 'org.bytedeco', name: 'opencv', version: '4.7.0-1.5.9'
请务必注意version需要和所下载的OpenCV运行版本号一致。
示例代码
// 加载OpenCV库 System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // 读取源图像和模板图像 Mat sourceImage = Imgcodecs.imread("screenshot.png"); Mat templateImage = Imgcodecs.imread("template.png"); // 创建结果矩阵 int resultCols = sourceImage.cols() - templateImage.cols() + 1; int resultRows = sourceImage.rows() - templateImage.rows() + 1; //Mat resultImage = new Mat(resultRows, resultCols, CvType.CV_32F); Mat resultImage = new Mat(resultRows, resultCols, CvType.CV_32FC1); // 执行模板匹配 // 注意:这里只是一个简单的示例,实际的模板匹配需要根据具体需求进行参数调整和处理 /** * result 参数:用于存储匹配结果的矩阵,您可以检查这个矩阵来了解匹配的情况。 * method 参数:指定匹配方法。常见的匹配方法包括 Imgproc.TM_SQDIFF、 Imgproc.TM_SQDIFF_NORMED、Imgproc.TM_CCORR、Imgproc.TM_CCORR_NORMED、Imgproc.TM_CCOEFF 和 Imgproc.TM_CCOEFF_NORMED,它们会影响到匹配结果的精确度和准确度。 * mask 参数:指定模板的掩码,可以使用它来限制匹配区域,提高匹配的准确度。 * scale 和 scaleFactor 参数:指定搜索图像和模板图像的缩放比例,可以通过调整这些参数来适应不同尺寸的图像。 */ Imgproc.matchTemplate(sourceImage, templateImage, resultImage, Imgproc.TM_CCOEFF_NORMED); // --------- 处理匹配结果 ---------- //匹配阈值处理 //double thresholdValue = 0.8; //Core.compare(resultImage, new Scalar(thresholdValue), resultImage, Core.CMP_GE); // 寻找最大和最小匹配值及其位置 Core.MinMaxLocResult mmr = Core.minMaxLoc(resultImage); //比对匹配到的图像结果 double threshold = 0.2; // 设置匹配阈值 if (mmr.maxVal >= threshold) { //log.info("匹配成功"); System.out.println("匹配成功"); Point maxLoc = mmr.maxLoc; // 在原始图像中画出匹配结果的矩形框 Rect matchRect = new Rect((int)maxLoc.x, (int)maxLoc.y, templateImage.cols(), templateImage.rows()); Imgproc.rectangle(sourceImage, matchRect.tl(), matchRect.br(), new Scalar(0, 255, 0), 2); // 将 Mat 对象转换为 BufferedImage //imageView.setImage(SwingFXUtils.toFXImage(matToBufferedImage(resultImage),null)); BufferedImage resultBuffImage = Mat2BufImg(sourceImage,".png"); WritableImage rersultWritableImage = SwingFXUtils.toFXImage(resultBuffImage,null); File resultImageFile = new File("outputImage.png"); try { ImageIO.write(SwingFXUtils.fromFXImage(rersultWritableImage, null), "png", resultImageFile); System.out.println("屏幕截图已保存到: " + resultImageFile.getAbsolutePath()+"; 大小="+resultImageFile.length()); } catch (IOException e) { System.out.println("无法保存屏幕截图: " + e.getMessage()); } imageView.setImage(rersultWritableImage); } else { // 未找到匹配 //log.info("匹配失败"); System.out.println("匹配失败"); } // 释放资源 sourceImage.release(); templateImage.release(); resultImage.release();