OpenCV 命令行应用程序无法在 macOS Mojave 下访问相机

     2023-02-19     140

关键词:

【中文标题】OpenCV 命令行应用程序无法在 macOS Mojave 下访问相机【英文标题】:OpenCV command line app can't access camera under macOS Mojave 【发布时间】:2019-09-28 18:12:33 【问题描述】:

我无法从命令行 OpenCV 程序访问 iMac 相机。 (我在 CodeRunner 下编译和运行程序,而不是 Xcode。)我读过 Mojave 在 Info.plist 中需要NSCameraUsageDescription,我认为我将它正确地嵌入到二进制文件中。我在编译标志中添加了-sectcreate __TEXT __info_plist Info.plist (which I learned about here),当我运行otool -X -s __TEXT __info_plist videotest | xxd -r(来自同一篇博文)时,它输出:

-?<?xml ve.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSCameraUsageDescription</key>
    <string>Uses camera to see vision targets</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>This app requires to access your microphone in order to access the camera</string>
</dict>
</plist>

(我添加了 NSMicrophoneUsageDescription 以防它试图打开麦克风和摄像头。)

这是我运行程序时的输出:

OpenCV version 4.1.0-dev
[ INFO:0] global /Users/steve/Documents/GitHub/ssteve-opencv/modules/videoio/src/videoio_registry.cpp (185) VideoBackendRegistry VIDEOIO: Enabled backends(5, sorted by priority): FFMPEG(1000); GSTREAMER(990); AVFOUNDATION(980); CV_IMAGES(970); CV_MJPEG(960)
[ INFO:0] global /Users/steve/Documents/GitHub/ssteve-opencv/modules/videoio/src/backend_plugin.cpp (248) getPluginCandidates VideoIO pluigin (GSTREAMER): glob is 'libopencv_videoio_gstreamer*.dylib', 1 location(s)
[ INFO:0] global /Users/steve/Documents/GitHub/ssteve-opencv/modules/videoio/src/backend_plugin.cpp (256) getPluginCandidates     - /usr/local/lib: 0
[ INFO:0] global /Users/steve/Documents/GitHub/ssteve-opencv/modules/videoio/src/backend_plugin.cpp (259) getPluginCandidates Found 0 plugin(s) for GSTREAMER
OpenCV: not authorized to capture video (status 0), requesting...
OpenCV: camera failed to properly initialize!
Unable to open camera

这意味着它正在请求访问,但我从来没有得到一个对话框,并且系统偏好设置 > 安全和隐私 > 相机下没有列出任何应用程序。

这是我正在运行的程序:

#include <iostream>

#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"

using namespace std;
using namespace cv;

int main(int argc, char *argv[]) 
    cout << "OpenCV version " << CV_VERSION << endl;
    VideoCapture cap;
    cap.open(0);
    if (!cap.isOpened()) 
        cerr << "Unable to open camera\n";
        return -1;
    

    Mat frame;
    for (;;) 
        cap >> frame;
        if (frame.empty()) 
            cerr << "Got blank frame\n";
            return -1;
        
        imshow("Live", frame);
        if (waitKey(5) >= 0)
        break;
    

    return 0;

这是编译器调用:

xcrun clang++ -x c++ -lc++ -o "$out" -std=c++11 -I/usr/local/include/opencv4 -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs -lopencv_videoio -lopencv_calib3d -lopencv_aruco -lopencv_xfeatures2d -lopencv_features2d -sectcreate __TEXT __info_plist Info.plist "$files[@]" "$@:1"

我错过了哪一块拼图?

(我知道这类似于Cannot access camera with opencv on Mac Mojave,但这个问题从未超出格式错误的 plist 文件。)


响应确保 ffmpeg 看到设备的建议:

