Захват видео с помощью монохромной камеры в aruco opencv

В настоящее время я пытаюсь использовать монохромную камеру с библиотеками aruco и opencv, чтобы ускорить вычисления и улучшить захват маркеров. У меня проблема в том, что при запуске программы aruco_test монохромная подача утраивается на экране, поэтому разрешение уменьшается на две трети, а маркеры обнаруживаются три раза, а не один.

Я видел каналы, которые говорят о похожих проблемах с монохромными камерами в opencv. В некоторых ответах предлагалось обрезать изображение (что устраняет проблему утроения, но не меньшее разрешение), но, похоже, все это вызвано преобразованием из BGR2GRAY или GRAY2BGR.
Буду признателен за любую помощь в том, что именно вызывает утроение изображений и как обойти эту часть либо в исходном коде aruco, либо в исходном коде opencv.

ИНФОРМАЦИЯ :

Информация о драйвере (без использования libv4l2):

Driver name   : uvcvideo
Card type     : oCam-1MGN-U
Bus info      : usb-0000:00:1d.0-1.5
Driver version: 3.13.11
Capabilities  : 0x84000001
Video Capture
Streaming
Device Capabilities
Device Caps   : 0x04000001
Video Capture
Streaming
Priority: 2
Video input : 0 (Camera 1: ok)
Format Video Capture:
Width/Height  : 1280/960
Pixel Format  : 'GREY'
Field         : None
Bytes per Line: 1280
Size Image    : 1228800
Colorspace    : Unknown (00000000)
Crop Capability Video Capture:
Bounds      : Left 0, Top 0, Width 1280, Height 960
Default     : Left 0, Top 0, Width 1280, Height 960
Pixel Aspect: 1/1
Streaming Parameters Video Capture:
Capabilities     : timeperframe
Frames per second: 30.000 (30/1)
Read buffers     : 0
brightness (int)    : min=0 max=127 step=1 default=64 value=64
exposure_absolute (int)    : min=1 max=625 step=1 default=39 value=39

Использование 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));
}

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]