草庐IT

COI实验室技能:python控制相机的方法——采集、处理、显示、实时

山颠海涯 2024-07-02 原文

COI实验室技能:python控制相机的方法——采集、处理、显示、实时

  本文介绍如何利用python控制办公摄像头、工业相机和科研相机。将数据采集和处理统一到python代码中。
  主要围绕解决采用什么库、掌握这个库的控制相机方法(参数配置、读取数据等等)、结合自己的算法进行处理、保存显示结果。
  基本流程:导入相关的库 -> 读取图片的方法 -> 处理数据 -> 结果保存、显示等等。

目录

预备内容:
● 掌握python语言以及安装加载包的方法(cv2)
● pointgray官网SDK及Python库:https://meta.box.lenovo.com/v/link/view/a1995795ffba47dbbe45771477319cc3
● PCO相机介绍python控制方法:https://www.pco.cn/software/third-party-software/python/

1. python控制办公摄像头

   使用cv2库可以直接控制家用摄像头(usb连接主机后,可以直接用电脑自带相机软件打开),读取的图像是numpy数组。具体实现方法如下:

# 实时在线测试家用摄像头
# 流程:读取图像 -> 预处理 -> 实时显示

import cv2
import time
import numpy as np

# 初始化
cv2.destroyAllWindows(), time.sleep(0.003)  # 清空cv2显示的窗口
# gap = (np.ones([448, 20], dtype=np.float32)*65535).astype(np.uint16)
cap = cv2.VideoCapture(0)		# 指定相机
one = np.ones([480, 640, 3], dtype=np.uint8)*255	# 本demo的需求,用于计算1-img的结果,实现图像色彩负片

while True:
    start = time.time()	# 记录开始时间
    # 读取图像
    ret, frame = cap.read()	# 读取为numpy数组
    # 预处理
    frame_1 = one - frame
    # 显示图像
    cv2.imshow('frame', np.concatenate([frame, frame_1], axis=1))	# 并排显示原图和处理后的图像
    if cv2.waitKey(1) == 27:    # 按下ESC键退出
        break
    # 打印帧率
    print('帧率:{:.4f} fps'.format(1.0/(time.time()-start)))

# 释放资源
cap.release()
cv2.destroyAllWindows()

运行结果:

图1 家用相机的python控制运行结果

2. python控制工业相机的例子

  这一节以工业相机pointgray为例,介绍python如何控制pointgray相机。
  控制工业相机笔者测试了很多办法(cv2.VideoCapture(0),pyflycap2,PyCapture2),很多方法都不行,最后成功运行的是用官网提供的相关资料,pointgray官网SDK及Python库:https://meta.box.lenovo.com/v/link/view/a1995795ffba47dbbe45771477319cc3,下面下载的压缩包中有readme文件,它也详细讲述了安装步骤。

2.1 环境配置

  装包流程:下载应用程序和python库 -> 进行安装 -> 运行demo程序 -> 进行自己的开发。

1)从官网中下载对应的SpinnakerSDK应用程序(笔者是64位电脑,就安装了x64的包),下载完之后进行安装(默认形式安装即可),装完之后打开应用程序,应用程序在安装路径的bin文件夹下,如何可以用软件打开相机,说明连接上没有问题,准备下一步;

软件成功打开相机,并能够控制相机;

2)下载python版本的压缩包,如下图,进入到python文件夹中,下载对应电脑系统和python版本的压缩包;

3)随便解压到一个文件夹,打开文件夹,复制.whl文件到cmd的默认路径(一般是C:\user\xxx),使用pip install xxx.whl进行安装。

安装完之后,可以在命令行中输入pip list来检查pyspin包是否安装好了:

安装成功之后就可以使用这个库对相机进行控制了。

2.2 控制pointgray相机

  因为安装好的库是小写的,官网给的代码示例都是大写的,直接导入PySpin会出错,因此这里需要到入库名称为pyspin。

# 使用PySpin控制pointgray相机

import cv2
import numpy as np
import pyspin as PySpin

# 初始化
system = PySpin.System.GetInstance()    # 创建系统对象
cam_list = system.GetCameras()          # 获取相机列表
cam = cam_list.GetByIndex(0)            # 选择要使用的相机
cam.Init()
cam.AcquisitionMode.SetValue(PySpin.AcquisitionMode_Continuous) # 采集模式为连续采集
cam.BeginAcquisition()                  # 开始采集