$ ffmpeg -hide_banner -f avfoundation -list_devices true -i ""
[AVFoundation input device @ 0x7fed77d16dc0] AVFoundation video devices:
[AVFoundation input device @ 0x7fed77d16dc0] [0] FaceTime HD Camera (Built-in)
[AVFoundation input device @ 0x7fed77d16dc0] [1] Capture screen 0
[AVFoundation input device @ 0x7fed77d16dc0] [2] Capture screen 1
[AVFoundation input device @ 0x7fed77d16dc0] [3] Capture screen 2
[AVFoundation input device @ 0x7fed77d16dc0] AVFoundation audio devices:
[AVFoundation input device @ 0x7fed77d16dc0] [0] Built-in Microphone

【问题讨论】:

不知道它是否有帮助,但如果你想抓住一根稻草......你可以尝试使用brew install ffmpeg安装ffmpeghomebrew,然后检查可以使用此命令找到相机***.com/a/46768069/2836621 @MarkSetchell 感谢您的建议。 ffmpeg 似乎正在寻找相机。它确实适用于 Photo Booth。 (TIL:千万不要在咀嚼食物时启动 Photo Booth。) 你可以试试 sudo 吗?值得一试。 AFAIK 你根本不需要包含 plist,但我不确定。你也可以试试 Python 吗? sudo 是个好主意。我没有尝试过。但它没有用。但后来我尝试了 Python 的建议。第一次运行它时,我得到一个对话框,说终端正在请求访问相机,所以我授予了访问权限。之后,Python 程序开始工作。然后我尝试了命令行程序,它也工作了! 成功!! 【参考方案1】:

这不是最终的解决方案,但我通过安装任何请求访问您的相机的终端应用程序来解决它。然后您的 openCv c++ 程序将获得对 FaceTime 高清摄像头的访问权限。

例如,您可以通过以下方式安装 ImageSnap:

brew install imagesnap

imagesnap -w 1 shot.png

然后通过将出现的弹出窗口授予相机权限。

【讨论】:

【参考方案2】:

问题在于,无论出于何种原因,c++ 程序都没有请求摄像头访问权限。我在 cmets 中听取了@gerwin 的建议,尝试使用 Python。从终端运行该程序导致终端要求访问相机。一旦我同意,当从终端运行时,c++ 程序就能够访问相机。

就 CodeRunner 而言,我不确定如何让 CodeRunner 在虚拟环境下运行 Python 程序,因此我无法运行 Python OpenCV 程序来让它请求摄像头访问权限。所以目前我无法使用 CodeRunner 运行访问相机的 c++ 程序。

【讨论】:

从终端运行?真的吗?这只是解决方案的 1/3d。你不可能那样逐帧调试,叹息。我认为 OpenCV 有问题...我知道错误消息来自 exactly here. 。因为相机是通过终端工作的,所以我们无法在开发工具中到达那里是没有意义的。一定是openCV和许可时间相关的问题吗?你的想法?【参考方案3】:

这里有几个cmets...

尝试从我的 MacOS 开发环境运行 OpenCV 时看到的错误是:

OpenCV:未授权捕获视频(状态 0),请求... OpenCV:相机未能正确初始化!打开视频时出错 流或文件程序以退出代码结束:255

我知道这些词来自 OpenCV 库 here. 我最初的想法是这是一个 OpenCV 问题。通过更多的测试,我认为这是另一回事。正如其他人所指出的,MacOS 安全/权限问题。但这就是问题所在。

如果我转到 Mac Apple 图标(左上角) --> 系统偏好设置 --> 安全和隐私,我可以收集到很多信息。

检查相机图标。

在我的例子中,这显示了两个需要额外权限才能访问相机、终端和 Virtualbox 的应用程序(不确定浏览器会发生什么,Facetime?)我确实注意到,Xcode 没有列出这个列表。

当我点击麦克风时,我看到列出了不同的应用程序,包括 Xcode。

