Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在aruco opencv中使用单色摄像头捕获视频_C++_Opencv_Video Capture_Aruco_Monochrome - Fatal编程技术网

C++ 在aruco opencv中使用单色摄像头捕获视频

C++ 在aruco opencv中使用单色摄像头捕获视频,c++,opencv,video-capture,aruco,monochrome,C++,Opencv,Video Capture,Aruco,Monochrome,我目前正在尝试使用带有aruco和opencv库的单色相机,以加速计算并获得更好的标记捕获。我遇到的问题是,在运行aruco_测试程序时,屏幕上的单色馈源被增加了三倍,因此分辨率降低了三分之二,标记被检测到三次,而不是一次 我在opencv中看到了关于单色相机类似问题的提要。一些答案建议裁剪图像(这解决了三倍化问题,但并没有解决较小的分辨率),但这一切似乎都是由BGR2GRY或GRAY2BGR的转换引起的。 如果您能在aruco源代码或opencv源代码中提供帮助,了解到底是什么原因导致图像增加

我目前正在尝试使用带有aruco和opencv库的单色相机,以加速计算并获得更好的标记捕获。我遇到的问题是,在运行aruco_测试程序时,屏幕上的单色馈源被增加了三倍,因此分辨率降低了三分之二,标记被检测到三次,而不是一次

我在opencv中看到了关于单色相机类似问题的提要。一些答案建议裁剪图像(这解决了三倍化问题,但并没有解决较小的分辨率),但这一切似乎都是由BGR2GRY或GRAY2BGR的转换引起的。 如果您能在aruco源代码或opencv源代码中提供帮助,了解到底是什么原因导致图像增加了三倍,以及如何绕过该部分,我们将不胜感激

信息:

驱动程序信息(不使用libv4l2):

使用Aruco 2.0.19和OpenCV 3.2

像素格式不是YUYV,我不能简单地从相机馈送中获取Y通道

执行的代码:

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include "aruco.h" 
#include "cvdrawingutils.h"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace aruco;

MarkerDetector MDetector;
VideoCapture TheVideoCapturer;
vector< Marker > TheMarkers;
Mat TheInputImage, TheInputImageCopy;
CameraParameters TheCameraParameters;
void cvTackBarEvents(int pos, void *);

pair< double, double > AvrgTime(0, 0); // determines the average time required for detection
int iThresParam1, iThresParam2;
int waitTime = 0;
class CmdLineParser{int argc; char **argv; public: CmdLineParser(int _argc,char **_argv):argc(_argc),argv(_argv){}  bool operator[] ( string param ) {int idx=-1;  for ( int i=0; i<argc && idx==-1; i++ ) if ( string ( argv[i] ) ==param ) idx=i;    return ( idx!=-1 ) ;    } string operator()(string param,string defvalue="-1"){int idx=-1;    for ( int i=0; i<argc && idx==-1; i++ ) if ( string ( argv[i] ) ==param ) idx=i; if ( idx==-1 ) return defvalue;   else  return ( argv[  idx+1] ); }};


cv::Mat resize(const cv::Mat &in,int width){
    if (in.size().width<=width) return in;
    float yf=float(  width)/float(in.size().width);
    cv::Mat im2;
    cv::resize(in,im2,cv::Size(width,float(in.size().height)*yf));
    return im2;

}

