【问题标题】:C++ OpenCV imread not working in AndroidC++ OpenCV imread 在 Android 中不起作用
【发布时间】:2014-11-20 10:51:29
【问题描述】:

我正在尝试在我的 C++ 代码中读取图像

LOGD("Loading image '%s' ...\n", (*inFile).c_str());;
Mat img = imread(*inFile, CV_LOAD_IMAGE_GRAYSCALE);
CV_Assert(img.data != 0);

并得到以下输出:

09-25 17:08:24.798: D/IRISREC(12120): Loading image '/data/data/com.example.irisrec/files/input/osoba1.jpg' ...
09-25 17:08:24.798: E/cv::error()(12120): OpenCV Error: Assertion failed (img.data != 0) in int wahet_main(int, char**), file jni/wahet.cpp, line 4208

文件存在。但奇怪的是,如果我尝试使用根文件浏览器预览图像,它只是黑色的。我手动复制了那里的文件。

编辑:

代码在 .png 和 .jpg 格式的 Windows 下运行良好。我只是想将 Iris Recognition 的现有 C++ 项目移植到 Android。

【问题讨论】:

    标签: android c++ opencv imread


    【解决方案1】:

    imread()根据文件的内容确定文件的类型,而不是根据文件扩展名。如果文件头损坏,则该方法失败是有道理的。

    您可以尝试以下几点:

    • 将这些图像复制回计算机,看看它们是否可以被其他应用程序打开。它们有可能在设备中损坏;
    • 确保该位置有文件并且您的用户有权读取该文件;
    • 测试图像类型(jpg、png、tiff、bmp、...);

    • 出于测试目的,最好直接一些。摆脱inFile

    例子:

    Mat img = imread("/data/data/com.example.irisrec/files/input/osoba1.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    if (!img.data) {
        // Print error message and quit
    }
    

    【讨论】:

    • 当我将它们复制回来时,它们没有损坏,并且我没有看到 Android 内部存储的权限有任何问题。我试过jpg和png。两者都不起作用。代码在windows下运行良好。此外,我不想更改 C++ 代码,因为我正在尝试将整个项目移植到 Android。这是一个虹膜识别工具包,有太多代码行无法适应。而且我确信文件路径是正确的。
    【解决方案2】:

    调试时,首先尝试获取更多关于问题的数据。

    • 不幸的是imread() 没有提供任何错误信息。 docs 只是说它会失败“因为丢失文件、不正确的权限、不受支持或无效的格式”。
    • 如果可以,请使用调试器单步执行代码。你能说出它失败的地方吗?
    • 搜索已知问题,stackoverflow.com/search?q=imread,例如imread not working in OpenCV.

    然后尽可能多地提出假设。对于每一个,想一个方法来测试它。例如

    • 图像文件格式错误(如@karlphillip 提供的那样)。 -- 看看其他软件能不能打开文件。
    • 图像文件不是受支持的格式。 -- 验证您桌面上的文件格式。测试桌面 OpenCV 是否可以读取它。检查文档以验证 AndroidCV 可以读取的图像格式。
    • 图像文件不在预期的路径中。 -- 编写代码测试该路径是否有文件,并验证其长度。
    • 图像文件没有读取权限。 -- 编写代码打开文件进行读取。
    • imread() 参数有问题。 -- 尝试默认第二个参数。

    【讨论】:

    • 请看我对其他答案的评论。
    • 哦,是的,我会尝试调试 C++ 代码。还不能正确设置调试器
    【解决方案3】:

    我只能通过在代码中复制图像文件来解决这个问题。我首先将它们存储在我的资产文件夹中,然后将它们复制到this example 之后的内部存储中。 如果有人可以向我解释这一点,请这样做。

    【讨论】:

    • imread 无法从 zip 文件(您的 apk)中读取。这就是为什么你必须先把它复制到别处。
    • 并重新考虑您的答案 - 我不确定 data/data 文件夹是否与 apk 有任何关系?
    【解决方案4】:

    这可能是权限问题。在 Android 6.0 或更高版本中,您必须像这样在 Activity 类中请求 Java 代码的权限。还要确保在您的 AndroidManifest.xml 中有以下行:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

    在您的活动文件中添加以下内容:

    if (PermissionUtils.requestPermission(
                        this,
                        HOME_SCREEN_ACTIVITY,
                        Manifest.permission.READ_EXTERNAL_STORAGE)) {
         Mat image = Imgcodecs.imread(filePath,Imgcodecs.IMREAD_COLOR);
    }
    

    我花了很长时间才找到这个,而且我之前一直在获取 Mat 对象 null

    【讨论】:

      猜你喜欢
      • 2011-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-19
      • 2020-03-13
      • 2015-04-25
      相关资源
      最近更新 更多