它是如何工作的?我确实做了很多测试,包括研究修改 Xcode 应用程序包的 Info.plist (Finder --> Applications Folder --> Xcode --> Rt click, Show Package Contents. Copy Info.plist save it else,通过 Xcode 修改它,重新提交。)注意:如果没有保留原始 Info.plist 的副本,请勿尝试此操作。完全失败。添加NSCameraUsageDescription 键/值完全失败。 Xcode 根本打不开。提醒不要丢失原始 Info.plist。

这整件事令人费解。为什么Apple允许我们通过终端访问相机而不是在Xcode中?那里的逻辑是什么?

我当然希望能够通过代码逐帧了解可能的设计问题。这不好玩。

所以有几件事要理解。

    是的,在程序成功编译为 Unix 可执行文件后,您可以使用相机在 MacOS 上运行 OpenCV 项目。您必须确保在上面的每张照片的安全和隐私中设置终端的权限。显然,您在开发工具(在我的情况下为 Xcode)中构建可执行文件,然后从项目 Build/Debug 文件夹中打开可执行文件。该应用程序在终端窗口中打开,并且正如 SSteve 所指出的那样可以正常工作。

    如果您真的想要进行一些视频/摄像头调试,您可以选择“预先录制”视频,然后在您的开发环境中打开该视频。此时您可以使用调试器。你们是如何逐帧分析的?这是我所知道的至少部分可行的唯一方法。

    (编辑更新 5/22/19...)哇。我刚刚意识到..您可以将调试器附加到正在运行的(终端)进程。您完全可以使用相机进行逐帧调试(只要程序编译为功能可执行文件)。现在这非常酷,让我获得了 98% 的功能。为此,启动终端可执行文件,然后转到 Xcode --> Debug --> Attach to Process。选择正在运行的应用程序,将断点添加到源代码并调试/单步执行。效果很好。

我开始我的 OpenCV 项目:

int main(int argc, char** argv)
    // Parse command line arguments
    CommandLineParser parser(argc,argv,keys);

    // Create a VideoCapture object & open the input file
    VideoCapture cap;
    if (parser.has("video"))
        cap.open(parser.get<String>("video"));
    
    else
        cap.open(0);
   ...

这是一种破解方法,但总比没有好。 (当然希望 Apple 将相机包含在 iOS 模拟器中,这将是解决此问题的另一种方法,叹息。)显然,很大程度上取决于您的项目将在哪里进行。最终我需要我的在 iPad 上运行;在 MacOS 上进行 Proveout,然后在 Swift 中包装代码等...

作为参考,我使用的是 macOS Mojave,10.14.4,MacBook 2.7GHz i7

PS。上面的安全首选项不显示具有相机访问权限的 Chrome。似乎很奇怪。我刚刚在 Chrome 中以this site... 测试了相机,它请求许可并完全按预期工作。目前尚不清楚这里发生了什么。

PS2。我是唯一一个在这个问题上file a bug report 的人吗?为方便起见,包含链接。谢谢。

【讨论】:

看来,对于修改 Xcode plist 方法现在无法在 macOS 10.15 上执行。我无法让它工作,即使修改。感谢您每次尝试并向 Apple 报告问题。有任何进展请告诉我们,谢谢!【参考方案4】:

版本:XCode 10.3MacOS Mohave 10.14.6OpenCV 4.1.1_2

OpenCV 项目在C++

将此类添加到您的项目中:

标头(.h):

class CameraIssue 


public:
    CameraIssue() 
    ~CameraIssue() 

    bool dealWithCamera();
;

.mm 文件。注意不是.cpp,而是.mm,因为我们要操作AVFoundation

bool CameraIssue::dealWithCamera()

    AVAuthorizationStatus st = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (st == AVAuthorizationStatusAuthorized) 
        return true;
    

    dispatch_group_t group = dispatch_group_create();

    __block bool accessGranted = false;

    if (st != AVAuthorizationStatusAuthorized) 
        dispatch_group_enter(group);
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) 

            accessGranted = granted;
            NSLog(@"Granted!");
            dispatch_group_leave(group);
        ];
    

    dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)));

    return accessGranted;