int main(int argc, char **argv) {
    try {
        CmdLineParser cml(argc,argv);
        if (argc < 2  || cml["-h"]) {
            cerr << "Invalid number of arguments" << endl;
            cerr << "Usage: (in.avi|live[:idx_cam=0]) [-c camera_params.yml] [-s  marker_size_in_meters] [-d dictionary:ARUCO by default] [-h]" << endl;
            cerr<<"\tDictionaries: "; for(auto dict:aruco::Dictionary::getDicTypes())    cerr<<dict<<" ";cerr<<endl;
            cerr<<"\t Instead of these, you can directly indicate the path to a file with your own generated dictionary"<<endl;
            return false;
        }

        ///////////  PARSE ARGUMENTS
        string TheInputVideo = argv[1];
        // read camera parameters if passed
    if (cml["-c"] )  TheCameraParameters.readFromXMLFile(cml("-c"));
    float TheMarkerSize = std::stof(cml("-s","-1"));
    //aruco::Dictionary::DICT_TYPES  TheDictionary= Dictionary::getTypeFromString( cml("-d","ARUCO") );




    ///////////  OPEN VIDEO
    // read from camera or from  file
    if (TheInputVideo.find("live") != string::npos) {
        int vIdx = 0;
        // check if the :idx is here
        char cad[100];
        if (TheInputVideo.find(":") != string::npos) {
            std::replace(TheInputVideo.begin(), TheInputVideo.end(), ':', ' ');
            sscanf(TheInputVideo.c_str(), "%s %d", cad, &vIdx);
        }
        cout << "Opening camera index " << vIdx << endl;
        TheVideoCapturer.open(vIdx);
        waitTime = 10;
    }
    else TheVideoCapturer.open(TheInputVideo);
    // check video is open
    if (!TheVideoCapturer.isOpened())  throw std::runtime_error("Could not open video");

    ///// CONFIGURE DATA
    // read first image to get the dimensions
    TheVideoCapturer >> TheInputImage;
    if (TheCameraParameters.isValid())
        TheCameraParameters.resize(TheInputImage.size());

    MDetector.setDictionary(cml("-d","ARUCO"));//sets the dictionary to be employed (ARUCO,APRILTAGS,ARTOOLKIT,etc)
    MDetector.setThresholdParams(7, 7);
    MDetector.setThresholdParamRange(2, 0);
   //  MDetector.setCornerRefinementMethod(aruco::MarkerDetector::SUBPIX);

    //gui requirements : the trackbars to change this parameters
    iThresParam1 = MDetector.getParams()._thresParam1;
    iThresParam2 = MDetector.getParams()._thresParam2;
    cv::namedWindow("in");
    cv::createTrackbar("ThresParam1", "in", &iThresParam1, 25, cvTackBarEvents);
    cv::createTrackbar("ThresParam2", "in", &iThresParam2, 13, cvTackBarEvents);

    //go!
    char key = 0;
    int index = 0;
    // capture until press ESC or until the end of the video
    do {

        TheVideoCapturer.retrieve(TheInputImage);
        // copy image
        double tick = (double)getTickCount(); // for checking the speed
        // Detection of markers in the image passed
        TheMarkers= MDetector.detect(TheInputImage, TheCameraParameters, TheMarkerSize);
        // chekc the speed by calculating the mean speed of all iterations
        AvrgTime.first += ((double)getTickCount() - tick) / getTickFrequency();
        AvrgTime.second++;
        cout << "\rTime detection=" << 1000 * AvrgTime.first / AvrgTime.second << " milliseconds nmarkers=" << TheMarkers.size() << std::endl;

        // print marker info and draw the markers in image
        TheInputImage.copyTo(TheInputImageCopy);

        for (unsigned int i = 0; i < TheMarkers.size(); i++) {
            cout << TheMarkers[i]<<endl;
            TheMarkers[i].draw(TheInputImageCopy, Scalar(0, 0, 255));
        }

        // draw a 3d cube in each marker if there is 3d info
        if (TheCameraParameters.isValid() && TheMarkerSize>0)
            for (unsigned int i = 0; i < TheMarkers.size(); i++) {
                CvDrawingUtils::draw3dCube(TheInputImageCopy, TheMarkers[i], TheCameraParameters);
                CvDrawingUtils::draw3dAxis(TheInputImageCopy, TheMarkers[i], TheCameraParameters);
            }

        // DONE! Easy, right?
        // show input with augmented information and  the thresholded image
        cv::imshow("in", resize(TheInputImageCopy,1280));
        cv::imshow("thres", resize(MDetector.getThresholdedImage(),1280));


        key = cv::waitKey(waitTime); // wait for key to be pressed
        if(key=='s')  waitTime= waitTime==0?10:0;
        index++; // number of images captured
    } while (key != 27 && (TheVideoCapturer.grab() ));

} catch (std::exception &ex)

{
    cout << "Exception :" << ex.what() << endl;
}
}