# 循环
while True:
    # 读取图像
    image_result = cam.GetNextImage(1000)
    img = image_result.GetNDArray()         # 转为numpy数组
    # 显示图像
    n, m = (int(img.shape[0]/3), int(img.shape[1]/3))   # 缩小尺寸
    img_resize = cv2.resize(img, (m, n))                # 缩小后的图像
    cv2.imshow('frame', np.concatenate([img_resize, 255-img_resize], axis=1))  # 并排显示原图和处理后的图像
    # 按下 'q' 键退出循环
    if cv2.waitKey(1) == ord('q'):
        break

# 停止采集
cam.EndAcquisition()
# 关闭相机
cam.DeInit()
# 释放系统资源
del cam
del cam_list
system.ReleaseInstance()
cv2.destroyAllWindows()

结果:

3. python控制科研相机

  以PCO相机为例,1) 使用pip install pco安装控制PCO相机所需要的库;2)使用库初始化相机参数和读取数据;3)进行后续自己的数据处理;
  PCO官网提供的说明文档也有非常具体的操作指南,读者可以下载下来进一步学习。
PCO相机介绍python控制方法:https://www.pco.cn/software/third-party-software/python/

import cv2
import pco

# 清空cv2显示的窗口
cv2.destroyAllWindows(), time.sleep(0.003)  

# 初始化相机
cam = pco.Camera()  # 指定相机
exp_time = 0.01
cam.set_exposure_time(exp_time)
cam.record(4, mode='ring buffer')  # 启动相机
cam.wait_for_first_image()

while True:
	img, meta = cam.image(image_number=0xFFFFFFFF)	# 读取为numpy数组
	# 执行数据处理
	# xxx

	# 显示图像
	cv2.imshow('frame', img)	# 并排显示原图和处理后的图像
	# 按下 'q' 键退出循环
    if cv2.waitKey(1) == ord('q'):
        break
# 释放资源
cv2.waitKey(-1)
cam.close()
cv2.destroyAllWindows()

如图是笔者实时运行一个去散射的结果:

如果有自动调节曝光时间的需求,可以在上面循环语句中的xxx位置放置下面这段代码:

if np.max(img[543:1438:2, 560:1455:2]) == 65535:    # 过曝了,缩小曝光时间
    exp_time = exp_time*55000/65535
    cam.set_exposure_time(exp_time)
    print('exp_time: ', exp_time)
elif np.max(img[543:1438:2, 560:1455:2]) > 50000:   # 最大像素值>50000, 无需调节
    pass
else:                                               # 最大像素值<50000, 增加曝光时间
    exp_time = exp_time*55000/np.max(img[543:1438:2, 560:1455:2])
    cam.set_exposure_time(exp_time)
    print('exp_time: ', exp_time)

自适应曝光的实现过程:利用图像的最大值分布在50000~65535之间的约束来调节曝光时间,首先计算采集图像的最大值I_max,执行判断:1)如果最大值等于65535(说明过曝),增益系数α=55000/65535,用exp_time = αexp_time来缩小曝光时间;2)如果最大值大于50000,略过;3)如果最大值小于50000,增益系数α=55000/I_max,用exp_time = αexp_time来增大曝光时间。说明:考虑到不同帧之间最大值会波动,所以用55000这个中间值来计算增益α,这样即使有波动,只要最大值大于50000,我们就不用更新曝光时间,从而在程序上只执行一行判断语句,对整体运行效率几乎没有影响。

4. 实时监测系统的实现

  采集完图片和处理之后,只要外部增加一个循环语句,就可以实现实时监测,实时看到自己算法的效果。

while True:
	img = cam.capture()	# 这行命名是示例,要根据具体的读取命令进行编写
	cv2.imshow('windows', img)
	# 按下 'q' 键退出循环
    if cv2.waitKey(1) == ord('q'):
        break

其他相关资料:
● matlab控制pointgray工业相机:https://www.flir.cn/support-center/iis/machine-vision/application-note/getting-started-with-matlab/
● matlab控制pco相机:https://blog.csdn.net/qq_34917728/article/details/121527862

有关COI实验室技能:python控制相机的方法——采集、处理、显示、实时的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  3. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  4. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  5. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  6. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  7. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  8. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  9. python - 如何读取 MIDI 文件、更改其乐器并将其写回? - 2

    我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的

  10. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

随机推荐