并且在访问VideoCapture之前,像这样调用这个方法:

CameraIssue _camIssue;
_camIssue.dealWithCamera(); //do whatever you need with bool return

您可能想知道 - 为什么我在使用 Objective-C++ 扩展 (.mm) 时创建 C++ 类?

为了创建 Objective-C 类,我可能需要导入 Foundation 框架并导入这给了我很多关于重复符号的错误,因为 Foundation 和我使用的第 3 方库共享很多名称。所以我创建了C++ 类,但带有.mm 扩展名,因此我可以导入AVFoundation 框架并授予相机访问权限。

方法dealWithCamera() 远非完美,但它完全符合我的需求。随意扩展、优化、添加回调等。

【讨论】:

【参考方案5】:

我们可以修改 TCC.db。在 10.14 或 10.15 中打开 Terminal.app:

/usr/bin/sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db "REPLACE INTO access VALUES('kTCCServiceCamera','com.krill.CodeRunner',0,1,1,NULL,NULL,NULL,'UNUSED',NULL,0,1602129687);"

在 11.x 中:

/usr/bin/sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db "REPLACE INTO access VALUES('kTCCServiceCamera','com.krill.CodeRunner',0,2,0,1,NULL,NULL,NULL,'UNUSED',NULL,0,1608354323);"

【讨论】:

【参考方案6】:

通过 *** 和 GitHub 上的一系列建议,我终于能够解决这个问题。这是一个痛苦的错误,虽然在 MacOS Mojave 之前它运行良好,但我试图让我的代码再次运行,这让我一天都白费了。

解决方案

Info.plist 文件与NSCameraUsageDescription 字段作为suggested 放在您的Target 的Products/Build 目录中(在Xcode 项目的左窗格中右键单击Product 并单击“在Finder 中显示”)。

通过将Copy Files 添加到“目标”的Build Phases 下的Copy Files 列表并将目标更改为“产品”,自动将Info.plist 复制/粘贴到您的构建目录(在此suggestion 之后)的过程目录”和“。”的子路径

结果

Target 的 Unix 可执行二进制文件随后将请求访问摄像头的权限,并且在获得同意后,该二进制文件将被添加到允许访问摄像头的应用程序列表中,该应用程序位于 System Preferences &gt; Privacy &gt; Camera 中。 仅供参考:要强制清除此列表,请在 Terminal 中键入 tccutil reset Camera 您可能需要运行 Target 几次,然后系统会提示您授予权限/访问相机。

问题

实例化 cv::VideoCapture(0) 对象以访问相机视频流会引发以下错误,即使代码在 Mojave 之前的 MacOS 版本中运行良好

OpenCV:未授权捕获视频(状态 0),请求... OpenCV:相机无法正确初始化!

原因

MacOS Mojave 加强了隐私保护,现在要求应用程序在访问相机之前明确提示并寻求许可,如 here 所述。

无效的建议

以下各种 *** posts 中给出的建议没有成功强制构建的二进制文件提示访问相机的权限: - 将Info.plist 添加到您的项目目录 - 在Build Settings &gt; Packaging &gt; Info.plist File下设置Info.plist的路径 - 在目标的General &gt; Identity &gt; Choose Info.plist File... 中选择它

可能有帮助的建议

opencv 已关闭的 GitHub issue 中所示,在 19 年 4 月左右对 libopencv 进行了一些更改,这也可能有助于在构建目录中使用可用的 Info.plist 以提示用户访问相机的权限。所以我还使用brew upgrade 将我的opencv 升级到了最新的稳定版4.1.0

附:我正在运行 MacOS Mojave 10.14.5、Xcode 10.2.1 和 OpenCV 4.1.0

【讨论】:

【参考方案7】:

我找到了解决方法:

首先,重置你的相机规则:

