Ubuntu下读取CHUSEI 3D Webcam 双目摄像头C++版本(调用python脚本进行配置)

本博客做了一个工作——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 <iostream>
#include <opencv2/opencv.hpp>
#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..." <<std::endl;
    std::cout<<"Now we go to detect Lines and Circles using Hough Transform..." <<std::endl;
    cv::VideoCapture capture(0);//打开摄像头,根据需要更改地址,笔记本接摄像头一般需要改成1,台式接摄像头一般为0
    if(capture.isOpened()){//判断是否接上摄像头
        std::cout<<"Now we go to show a video from your camera..." <<std::endl;
    }else{
        std::cout<<"Camera is lost!Please connect your camera!" <<std::endl;
        return -1;
    }
    cv::Mat frame;
    capture >> frame; //读取第一帧,要先读取,后面调用python脚本进行配置时才有效


    //----调用python进行对CHUSEI 3D Webcam 双目摄像头进行配置步骤开始-------------------------
    Py_Initialize();//初始化Python解释器
    if(!Py_IsInitialized())//检查是否已经进行了初始化,如果返回0,表示没有进行过初始化。
    {
        std::cout <<"Python parser initialization failed!" <<std::endl;
        return -1;
    }
    /*传递参数时用,另参考教程
    int argc = 1;
    char *argv[1];
    argv[0] = "/home/weide/MyDo/my_py/test.py";
    PySys_SetArgv(argc, argv);
     */
    PyRun_SimpleString("execfile('/home/xxxx/test.py')");//执行配置脚本
    Py_Finalize();//反初始化Python解释器,包括子解释器,调用此函数同时会释放Python解释器所占用的资源。

    cv::waitKey(1000);//等待1s

    //下面是双目视频的显示及左目的霍夫圆检测
    char key;
    while (key != 'q' && key != 27) {
        //cv::Mat frame;
        capture >> 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<cv::Vec3f> 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可执行文件就可以,该可执行文件一般在编译的目录下。效果如下:
Ubuntu下读取CHUSEI 3D Webcam 双目摄像头C++版本(调用python脚本进行配置)
结束语
该工作能实现双目摄像头的设置和双目图像的读取,并作了简单的圆检测。个人觉得还是方便了很多,且操作简单。
问题
在运行时偶尔会遇到配置不成功的情况,笔者的解决方法是重新运行程序,具体原因及解决方法笔者还没有去研究,希望了解的朋友留言解答一下,非常感谢。纯属个人工作记录,有不足的地方希望大家多多留言指导。