Java detectMultiScale中的OpenCV断言错误
我正在尝试在OpenCV中测试面部识别API。我已经导入了提供的Java detectMultiScale中的OpenCV断言错误,java,opencv,Java,Opencv,我正在尝试在OpenCV中测试面部识别API。我已经导入了提供的.jar,它正确加载了DLL。函数将加载DLL。我还在目录中提供了XML文件:src\main\resources\opencv 我仍然得到一个错误: OpenCV Error: Assertion failed (!empty()) in cv::CascadeClassifier::detectMultiScale, file C:\builds\master_PackSlaveAddon-win64-vc12-static\
.jar
,它正确加载了DLL。函数将加载DLL。我还在目录中提供了XML文件:src\main\resources\opencv 我仍然得到一个错误:
OpenCV Error: Assertion failed (!empty()) in cv::CascadeClassifier::detectMultiScale, file C:\builds\master_PackSlaveAddon-win64-vc12-static\opencv\modules\objdetect\src\cascadedetect.cpp, line 1639
我研究过这个错误,每次解决方案似乎都与资源有关。这很可能是一个非常简单的问题,但我现在还没有解决。查看OpenCV源代码,我们可以找到以下内容:
- 在内部,
实现使用类CascadeClassifier
加载数据。[]FileStorage
- 类
在内部使用函数FileStorage
打开数据文件。[][]fopen(…)
由于资源加载程序(
“/D:/Programming/workspace/github/project1/HomeServer/target/classes/opencv/ha)返回的路径arcascade_frontalface_alt.xml“
)有点奇怪,包含前导斜杠,第一个怀疑导致打开文件时出现一些问题
我编写了一个简单的小测试,用Visual C++检查这一点:
#include <cstdio>
#include <iostream>
bool try_open(char const* filename)
{
FILE* f;
f = fopen(filename, "rb");
if (f) {
fclose(f);
return true;
}
return false;
}
int main()
{
char const* path_1("/e:/foo.txt");
char const* path_2("e:/foo.txt");
std::cout << "fopen(\"" << path_1 << "\") -> " << try_open(path_1) << "\n";
std::cout << "fopen(\"" << path_2 << "\") -> " << try_open(path_2) << "\n";
return 0;
}
因此,这条道路是罪魁祸首。根据,一种与平台无关的方法是修改代码以生成有效路径,如下所示:
// ...
ClassLoader loader = Thread.currentThread().getContextClassLoader();
String xmlResource = loader.getResource("opencv/haarcascade_frontalface_alt.xml").getPath();
File file = new File(xmlResource);
xmlResource = file.getAbsolutePath());
// ...
CascadeClassifier faceDetector = new CascadeClassifier(xmlResource);
if(faceDetector.empty()){
ErrorUtils.println("cascade classifier is empty");
return false;
}
// ...
看起来您的分类器从未初始化过。加载资源之后和构建级联分类器之前,
xmlResource
变量的内容是什么?@DanMašek ErrorUtils类是一个简单的调试相关类,尽管您可能会推断出这一点。无论如何,它打印出XML文件的路径:“/D:/Programming/workspace/github/project1/HomeServer/target/classes/opencv/haarcascade\u frontalface\u alt.XML”
Aha。我认为问题在于路径开头的第一个正斜杠。OpenCV内部使用FileStorage
类加载数据。此类使用fopen
打开文件。我只是在VisualC++中做了一个小测试,它无法用这样的路径打开文件。删除前导斜杠应该可以解决这个问题。请参阅本文,了解如何以独立于平台的方式解决此问题。我的朋友,工作非常出色。除非你愿意,否则我会发布一个答案。这个很好用。另外,我感谢您在C++中这样做,因为我对java相对来说是新的):代码>字符串XMLRealEppsAtdie=新文件(Looer-.GETRealver(“opencv/HaasCACADFEXTALFACEFEAUR.ALT.XML”).GETPATH())代码>没问题,我已经十多年没有真正编写任何Java了,所以这主要是查找Java文档,然后挖掘OpenCV源代码(因为错误发生在那里),并将其缩小到一个可以复制此代码的最小测试用例。
fopen("/e:/foo.txt") -> 0
fopen("e:/foo.txt") -> 1
// ...
ClassLoader loader = Thread.currentThread().getContextClassLoader();
String xmlResource = loader.getResource("opencv/haarcascade_frontalface_alt.xml").getPath();
File file = new File(xmlResource);
xmlResource = file.getAbsolutePath());
// ...
CascadeClassifier faceDetector = new CascadeClassifier(xmlResource);
if(faceDetector.empty()){
ErrorUtils.println("cascade classifier is empty");
return false;
}
// ...