tccutil reset Camera

接下来,我运行了第 3 方软件从终端访问摄像头。通过运行以下命令:

brew install imagesnap
imagesnap -w 1 snapshot.png

有人问我是否要允许终端访问我的相机。我点击“是”。现在我的 C++ 程序现在可以从终端访问相机了。

注意:ZipZit 显示的图片非常相似,只是我没有在相机下列出终端。

但在运行 3rd 方程序后,。然后将其添加到列表中。

【讨论】:

【参考方案8】:

我们正在 opencv 4.1.1-pre 上运行这个确切的问题。我们通过回滚到 4.0.1 解决了这个问题。

【讨论】:

请提供更多细节。 4.1.1-pre 是什么导致了 4.0.1 修复的问题? 很遗憾,由于时间限制,我们无法确定原因。【参考方案9】:

您的 OpenCV 包可能已损坏。以上解决方案都没有帮助我,我把我的解决方案放在here。也许它对你也有帮助。

【讨论】:

macos命令行安装ipa

macos命令行安装ipa苹果发神经后itunes已经无法在安装app了,如果有知道的兄弟可以告诉我啊ideviceinstaller使用这个开源项目可以在macos下安装appbrewinstallideviceinstaller#使用brew安装ideviceinstalleridevice_id-l#查看链接的设备idideviceinstaller-l#... 查看详情

在 macOS 中通过命令行与 Siri 交互

...我不想通过使用Siri来打扰安静,所以我通常使用与Reminder应用程序集成的Alfred工作流程,或者直接使用Reminders应用程序。但是,两者都有一个相当笨拙的界 查看详情

苹果macos怎么用命令行终端打开app应用程序

...打开finder。2、打开之后,在finder左侧的工具栏中,选择应用程序。3、应用程序中选择实用工具。4、实用工具中找到终端,这就是所说的Terminal。5、打开之后,弹出Terminal窗口,在这里面可以输入命令符,来完成不同命令。参考... 查看详情

苹果macos怎么用命令行终端打开app应用程序

...的使用Mac命令行终端。第二种:1.打开finder,然后点开“应用程序”,在搜索栏中输入“终端”,如果是英文版的mac那么输入“Terminal”搜索。2.打开终端后在终端的Dock上面的图标上点击鼠标右键。3.把鼠标移动到“选项”--->... 查看详情

苹果macos怎么用命令行终端打开app应用程序

...常的使用Mac命令行终端。第二种:1.打开finder,然后点开“应用程序”,在搜索栏中输入“终端”,如果是英文版的mac那么输入“Terminal”搜索。2.打开终端后在终端的Dock上面的图标上点击鼠标右键。3.把鼠标移动到“选项”--->... 查看详情

macos下命令行通过ndk编译android下可以执行的elf程序(并验证opencl的调用)(代码片段)

源码如下,实现把一个JPG保存成灰度图格式的BMP1//jpg2bmp.cpp2#include<stdio.h>3#include<inttypes.h>4#include<opencv2/opencv.hpp>5#include<opencv2/core.hpp>67#ifndefP8#defineP(format,...)do910print 查看详情

如何在 MacOS 上切换命令行工具

】如何在MacOS上切换命令行工具【英文标题】:HowtoswitchcommandlinetoolsonMacOS【发布时间】:2018-06-0512:57:28【问题描述】:我在我的mac上安装了两个命令行工具。所以我想切换命令行工具。我该怎么做?我尝试从Xcode首选项>位置>... 查看详情

国产手机插入macos系统中无法被识别的解决方法

一些国产手机插入macos系统中无法被识别,在命令行输入 system_profilerSPUSBDataType在,然后将魅蓝note的vendorid添加至~/.android/adb_usb.ini文件中,然后依次执行adbkill-server  adbstart-server即可进入adbshell。  上述中的vendorid... 查看详情

用于在 Travis CI 上进行测试的代码签名 macOS 应用程序

