利用OpenCV打开双目相机并实时处理数据

您所在的位置:网站首页 双目摄像头开发包是什么 利用OpenCV打开双目相机并实时处理数据

利用OpenCV打开双目相机并实时处理数据

#利用OpenCV打开双目相机并实时处理数据| 来源: 网络整理| 查看: 265

1.前言 2.双目相机的使用 3.Python代码 3.简单应用 (1)实时双目ORB特征提取 (2)实时双目ORB特征匹配 4.小问题 1.前言

前阵子在淘宝上闲逛,看到有家卖双目摄像头的,价格感觉也还在可接受的范围内。和其它动辄一两千的双目摄像头相比,一两百的价格算是比较良心了。最便宜的6cm基线的100万像素的双目相机才150。 当然如果说差距,肯定还是有的。比如像素、帧率、数据传输速率、影像质量等等,肯定不如贵的。不过自己买来玩玩足够了,这个价格就别要什么自行车了。 所以就在他们家买了个双目摄像头来学习一下,如下图。 正面 处理芯片特写 镜头特写

因为他们家是工厂店,所以双目摄像头的一些参数是按照我的要求生产的。双目摄像头的基线长度是24cm,他们家默认生产的双目相机基线是6cm,最大能生产24cm基线。 因为想着买来是用来做SLAM的,不是小场景的应用,如人脸识别、小车避障这种,所以就要了最大的。镜头选的是100度视场角无畸变的镜头,像素是100万。 按照店家的说法,只支持特定几种分辨率,经过测试也确实如此。这在之后代码部分再详细介绍。 如果感兴趣的话,可以在淘宝里搜“树莓派摄像头模块工厂直销店”就能找到了。

2.双目相机的使用

双目相机的使用非常简单,由于是USB接口的,所以直接插到USB接口即可,免驱。

首先说说双目相机的成像和数据传输形式。双目相机顾名思义就是有两个摄像头,同时拍照。这里的关键词是“同时”,这又属于那种说起来简单做起来难的问题。 如何保证两个相机每一帧都是同时成像的,这会直接关系到双目数据的应用结果。好在厂家已经把“同步”这个问题在硬件层面解决了,通过板载芯片来进行同步。 作为我们用户无需关心这个问题,只需要读取数据即可。

那么双目相机输入给电脑的数据又是什么形式呢?如果不了解,你可能会以为是两个独立的画面或什么的,但其实不是。其实还是“一个画面”,双目相机在硬件层面将两个摄像头的数据合并到了“同一个画面”上,如下所示。 在处理数据时,我们只需要将影像画面拆分成左右两个,如下图,然后单独处理即可。

以我买的这款为例,之前说它只支持几种特定的分辨率,经过实测它支持:2560×960、1280×480、640×240,因此需要在代码中事先设置好。 注意这里所指的分辨率并不是单个相机的分辨率,而是两个相机合并成一张影像后的分辨率,对于单个影像而言,宽度除以2。

下面主要介绍如何通过代码打开双目相机。

3.Python代码 # coding=utf-8 import cv2 import sys def getCameraInstance(index, resolution): """ 用于初始化获取相机实例,从而读取数据 :param index: 相机的索引编号,如果只有一个相机那就是0,有多个则以此类推 :param resolution: 相机数据的分辨率设置 :return: 相机实例,以及设置的影像长宽 """ cap = cv2.VideoCapture(index) if resolution == '960p': width = 2560 height = 960 elif resolution == '480p': width = 1280 height = 480 elif resolution == '240p': width = 640 height = 240 # OpenCV有相关API可以设置视频流的长宽 cap.set(cv2.CAP_PROP_FRAME_WIDTH, width) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height) return cap, width, height if __name__ == '__main__': # 读取启动参数,设置分辨率 if sys.argv.__len__() == 3: cam_no = int(sys.argv[1]) reso_flag = sys.argv[2] else: cam_no = 1 reso_flag = '960p' # 获取相机实例并返回对象 cap, width, height = getCameraInstance(cam_no, reso_flag) # 不断循环读取帧数据 while True: ret, frame = cap.read() # 对影像进行拆分,左右影像 left_cam = frame[:, :int(width / 2), :] right_cam = frame[:, int(width / 2):, :] # 分别显示 cv2.imshow("left_cam", left_cam) cv2.imshow("right_cam", right_cam) cv2.waitKey(25)

