15 votes

L'application de ligne de commande OpenCV ne peut pas accéder à la caméra sous macOS Mojave

Je n'arrive pas à accéder à la caméra de l'iMac depuis un programme OpenCV en ligne de commande. (Je compile et exécute le programme sous CodeRunner, et non Xcode.) J'ai lu que Mojave requiert que NSCameraUsageDescription dans Info.plist et je pense l'intégrer correctement dans le binaire. J'ai ajouté -sectcreate __TEXT __info_plist Info.plist ( dont j'ai appris l'existence ici ) aux drapeaux de compilation et lorsque j'exécute otool -X -s __TEXT __info_plist videotest | xxd -r (du même article de blog) il sort :

-?<?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>

(J'ai ajouté NSMicrophoneUsageDescription au cas où il essayait d'ouvrir le microphone en même temps que la caméra).

Voici le résultat lorsque j'exécute le programme :

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

Cela implique une demande d'accès, mais je n'obtiens jamais de dialogue et aucune application n'est répertoriée dans Préférences système > Sécurité et confidentialité > Caméra.

Voici le programme que j'exécute :

#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;
}

C'est l'invocation du compilateur :

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}"

Quelle pièce du puzzle me manque-t-il ?

(Je sais que c'est similaire à Impossible d'accéder à la caméra avec opencv sur Mac Mojave mais cette question n'est jamais allée au-delà d'un fichier plist malformé).


En réponse à la suggestion de s'assurer que ffmpeg voit le périphérique :

$ 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

1voto

Pacific Stickler Points 944

J'ai finalement réussi à résoudre ce problème en suivant une chaîne de recommandations sur Stackoverflow et GitHub. C'était un bug douloureux qui a brûlé ma journée en essayant de faire fonctionner mon code à nouveau, même s'il fonctionnait bien avant MacOS Mojave.

Solution

Mettez le Info.plist avec le fichier NSCameraUsageDescription comme Proposition de dans le répertoire Products/Build de votre cible (cliquez avec le bouton droit de la souris sur Product dans le volet gauche du projet Xcode et cliquez sur "Show in Finder").

  • Automatiser ce processus de copier/coller Info.plist dans votre répertoire de construction (en suivant cette suggestion ) en l'ajoutant à la liste des Copy Files en Build Phases de votre "Cible" et en changeant la Destination en "Répertoire des produits" et le Sous-chemin en "."

Résultat

  • Le binaire exécutable Unix de la cible demandera alors l'autorisation d'accéder à la caméra et, en cas d'accord, le binaire sera ajouté à la liste des applications autorisées à accéder à la caméra, disponible dans le site Web de l'entreprise. System Preferences > Privacy > Camera .
    • FYI : Pour forcer l'effacement de cette liste, tapez tccutil reset Camera en Terminal
  • Il se peut que vous deviez exécuter la cible plusieurs fois avant d'être invité à demander l'autorisation / l'accès à la caméra.

Numéro

L'instanciation de la cv::VideoCapture(0) pour accéder au flux vidéo de la caméra génère l'erreur suivante, alors que le code fonctionnait correctement dans les versions de MacOS antérieures à Mojave.

OpenCV : non autorisé à capturer la vidéo (statut 0), demande...
OpenCV : la caméra n'a pas réussi à s'initialiser correctement !

Cause

MacOS Mojave a renforcé la protection de la vie privée, qui exige désormais que les applications demandent explicitement l'autorisation de l'utilisateur avant d'accéder à la caméra, comme expliqué ci-après. aquí .

Suggestions qui n'ont pas fonctionné

Les suggestions suivantes sont données dans divers Stackoverflow postes n'a pas réussi à forcer le binaire construit à demander la permission d'accéder à la caméra : - L'ajout de l'option Info.plist dans le répertoire de votre projet - Définir le chemin d'accès à Info.plist en Build Settings > Packaging > Info.plist File ou - Le choisir dans General > Identity > Choose Info.plist File... de votre cible

Suggestions qui auraient pu être utiles

Comme indiqué dans le opencv fermé GitHub numéro des changements ont été apportés à la libopencv vers le mois d'avril 19, ce qui aurait également pu faciliter l'utilisation des ressources disponibles. Info.plist dans le répertoire de construction pour demander à l'utilisateur la permission d'accéder à la caméra. J'ai donc également mis à jour mon opencv vers la dernière version stable 4.1.0 libérer en utilisant brew upgrade .

P.S. J'utilise MacOS Mojave. 10.14.5 Xcode 10.2.1 et OpenCV 4.1.0

1voto

Shawn Swanson Points 11

J'ai trouvé un moyen de contourner ce problème :

D'abord, réinitialisez les règles de votre appareil photo :

tccutil reset Camera

Ensuite, j'ai utilisé un logiciel tiers pour accéder à la caméra depuis le terminal. En exécutant ce qui suit :

brew install imagesnap
imagesnap -w 1 snapshot.png

On m'a demandé si je voulais autoriser le terminal à accéder à ma caméra. J'ai cliqué sur "Oui". Et maintenant mon programme C++ peut accéder à la caméra depuis le terminal.

Note : Les photos montrées par ZipZit étaient très similaires, sauf que je n'avais pas le terminal listé sous la caméra.

Mais après avoir exécuté un programme tiers,. il a été ajouté à la liste.

0voto

Liam Points 44

Nous avons exactement le même problème avec opencv 4.1.1-pre. Nous avons résolu le problème en revenant à la version 4.0.1.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X