void cvTackBarEvents(int pos, void *) {
(void)(pos);
if (iThresParam1 < 3)  iThresParam1 = 3;
if (iThresParam1 % 2 != 1)  iThresParam1++;
if (iThresParam1 < 1)  iThresParam1 = 1;
MDetector.setThresholdParams(iThresParam1, iThresParam2);
// recompute
MDetector.detect(TheInputImage, TheMarkers, TheCameraParameters);
TheInputImage.copyTo(TheInputImageCopy);
for (unsigned int i = 0; i < TheMarkers.size(); i++)
    TheMarkers[i].draw(TheInputImageCopy, Scalar(0, 0, 255));

// draw a 3d cube in each marker if there is 3d info
if (TheCameraParameters.isValid())
    for (unsigned int i = 0; i < TheMarkers.size(); i++)
        CvDrawingUtils::draw3dCube(TheInputImageCopy, TheMarkers[i], TheCameraParameters);

cv::imshow("in", resize(TheInputImageCopy,1280));
cv::imshow("thres", resize(MDetector.getThresholdedImage(),1280));
}
#包括
#包括
#包括
#包括
#包括“aruco.h”
#包括“cvdrawingutils.h”
#包括
#包括
使用名称空间cv;
使用aruco;
标记检测器MDetector;
视频捕捉器;
向量TheMarkers;
在输入图像上,输入图像副本;
摄像机参数摄像机参数;
空位(内部位置,空位*);
配对AvrgTime(0,0);//确定检测所需的平均时间
int ITHREPARAM1、ITHREPARAM2;
int waitTime=0;