运行上述代码后,结果就如下所示。 这样,就能够正常打开双目相机并获取双目相机的数据了。而且由于基于OpenCV,因此在Windows、Ubuntu、树莓派等平台上都是可以运行的。

3.简单应用

下面基于使用双目相机代码的框架,就可以对实时视频流进行一些简单的处理了,例如提取ORB特征点、匹配等。下面分别演示实时ORB提取与匹配。

(1)实时双目ORB特征提取 # coding=utf-8 import cv2 def drawKeyPoints(img, kps, color=(0, 0, 255), rad=3): if img.shape.__len__() == 2: img_pro = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) else: img_pro = img for point in kps: pt = (int(point.pt[0]), int(point.pt[1])) cv2.circle(img_pro, pt, rad, color, 1, cv2.LINE_AA) return img_pro def getORBkpts(img, features=1000): orb = cv2.ORB_create(nfeatures=features) kp, des = orb.detectAndCompute(img, None) return kp, des def getCameraInstance(index, resolution): cap = cv2.VideoCapture(index) if resolution == '960p': width = 2560 height = 960 elif resolution == '480p': width = 1280 height = 480 elif resolution == '240p': width = 640 height = 240 cap.set(cv2.CAP_PROP_FRAME_WIDTH, width) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height) return cap, width, height if __name__ == '__main__': cap, width, height = getCameraInstance(1, '480p') while True: ret, frame = cap.read() left_cam = frame[:, :int(width / 2), :] right_cam = frame[:, int(width / 2):, :] # ORB特征提取部分 kps_left, desc_left = getORBkpts(left_cam) kps_right, desc_right = getORBkpts(right_cam) # 绘制ORB特征点 left_kps = drawKeyPoints(left_cam, kps_left) right_kps = drawKeyPoints(right_cam, kps_right) cv2.imshow("left_kps", left_kps) cv2.imshow("right_kps", right_kps) cv2.waitKey(25)

运行结果如下所示,可以实时检测每帧的ORB特征点。

(2)实时双目ORB特征匹配

在上面实现了实时ORB特征提取,但提取特征点的目的是为了对左右影像进行匹配,从而原理计算视差,再根据双目成像原理计算特征点深度。因此,下面实现ORB特征点匹配。

# coding=utf-8 import cv2 import numpy as np def drawKeyPoints(img, kps, color=(0, 0, 255), rad=3): if img.shape.__len__() == 2: img_pro = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) else: img_pro = img for point in kps: pt = (int(point.pt[0]), int(point.pt[1])) cv2.circle(img_pro, pt, rad, color, 1, cv2.LINE_AA) return img_pro def drawMatches(img1, img2, good_matches): if img1.shape.__len__() == 2: img1 = cv2.cvtColor(img1, cv2.COLOR_GRAY2BGR) if img2.shape.__len__() == 2: img2 = cv2.cvtColor(img2, cv2.COLOR_GRAY2BGR) img_out = np.zeros([max(img1.shape[0], img2.shape[0]), img1.shape[1] + img2.shape[1], 3], np.uint8) img_out[:img1.shape[0], :img1.shape[1], :] = img1 img_out[:img2.shape[0], img1.shape[1]:, :] = img2 for match in good_matches: pt1 = (int(match[0]), int(match[1])) pt2 = (int(match[2] + img1.shape[1]), int(match[3])) cv2.circle(img_out, pt1, 5, (0, 0, 255), 1, cv2.LINE_AA) cv2.circle(img_out, pt2, 5, (0, 0, 255), 1, cv2.LINE_AA) cv2.line(img_out, pt1, pt2, (0, 0, 255), 1, cv2.LINE_AA) return img_out def getORBkpts(img, features=1000): orb = cv2.ORB_create(nfeatures=features) kp, des = orb.detectAndCompute(img, None) return kp, des def matchORBkpts(kps1, desp1, kps2, desp2): good_kps1 = [] good_kps2 = [] good_matches = [] bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) matches = bf.match(desp1, desp2) if matches.__len__() == 0: return good_kps1, good_kps2, good_matches else: min_dis = 10000 for item in matches: dis = item.distance if dis


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3