】用于在TravisCI上进行测试的代码签名macOS应用程序【英文标题】:CodeSigningmacOSAppforTestingonTravisCI【发布时间】:2020-03-1807:38:03【问题描述】:我正在尝试在TravisCI上向我的macOS应用程序添加自动化测试,但无法确定代码签名。我... 查看详情

C 中的 FTDI D2XX API 在命令行控制台上工作,但在由 Xcode 和 Swift 编程在 macOS 上构建的应用程序中始终返回零

...令行控制台上工作,但在由Xcode和Swift编程在macOS上构建的应用程序中始终返回零【英文标题】:FTDID2XXAPIinCworksoncommand-lineconsolebutalwaysreturnszeroinapplicationwhichisbuiltbyXcodeandSwiftprogrammingonmacOS【发布时间】:2019-10-2410:03:22【问题描述... 查看详情

无法在 macOS 上的 Anaconda3 python3.6 上安装 OpenCV3

】无法在macOS上的Anaconda3python3.6上安装OpenCV3【英文标题】:Can\'tinstallOpenCV3onAnaconda3python3.6onmacOS【发布时间】:2017-06-1122:51:47【问题描述】:我正在尝试在macOS10.11.6上的Anaconda3python3.6上安装OpenCV3.2.0,但我找不到方法。我的Anaconda... 查看详情

如何在 MacOS 上使用 OpenCV 链接 C++ 程序 [重复]

】如何在MacOS上使用OpenCV链接C++程序[重复]【英文标题】:HowtolinkaC++programusingOpenCVonMacOS[duplicate]【发布时间】:2017-08-0906:41:24【问题描述】:我是openCV的新手。我刚刚从Github下载了openCV的源码,并安装在桌面(MacOS)上。现在我... 查看详情

mips64el-linux-android-g++:错误:无法识别的命令行选项“-mfpu=neon”

...与NDK和OpenCV相关的项目。该项目构建无误。但是当我运行应用程序时,我得到了错误:m 查看详情

在 MacOS 的命令行中使用 Android Studio 的内置 Java

】在MacOS的命令行中使用AndroidStudio的内置Java【英文标题】:UsingAndroidStudio\'sbuilt-inJavaonthecommandlineinMacOS【发布时间】:2017-08-2812:49:24【问题描述】:这里有很多关于在Mac上安装Java以及让AndroidStudio使用正确版本的信息(很多内容... 查看详情

如何在mac上安装命令行工具?

...lina以及已安装新操作系统的Mac用户现在可以从XcodeIDE安装命令行工具,而无需安装整个Xcode软件包或开设Apple开发人员帐户。在本文中,我们介绍了如何安装此可选且非常有用的命令行工具包。 XcodeforMac https://www.macjb.com/ma... 查看详情

Charles App - 用于切换 macOS 代理的命令行

】CharlesApp-用于切换macOS代理的命令行【英文标题】:CharlesApp-commandlinetotogglemacOSproxy【发布时间】:2018-01-1123:39:10【问题描述】:我在使用CharlesApp时遇到浏览器同步问题。我可以让浏览器同步工作的唯一方法是关闭charles重新加... 查看详情

OpenCV 在调整大小功能时崩溃

...3-05-2120:04:20【问题描述】:我在使用一些OpenCV代码的iPhone应用程序中遇到了崩溃。异常在以下行抛出:cv::Matbackup_f=m_color_feature;cv::Matbackup_t=m_map;doubler=m_options.m_opt_height/m_color_ 查看详情

macOS Mojave 上的命令行/终端错误

】macOSMojave上的命令行/终端错误【英文标题】:Commandline/TerminalerroronmacOSMojave【发布时间】:2019-03-1506:44:48【问题描述】:更新到macOSMojave后,我的终端错误显示为:xcrun:错误:无效的活动开发者路径(/Library/Developer/CommandLineTools... 查看详情