将LabVIEW与python连接以触发USB摄像头

Posted

技术标签:

【中文标题】将LabVIEW与python连接以触发USB摄像头【英文标题】:Interfacing LabVIEW with python for triggering USB Camera 【发布时间】:2021-03-23 12:29:01 【问题描述】:

LabVIEW支持从python调用函数的pallet。我是否需要分别开发 3 个单独的函数来初始化、捕获和关闭?在 python 中使用 OpenCV 访问基于 directshow 的 USB 摄像头。

如果我创建 3 个单独的函数,是否需要将它们包含在同一个 python 脚本中?就好像我正在使用 while 循环来捕获函数一样,之后编写的函数可能不会被调用。如果我将它们保存在不同的 python 脚本中,它会识别出相机在同一个会话中运行吗?

为什么后面的函数不能识别'cam'?

import cv2
import math
import os
camname = -1
img_name = "sample"
filepath = r"C:\Users\Public"
message = "sampler"
caminitok = False
inierror = False

def caminit(camname):
    cam = cv2.VideoCapture(camname)
    if not (cam.isOpened()):
        return inierror == True
    else:
        return inierror == False    

def camcapture(img_name, filepath, caminitok):
    if caminitok == True:
        ret, frame = cam.read()
        os.chdir(filepath)
        cv2.imwrite(img_name, frame)

def camclose():
        cam.release()

【问题讨论】:

sweber 的回答很好,很可能会解决您的问题。但是您知道 Wineman Technology 有一个免费的、源代码发布的双向 LabVIEW/Python 连接器吗?您可以从 Python 编写 LabVIEW 脚本,或从 LabVIEW 调用 Python 函数。内置 Python 节点不允许您使用 Python 控制 LabVIEW。 【参考方案1】:

不使用全局变量,维护对外部资源的引用的更“Pythonic”方式是创建一个类:

import cv2
import os

class Cam:
    def __init__(self, camname):
        self.cam = cv2.VideoCapture(camname)
        self.caminitok = self.cam.isOpened()
    
    def capture(self, img_name, filepath):
        if self.caminitok:
            ret, frame = self.cam.read()
            os.chdir(filepath)
            cv2.imwrite(img_name, frame)

    def __del__(self):
        self.cam.release()

用法:

>>> c = Cam(0)
>>> c.caminitok
True
>>> c.capture('foo.jpg', 'path/to/folder')
>>> del c

这相当于 LabVIEW 中的函数式全局 VI,其中内部状态存储在例如一个移位寄存器。

【讨论】:

这很棒,在labview方面更容易理解,谢谢!【参考方案2】:

这首先是一个 python 问题,而不是一个 labview 问题。

变量camcaminit()中创建,在函数结束时被删除。所以,camcapture()camclose() 不知道cam 是什么。

您可以在开头的变量列表中添加cam。然后,它总是被定义,所有函数都可以读取它。 但是如果一个函数想要写入它,python 将创建一个具有相同名称的新变量,并将其用于函数的其余部分。最后,它会忘记新的变量,将原来的变量放回原处。因此,您需要在caminit() 中写入global cam,它明确告诉python 写入全局变量。这对其他函数来说不是必需的,因为它们对变量起作用,但不要编写它。

导入简历2 导入数学 导入操作系统 凸轮名称 = -1 img_name = "样本" 文件路径 = r"C:\Users\Public" 消息=“采样器” caminitok = 假 inierror = 假 凸轮=无########## def caminit(camname): 全局凸轮########## cam = cv2.VideoCapture(camname) 如果不是(cam.isOpened()): 返回 inierror == 真 别的: 返回 inierror == False def camcapture(img_name,文件路径,caminitok): 如果 caminitok == 真: ret, frame = cam.read() os.chdir(文件路径) cv2.imwrite(img_name, 帧) 定义凸轮关闭(): cam.release()

【讨论】:

嗨 sweber,非常感谢您的澄清。我创建这个程序时牢记在labview中使用托盘的结构(初始化,在while循环中运行和停止功能)。事实证明 python 的工作方式不同(非常感谢您的解释,因为我能够清楚地理解为什么)并且因为我只需要相机的快照,所以我从这里的源代码中获取了参考并进行了修改以使用 LabVIEW。 @Amlo4300 如果您在 Python 中定义一个函数,如 def myFun(foo, bar): return foo*bar,这就像一个子 VI,有两个输入端子 foobar 以及一个输出端子。您在函数内分配的任何其他变量就像子 VI 内的电线,不连接到输入或输出端子:无法从函数或子 VI 外部访问它们。【参考方案3】:
import cv2
import math
import os   
imagestate = False
def camcapture(camnum, img_name, filepath):
    cam = cv2.VideoCapture(camnum, cv2.CAP_DSHOW)
    ret, frame = cam.read()
    os.chdir(filepath)
    cv2.imwrite(img_name, frame)
    cam.release()
    return imagestate == True

每当我需要拍摄快照时,我都会从 LabVIEW 中调用这个脚本,效果很好。我还不明白为什么即使整个脚本运行正常,imagestate 也不会返回“True”。

【讨论】:

imagestate 在开始时设置为False,并且从未设置为其他任何值。最后一行将其与True 进行比较,结果始终为False,这就是返回的内容。 是的,我只是这么想的,但是放置一个“=”符号时出现语法错误,我会再检查一遍,谢谢。 return set imagestate=true之前,返回imagestate

以上是关于将LabVIEW与python连接以触发USB摄像头的主要内容,如果未能解决你的问题,请参考以下文章

USB 摄像头 进行python OpenCV 操作的基础设置以yolo 目标检测为例

USB 摄像头 进行python OpenCV 操作的基础设置以yolo 目标检测为例

labview连接摄像头卡出现卡顿的问题

基于LabVIEW和Python的USB串口数据传输

labview中vision控件怎么读取JPEG或者PNG图片的数据,这个image格式是啥

LabVIEW控制Arduino LED灯闪烁(基础篇—2)