类CmdLineParser{int argc;char**argv;public:CmdLineParser(int_argc,char**argv):argc(_argc),argv(_argv){}bool操作符[](string param){int idx=-1;for(int i=0;请共享从相机获取帧并发送到脚本的代码?我正在使用的代码可以从此链接下载:
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include "aruco.h" 
#include "cvdrawingutils.h"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace aruco;

MarkerDetector MDetector;
VideoCapture TheVideoCapturer;
vector< Marker > TheMarkers;
Mat TheInputImage, TheInputImageCopy;
CameraParameters TheCameraParameters;
void cvTackBarEvents(int pos, void *);

pair< double, double > AvrgTime(0, 0); // determines the average time required for detection
int iThresParam1, iThresParam2;
int waitTime = 0;
class CmdLineParser{int argc; char **argv; public: CmdLineParser(int _argc,char **_argv):argc(_argc),argv(_argv){}  bool operator[] ( string param ) {int idx=-1;  for ( int i=0; i<argc && idx==-1; i++ ) if ( string ( argv[i] ) ==param ) idx=i;    return ( idx!=-1 ) ;    } string operator()(string param,string defvalue="-1"){int idx=-1;    for ( int i=0; i<argc && idx==-1; i++ ) if ( string ( argv[i] ) ==param ) idx=i; if ( idx==-1 ) return defvalue;   else  return ( argv[  idx+1] ); }};


cv::Mat resize(const cv::Mat &in,int width){
    if (in.size().width<=width) return in;
    float yf=float(  width)/float(in.size().width);
    cv::Mat im2;
    cv::resize(in,im2,cv::Size(width,float(in.size().height)*yf));
    return im2;

}

int main(int argc, char **argv) {
    try {
        CmdLineParser cml(argc,argv);
        if (argc < 2  || cml["-h"]) {
            cerr << "Invalid number of arguments" << endl;
            cerr << "Usage: (in.avi|live[:idx_cam=0]) [-c camera_params.yml] [-s  marker_size_in_meters] [-d dictionary:ARUCO by default] [-h]" << endl;
            cerr<<"\tDictionaries: "; for(auto dict:aruco::Dictionary::getDicTypes())    cerr<<dict<<" ";cerr<<endl;
            cerr<<"\t Instead of these, you can directly indicate the path to a file with your own generated dictionary"<<endl;
            return false;
        }

        ///////////  PARSE ARGUMENTS
        string TheInputVideo = argv[1];
        // read camera parameters if passed
    if (cml["-c"] )  TheCameraParameters.readFromXMLFile(cml("-c"));
    float TheMarkerSize = std::stof(cml("-s","-1"));
    //aruco::Dictionary::DICT_TYPES  TheDictionary= Dictionary::getTypeFromString( cml("-d","ARUCO") );




    ///////////  OPEN VIDEO
    // read from camera or from  file
    if (TheInputVideo.find("live") != string::npos) {
        int vIdx = 0;
        // check if the :idx is here
        char cad[100];
        if (TheInputVideo.find(":") != string::npos) {
            std::replace(TheInputVideo.begin(), TheInputVideo.end(), ':', ' ');
            sscanf(TheInputVideo.c_str(), "%s %d", cad, &vIdx);
        }
        cout << "Opening camera index " << vIdx << endl;
        TheVideoCapturer.open(vIdx);
        waitTime = 10;
    }
    else TheVideoCapturer.open(TheInputVideo);
    // check video is open
    if (!TheVideoCapturer.isOpened())  throw std::runtime_error("Could not open video");

    ///// CONFIGURE DATA
    // read first image to get the dimensions
    TheVideoCapturer >> TheInputImage;
    if (TheCameraParameters.isValid())
        TheCameraParameters.resize(TheInputImage.size());

    MDetector.setDictionary(cml("-d","ARUCO"));//sets the dictionary to be employed (ARUCO,APRILTAGS,ARTOOLKIT,etc)
    MDetector.setThresholdParams(7, 7);
    MDetector.setThresholdParamRange(2, 0);
   //  MDetector.setCornerRefinementMethod(aruco::MarkerDetector::SUBPIX);

    //gui requirements : the trackbars to change this parameters
    iThresParam1 = MDetector.getParams()._thresParam1;
    iThresParam2 = MDetector.getParams()._thresParam2;
    cv::namedWindow("in");
    cv::createTrackbar("ThresParam1", "in", &iThresParam1, 25, cvTackBarEvents);
    cv::createTrackbar("ThresParam2", "in", &iThresParam2, 13, cvTackBarEvents);

    //go!
    char key = 0;
    int index = 0;
    // capture until press ESC or until the end of the video
    do {

        TheVideoCapturer.retrieve(TheInputImage);
        // copy image
        double tick = (double)getTickCount(); // for checking the speed
        // Detection of markers in the image passed
        TheMarkers= MDetector.detect(TheInputImage, TheCameraParameters, TheMarkerSize);
        // chekc the speed by calculating the mean speed of all iterations
        AvrgTime.first += ((double)getTickCount() - tick) / getTickFrequency();
        AvrgTime.second++;
        cout << "\rTime detection=" << 1000 * AvrgTime.first / AvrgTime.second << " milliseconds nmarkers=" << TheMarkers.size() << std::endl;

        // print marker info and draw the markers in image
        TheInputImage.copyTo(TheInputImageCopy);

        for (unsigned int i = 0; i < TheMarkers.size(); i++) {
            cout << TheMarkers[i]<<endl;
            TheMarkers[i].draw(TheInputImageCopy, Scalar(0, 0, 255));
        }

        // draw a 3d cube in each marker if there is 3d info
        if (TheCameraParameters.isValid() && TheMarkerSize>0)
            for (unsigned int i = 0; i < TheMarkers.size(); i++) {
                CvDrawingUtils::draw3dCube(TheInputImageCopy, TheMarkers[i], TheCameraParameters);
                CvDrawingUtils::draw3dAxis(TheInputImageCopy, TheMarkers[i], TheCameraParameters);
            }

        // DONE! Easy, right?
        // show input with augmented information and  the thresholded image
        cv::imshow("in", resize(TheInputImageCopy,1280));
        cv::imshow("thres", resize(MDetector.getThresholdedImage(),1280));


        key = cv::waitKey(waitTime); // wait for key to be pressed
        if(key=='s')  waitTime= waitTime==0?10:0;
        index++; // number of images captured
    } while (key != 27 && (TheVideoCapturer.grab() ));

} catch (std::exception &ex)

{
    cout << "Exception :" << ex.what() << endl;
}
}


void cvTackBarEvents(int pos, void *) {
(void)(pos);
if (iThresParam1 < 3)  iThresParam1 = 3;
if (iThresParam1 % 2 != 1)  iThresParam1++;
if (iThresParam1 < 1)  iThresParam1 = 1;
MDetector.setThresholdParams(iThresParam1, iThresParam2);
// recompute
MDetector.detect(TheInputImage, TheMarkers, TheCameraParameters);
TheInputImage.copyTo(TheInputImageCopy);
for (unsigned int i = 0; i < TheMarkers.size(); i++)
    TheMarkers[i].draw(TheInputImageCopy, Scalar(0, 0, 255));

// draw a 3d cube in each marker if there is 3d info
if (TheCameraParameters.isValid())
    for (unsigned int i = 0; i < TheMarkers.size(); i++)
        CvDrawingUtils::draw3dCube(TheInputImageCopy, TheMarkers[i], TheCameraParameters);

cv::imshow("in", resize(TheInputImageCopy,1280));
cv::imshow("thres", resize(MDetector.getThresholdedImage(),1280));
}