在MacOS X上拍摄图片时出现不一致的图像小睡行为,具体取决于调用环境

问题描述 投票:0回答:1

编辑后的帖子

[当我第一次写这篇文章时,我对MacOS上的“ imagesnap” USB cam图像捕获程序的各种行为感到迷惑不解。有时它会拍照,有时却不拍照,这似乎与调用它的环境有关:例如直接在Terminal窗口中,在Shell程序中,在Terminal中运行的Python程序中,在Python程序中在Pycharm IDE中运行,并通过os.popen(),subprocess.run(),subprocess.call(),subprocess.popen()等进行调用。

有时,图像快照可以正常工作并拍摄图像,有时它会无声地失败。我真的很难弄清楚为什么行为会有所不同,以及如何在Mac上使用imagesnap获取图片,以便从Python程序调用时能够可靠地工作。

我搜索了诸如以下的关键词: )等。我在任何地方都找不到解决方案,在这里也没有得到答案。

我终于更好地理解了这个问题,这就是为什么我重写了这个问题。

从不同环境调用imagesnap不一致行为的原因是什么,如何从Linux程序中调用它并使它可靠地拍照?

我现在知道,

[系统偏好设置]中的MacOS X的隐私设置控制允许或无提示拒绝访问USB相机的环境。

[有关详细信息和解决方法,请参阅下面的我自己的答案。我希望其他对问题有更多了解的人会增加答案。

原始帖子:

下面是一个简单的Python测试程序。它使用

os.popen()

和使用imagesnap -d从选定的USB网络摄像头捕获图像,然后将图像保存在image.jpg。但是

imagesnap -d

命令在PyCharm环境,返回空白响应('')和失败保存所请求的图像。 在PyCharm的终端窗口中提交相同的代码失败

完全

相同。 但是当相同的python命令提交到终端时

outside

Pycharm,程序成功拍摄图像并报告,如下所示。我正在运行

Mac OS X Catalina,并使用PyCharm 2019.2.3社区版进行开发。 Python版本是3.7.4

示例代码:

import os return_string = os.popen("imagesnap -d 'DEVICE_NAME' 'image.jpg'").read() print("'",return_string,"'")

在PyCharm开发环境中

此程序返回以下内容,并且不创建jpg文件/Users/mcgregor94086/PycharmProjects/SonaScannerGUI/venv/bin/python
/ Users / mcgregor94086 / Library / Preferences / PyCharmCE2019.2 / scratches / scratch_5.py''

Process finished with exit code 0

[Outside

PyCharm相同的代码返回:$ python3 Python 3.7.4 (v3.7.4:e09359112e, Jul 8 2019, 14:54:52) [Clang 6.0 (clang-600.0.57)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> return_string = os.popen("imagesnap -d 'DEVICE_NAME' 'image.jpg'").read() >>> print("'",return_string,"'") ' Capturing image from device "<AVCaptureDALDevice: 0x7fa9bc203330 [DEVICE_NAME][0x141717501bcf0b09]>"... ' >>>
python-3.x macos security webcam privacy
1个回答
0
投票
在深入研究这个问题之后,没有任何回应,我开始在网上更广泛地寻找答案。尽管我发现

几乎没有网络上的信息可以指导我发生了什么,但我现在相信我知道what阻止了我在python程序中以编程方式拍照。我还相信,对于我正在看到的结果,我现在有一个合理的假设。 我有一项工作正在解决,但我担心将来可能会消失。

[相信问题与MacOS有关,我相信它可能因MacOS的特定发行版而异。 我当前正在使用

MacOS X 10.15.1 Catalina。

较早的MacOS X版本可能不那么严格。至少在Catalina]版本中,

任何连接的USB摄像头都被视为受特殊安全性约束的特殊设备

,并且对摄像头设备的访问管理在系统偏好设置->中进行控制安全和隐私面板。
当您单击面板左侧菜单中的“相机”行时,您将看到允许以编程方式访问相机的应用程序的复选框列表。如果您解锁页面(左下方),则可以通过选中或取消选中列表中的应用,更改允许哪些应用访问相机。

在我可用的计算机上,此面板中有4个应用程序的列表:终端,UberConference,Google Chrome,Skype。

可用应用程序的列表因其他资源而异,例如联系人,日历,可访问性,完整磁盘访问等]

其中一些资源(例如Accessibility

Full Disk Access)选择列表具有app列表下方的一对[+ |-]按钮]

,您可以添加或永久删除访问该资源的应用程序。 但是相机。麦克风和某些其他资源没有这样的按钮,对于这些设备,用户无法更改列表。 面板建议应用程序进入列表

通过“请求对照相机的访问”,

,但是我没有找到关于

如何将应用程序添加到此访问列表的说明”。

列表中预定义的应用程序之一是“ Terminal”。这已经过检查,因此当我

终端窗口内运行图像快照时,程序具有必要的隐私特权,并且相机可以正常拍照。

相反,当我尝试在PyCharm IDE中运行python程序时,PyCharm IDE并未将自身标识为终端,并且请求默默地失败了。

Python有多种不同的方式来启动独立程序,例如imagesnap。这些方法包括os.popen(),subprocess.run()和subprocess.Popen()。其中有些方法是[[deprecated

,因此我们将来不能依靠它们来工作。其他method()具有控制是否创建新“外壳”的其他选项,这些选项可能会使确定应用程序将看到的环境变得复杂。

我发现很难预测这些python方法中的哪个会成功打开相机,而不会成功,以及它们在IDE中运行还是在终端窗口中运行时的行为。也许其他人可以编译这样的表。

变通方法:
目前,我可以使用os.popen来解决此问题,方法是使用一个初始字符串打开新的终端。这似乎可以确保Apple安全将父级视为我们在控制面板中特别授权的“终端”应用程序。

然后我找到了

os.popen("open -a Terminal.app imagesnap.sh")

工作。

尽管目前这种解决方法对我有用,但我对使用os.popen()而不是其中一种子处理方法感到不满意,因为我担心它可能已被弃用。其次,这与Shell脚本(“ imagesnap.sh”)一起使用,但是我还没有弄清楚如何传递参数或运行可执行文件。

也许一个知识渊博的读者可以提供更好的建议。 
© www.soinside.com 2019 - 2024. All rights reserved.