本博客做了一个工作——Ubuntu下用OpenCV读取CHUSEI 3D Webcam 双目摄像头(C++版本),希望能给予有需要的朋友一个参考。
购买了CHUSEI 3D Webcam 双目摄像头问群主有没有相关代码,群主说上班很忙,于是自己就参考群里资料做了些工作。群里给的方法一是python同时进行摄像头设置和双目图像的读取代码(如果用python开发的推荐使用),方法二是sh脚本设置。方法二中的具体工作是:先写一个opencv读取摄像头的代码(C++或python语言),运行该代码后在命令终端运行.sh脚本,这时候就配置成功了。但是笔者认为方法二中分两步操作闲麻烦,但是自己想要C++语言进行相关开发,于是想到了C++调用python的思路。下面具体介绍整个工作的过程。
(1)安装uvcdynctrl
sudo apt-get install uvcdynctrl
(2)编写python设置摄像头的代码
编写python设置摄像头的代码,笔者命名为test.py,cam_id是摄像头地址,cma_mode是摄像头的几种输出模式,1——左眼单目,2——右眼单目,3——红蓝模式,4——双目模式。
import cv2
import shlex
import subprocess
cam_id = 0
cam_mode=4
cammand_list = [
"uvcdynctrl -d /dev/video{cam_id} -S 6:8 '(LE)0x50ff'",
"uvcdynctrl -d /dev/video{cam_id} -S 6:15 '(LE)0x50f6'",
"uvcdynctrl -d /dev/video{cam_id} -S 6:8 '(LE)0x2500'",
"uvcdynctrl -d /dev/video{cam_id} -S 6:8 '(LE)0x5ffe'",
"uvcdynctrl -d /dev/video{cam_id} -S 6:15 '(LE)0x0003'",
"uvcdynctrl -d /dev/video{cam_id} -S 6:15 '(LE)0x0002'",
"uvcdynctrl -d /dev/video{cam_id} -S 6:15 '(LE)0x0012'",
"uvcdynctrl -d /dev/video{cam_id} -S 6:15 '(LE)0x0004'",
"uvcdynctrl -d /dev/video{cam_id} -S 6:8 '(LE)0x76c3'",
"uvcdynctrl -d /dev/video{cam_id} -S 6:10 '(LE)0x0{cam_mode}00'",
]
for cammand in cammand_list:
subprocess.Popen(shlex.split(cammand.format(cam_id=0, cam_mode=4)))
(3)编写读取摄像头的C++代码
编写读取摄像头的C++代码(利用OpenCV3)笔者命名为test.cpp,内容如下,有注释不做过多介绍。其中while中有一段代码是圆的检测,不需要可以注释掉。另:PyRun_SimpleString(“execfile(’/home/xxxx/test.py’)”);是调用python脚本的语句,根据自己test.py的目录自行修改xxxx。
#include
#include
#include "boost/python.hpp"//调用python脚本用的头文件,注意CMakeLists.txt里要加
//find_package(Boost COMPONENTS thread serialization python REQUIRED)
//include_directories(${Boost_INCLUDE_DIR}
// /usr/include/python2.7)
//target_link_libraries(test
// ${OpenCV_LIBRARIES}#这个与调用python没关系
// ${Boost_LIBRARIES}
// /usr/lib/x86_64-linux-gnu/libboost_python-py27.so
// /usr/lib/x86_64-linux-gnu/libstdc++.so.6
// /usr/lib/x86_64-linux-gnu/libpython2.7.so
// )
int main(int argc, char*argv[]){
std::cout<<"Hello OpenCV..." <> frame; //读取第一帧,要先读取,后面调用python脚本进行配置时才有效
//----调用python进行对CHUSEI 3D Webcam 双目摄像头进行配置步骤开始-------------------------
Py_Initialize();//初始化Python解释器
if(!Py_IsInitialized())//检查是否已经进行了初始化,如果返回0,表示没有进行过初始化。
{
std::cout <<"Python parser initialization failed!" <> frame;
cv::imshow("原始视频",frame);
//双目
//双目测试开始
cv::Mat DoubleImages;
cv::resize(frame, DoubleImages,cv::Size(640,240),(0,0),(0,0),cv::INTER_AREA);
cv::imshow("双目视频",DoubleImages);
cv::Mat LeftImages = DoubleImages(cv::Rect(0,0,320,240));
cv::Mat RightImages = DoubleImages(cv::Rect(320,0,320,240));
cv::imshow("左目视频",LeftImages);
cv::imshow("右目视频",RightImages);
//双目测试结束
//HoughCircles,左目的霍夫圆检测,----不需要可以注释掉,开始注释
cv::Mat midImages;
cv::cvtColor(LeftImages, midImages, CV_BGR2GRAY);
cv::GaussianBlur(midImages,midImages, cv::Size(9,9), 2, 2);
std::vector circles;
cv::HoughCircles(midImages, circles, CV_HOUGH_GRADIENT, 1.5, 10, 200,100,0,0);
for (size_t i = 0; i < circles.size(); i++) {
cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
cv::circle(LeftImages, center, 3, cv::Scalar(0,255,0),-1,8,0);
cv::circle(LeftImages, center, radius, cv::Scalar(155, 50,255),3,8,0);
}
cv::imshow("左目灰度图", midImages);
cv::imshow("左目圆检测", LeftImages);
//HoughCircles,左目的霍夫圆检测,----不需要可以注释掉,结束注释
//延时30ms,检测按键
key = cv::waitKey(30);
}
return 0;
}
(4)编写CMakeLists.txt
一般建立工程都需要自己写一个CMakeLists.txt的编译配置文件,该工程的CMakeLists.txt为:
cmake_minimum_required(VERSION 2.8)
project(test)
set( CMAKE_CXX_FLAGS "-std=c++11")
find_package(OpenCV REQUIRED)
find_package(Boost COMPONENTS thread serialization python REQUIRED)
include_directories(${Boost_INCLUDE_DIR}
/usr/include/python2.7)
include_directories(
${OpenCV_INCLUDE_DIRS}
include
)
add_executable(test src/test.cpp)
target_link_libraries(test
${OpenCV_LIBRARIES}
${Boost_LIBRARIES}
/usr/lib/x86_64-linux-gnu/libboost_python-py27.so
/usr/lib/x86_64-linux-gnu/libstdc++.so.6
/usr/lib/x86_64-linux-gnu/libpython2.7.so
)
(5)运行及效果
至此所有工作已经做完了。如果用CLion环境的话可以点击运行就可以了;如果在终端运行也可以,运行test可执行文件就可以,该可执行文件一般在编译的目录下。效果如下:
结束语
该工作能实现双目摄像头的设置和双目图像的读取,并作了简单的圆检测。个人觉得还是方便了很多,且操作简单。
问题
在运行时偶尔会遇到配置不成功的情况,笔者的解决方法是重新运行程序,具体原因及解决方法笔者还没有去研究,希望了解的朋友留言解答一下,非常感谢。纯属个人工作记录,有不足的地方希望大家多多留言指导。