Приложение командной строки OpenCV не может получить доступ к камере в MacOS Mojave - PullRequest
5 голосов
/ 10 мая 2019

Я не могу получить доступ к камере iMac из программы OpenCV из командной строки. (Я компилирую и запускаю программу под CodeRunner, а не с Xcode.) Я читал, что Mojave требует NSCameraUsageDescription в Info.plist, и я думаю, что правильно встраиваю его в двоичный файл. Я добавил -sectcreate __TEXT __info_plist Info.plist (, о котором я узнал здесь ) к флагам компиляции, и когда я запускаю 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}"

Какая часть головоломки мне не хватает?

(я знаю, что это похоже на Невозможно получить доступ к камере с opencv на 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

Ответы [ 5 ]

3 голосов
/ 16 мая 2019

Проблема заключалась в том, что программа c ++ по какой-либо причине не запрашивала доступ к камере.Я воспользовался советом @gerwin в комментариях, чтобы попробовать его с Python.Запуск этой программы из терминала привел к тому, что терминал запросил доступ к камере.После того, как я это подтвердил, программа c ++ смогла получить доступ к камере при запуске из терминала.

Что касается CodeRunner, я не уверен, как заставить CodeRunner запускать программы Python в виртуальной среде, поэтому я не смогНе удалось запустить программу Python OpenCV, чтобы она запрашивала доступ к камере.Поэтому в настоящее время я не могу использовать CodeRunner для запуска программы на языке c ++, которая обращается к камере.

1 голос
/ 19 мая 2019

Несколько комментариев здесь ...

Ошибка при попытке запустить OpenCV из моей среды разработки MacOS:

OpenCV: запрещен захватвидео (статус 0), запрос ... OpenCV: камера не удалось правильно инициализировать!Ошибка при открытии видеопотока или файла. Программа завершилась с кодом выхода: 255

Я знаю, что эти слова происходят из библиотеки OpenCV здесь. Сначала я думал, что это проблема OpenCV.Немного больше испытаний, я думаю, что это что-то еще.Как уже отмечалось, проблема безопасности / разрешений MacOS.Но вот беда.

Если я зайду в Mac Apple Icon (Верхний левый угол) -> Системные настройки -> Безопасность и конфиденциальность, я смогу получить много информации.

Mac Systems Preferences

Проверьте значок камеры.

Security and Privacy Camera

В моем случае это два приложения, которым требуются дополнительные разрешения для доступа к камере: терминал и виртуальная коробка (не знаю, что происходит с браузером,Facetime?) Замечу, Xcode не попал в этот список.

Когда я нажимаю на Микрофон, я вижу разные приложения в списке, ВКЛЮЧАЯ Xcode.

Security and Privacy Microphone

Как это вообще работает?Я провел много испытаний, в том числе исследовал изменение Info.plist для пакета приложения Xcode (Finder -> Папка приложений -> Xcode -> Rt click, Показать содержимое пакета. Скопируйте Info.plist и сохраните его в другом месте,измените это через XCode, повторно отправьте.) Примечание: не пытайтесь это делать, не сохраняя копию исходного Info.plist.Полный провал.Добавление NSCameraUsageDescription ключ / значение было полным провалом.Xcode вообще не открывается.Напоминание НЕ теряйте оригинальный Info.plist.

Все это сбивает с толку.Почему Apple позволяет нам получать доступ к камере через терминал, но не в Xcode?Какая там логика?

Я уверен, что хотел бы иметь возможность пошагово выполнять код, чтобы покадрово понимать возможные проблемы проектирования.Это просто не весело.

Итак, пара вещей, которые нужно понять.

  1. Да, вы можете запустить проект OpenCV на MacOS с вашей камерой после успешной компиляции программы в исполняемый файл Unix.Вы должны убедиться, что разрешения для Терминала установлены в разделе «Безопасность и конфиденциальность» для каждой фотографии выше.Очевидно, вы строите исполняемый файл в своем инструменте разработки (в моем случае Xcode), а затем открываете исполняемый файл из папки проектов Build / Debug.Приложение открывается в окне терминала и работает отлично, как отмечает SSteve.

  2. Если вы действительно хотите выполнить отладку видео / камеры, у вас есть возможность предварительно записать видео, а затем открыть это видео в своей среде разработки.В этот момент вы можете использовать отладчик.Как вы, ребята, делаете покадровый анализ?Это единственный известный мне способ, который по крайней мере частично сработает.

  3. (редактировать обновление 22.05.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, затем обернуть код в Swift и т.д ...

Для справки, я использую macOS Mojave, 10.14.4, MacBook 2.7GHz i7

PS. Приведенные выше настройки безопасности не отображают Chrome с доступом к камере. Кажется странным Я только что проверил камеру на этом сайте ... в Chrome, и он запрашивает разрешение и работает точно так, как ожидалось. Не ясно, что здесь происходит.

PS2. Я единственный, кто подал сообщение об ошибке по этому вопросу? Ссылка включена для вашего удобства. Благодарю.

0 голосов
/ 18 июля 2019

Мы получаем именно эту проблему на opencv 4.1.1-pre.Мы решили проблему, откатившись до 4.0.1.

0 голосов
/ 05 июля 2019

Я нашел способ обойти это:

Сначала сбросьте правила вашей камеры:

tccutil reset Camera

Затем я запустил стороннее программное обеспечение для доступа к камере из терминала.Запустив следующее:

brew install imagesnap
imagesnap -w 1 snapshot.png

Меня спросили, хочу ли я разрешить терминалу доступ к моей камере.Я нажал «Да».И теперь моя программа на C ++ теперь может получить доступ к камере из терминала.

Примечание: показанные ZipZit изображения были очень похожи, за исключением того, что у меня не было терминала, указанного в разделе камеры.

Но после запуска сторонней программы,.затем он был добавлен в список.

0 голосов
/ 22 июня 2019

Я наконец смог решить эту проблему, следуя цепочке рекомендаций через Stackoverflow и GitHub.Это была болезненная ошибка, которая сожгла мой день, пытаясь заставить мой код работать снова, хотя он работал нормально до MacOS Mojave.

Решение

Поместите Info.plist файл с полем NSCameraUsageDescription, как предложил в каталоге Products / Build вашей цели (щелкните правой кнопкой мыши Product на левой панели в проекте Xcode и нажмите «Показать в Finder»).

  • Автоматизируйте этот процесс копирования / вставки Info.plist в каталог Build (следуя этому предложению ), добавив его в список Copy Files в Build Phases вашего«Target» и изменение «Destination» на «Product Directory» и Subpath на «.»запросите разрешение на доступ к камере, и после получения разрешения двоичный файл будет добавлен в список приложений, которым разрешен доступ к камере, доступных в System Preferences > Privacy > Camera.
    • К вашему сведению: чтобы принудительно очистить этот список, введите tccutil reset Camera в Terminal
  • . Возможно, вам придется запустить цель несколько раз, прежде чем вам будет предложено разрешение/ Доступ к камере.

Проблема

Создание объекта cv::VideoCapture(0) для доступа к видеопотоку с камеры приводит к следующей ошибке, даже если код был запущеннормально в версии MacOS до Mojave

OpenCV: не авторизован для захвата видео (статус 0), запрос ...
OpenCV: камера не смогла правильно инициализироваться!

Причина

MacOS Mojave усилил защиту конфиденциальности, которая теперь требует, чтобы приложения явно запрашивали и запрашивали разрешение у доступа к камере, как объяснено здесь .

Предложения, которые не работали

Ниже предложений, приведенных в различных Stackoverflow posts , не удалось принудительно заставить встроенный двоичный файл запрашивать разрешение наполучить доступ к камере: - добавив Info.plist в каталог проекта - установить путь к Info.plist в Build Settings > Packaging > Info.plist File или - выбрать его в General > Identity > Choose Info.plist File... вашей цели

Предложения, которые могли бы помочь

Как указано в opencv закрытом выпуске GitHub , в libopencv около апреля 1919 года были внесены некоторые изменения, которые моглитакже возможно облегчило использование доступного Info.plist в каталоге сборки, чтобы запросить у пользователя разрешение на доступ к камере.Поэтому я также обновил свой opencv до последней стабильной версии 4.1.0, используя brew upgrade.

PS Я использую MacOS Mojave 10.14.5, Xcode 10.2.1 и OpenCV 4.1.0

...