0

Делаю проект с использованием библиотеки opencv. при использовании #include <opencv2/opencv.hpp> всё работает замечательно. все собирается и ошибок нет. по при добавлении еще одного хедера из библиотеки выдает ошибку 2019 #include <aruco.hpp>. можете подсказать в чем ошибка?

try.cpp

#include <opencv2/opencv.hpp>
#include <aruco.hpp>
#include <iostream>

using namespace std;
using namespace cv;

namespace {
const char* about = "Basic marker detection";
const char* keys  =
    "{d        |       | dictionary: DICT_4X4_50=0, DICT_4X4_100=1,DICT_4X4_250=2,"
    "DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
    "DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
    "DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
   "{v        |       | Input from video file, if ommited, input comes from camera }"
   "{ci       | 0     | Camera id if input doesnt come from video (-v) }"
   "{c        |       | Camera intrinsic parameters. Needed for camera pose }"
   "{l        | 0.1   | Marker side lenght (in meters). Needed for correct scale in camera pose }"
   "{dp       |       | File of marker detector parameters }"
   "{r        |       | show rejected candidates too }";
}

static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeffs) {
FileStorage fs(filename, FileStorage::READ);
if(!fs.isOpened())
    return false;
fs["M1"] >> camMatrix;
fs["D1"] >> distCoeffs;
return true;
}

static bool readDetectorParameters(string filename, Ptr<aruco::DetectorParameters> &params) {
FileStorage fs(filename, FileStorage::READ);
if(!fs.isOpened())
    return false;
fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin;
fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax;
fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep;
fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant;
fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate;
fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate;
fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate;
fs["minCornerDistanceRate"] >> params->minCornerDistanceRate;
fs["minDistanceToBorder"] >> params->minDistanceToBorder;
fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate;
fs["doCornerRefinement"] >> params->doCornerRefinement;
fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize;
fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations;
fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy;
fs["markerBorderBits"] >> params->markerBorderBits;
fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell;
fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell;
fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate;
fs["minOtsuStdDev"] >> params->minOtsuStdDev;
fs["errorCorrectionRate"] >> params->errorCorrectionRate;
return true;
}

int main(int argc, char *argv[]) {
CommandLineParser parser(argc, argv, keys);
parser.about(about);

if(argc < 2) {
    parser.printMessage();
    return 0;
}

int dictionaryId = 0;//parser.get<int>("d");
bool showRejected = parser.has("r");
bool estimatePose = true;//parser.has("c");
float markerLength = 0.1;//parser.get<float>("l");

Ptr<aruco::DetectorParameters> detectorParams = aruco::DetectorParameters::create();
{
    bool readOk = readDetectorParameters("detector_params.yml"/*parser.get<string>("dp")*/, detectorParams);
    if(!readOk) {
        cerr << "Invalid detector parameters file" << endl;
        return 0;
    }
}
detectorParams->doCornerRefinement = true; // do corner refinement in markers

int camId = 1;//parser.get<int>("ci");

String video;
if(parser.has("v")) {
    video = parser.get<String>("v");
}

if(!parser.check()) {
    parser.printErrors();
    return 0;
}

Ptr<aruco::Dictionary> dictionary =
    aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));

Mat camMatrix, distCoeffs;
if(estimatePose) {
    bool readOk = readCameraParameters("SSSintrinsics.yml"/*parser.get<string>("c")*/, camMatrix, distCoeffs);
    if(!readOk) {
        cerr << "Invalid camera file" << endl;
        return 0;
    }
}

VideoCapture inputVideo;
int waitTime;
if(!video.empty()) {
    inputVideo.open(video);
    waitTime = 0;
} else {
    inputVideo.open(camId);
    waitTime = 10;
}

double totalTime = 0;
int totalIterations = 0;

while(inputVideo.grab()) {
    Mat image, imageCopy;
    inputVideo.retrieve(image);

    double tick = (double)getTickCount();

    vector< int > ids;
    vector< vector< Point2f > > corners, rejected;
    vector< Vec3d > rvecs, tvecs;

    // detect markers and estimate pose
    aruco::detectMarkers(image, dictionary, corners, ids, detectorParams, rejected);
    if(estimatePose && ids.size() > 0)
        aruco::estimatePoseSingleMarkers(corners, markerLength, camMatrix, distCoeffs, rvecs,
                                         tvecs);

    double currentTime = ((double)getTickCount() - tick) / getTickFrequency();
    totalTime += currentTime;
    totalIterations++;
    if(totalIterations % 30 == 0) {
        cout << "Detection Time = " << currentTime * 1000 << " ms "
             << "(Mean = " << 1000 * totalTime / double(totalIterations) << " ms)" << endl;
    }

    // draw results
    image.copyTo(imageCopy);
    if(ids.size() > 0) {
        aruco::drawDetectedMarkers(imageCopy, corners, ids);

        if(estimatePose) {
            for(unsigned int i = 0; i < ids.size(); i++)
                aruco::drawAxis(imageCopy, camMatrix, distCoeffs, rvecs[i], tvecs[i],
                                markerLength * 0.5f);
        }
    }

    if(showRejected && rejected.size() > 0)
        aruco::drawDetectedMarkers(imageCopy, rejected, noArray(), Scalar(100, 0, 255));

    imshow("out", imageCopy);
    char key = (char)waitKey(waitTime);
    if(key == 27) break;
}

return 0;
}

Aruco.hpp

#ifndef __OPENCV_ARUCO_HPP__
#define __OPENCV_ARUCO_HPP__

#include <opencv2/core.hpp>
#include <vector>
#include <opencv2/aruco/dictionary.hpp>

namespace cv {
namespace aruco {

//! @addtogroup aruco
//! @{

struct CV_EXPORTS_W DetectorParameters {

//DetectorParameters();

CV_WRAP static Ptr<DetectorParameters> create();

CV_PROP_RW int adaptiveThreshWinSizeMin;
CV_PROP_RW int adaptiveThreshWinSizeMax;
CV_PROP_RW int adaptiveThreshWinSizeStep;
CV_PROP_RW double adaptiveThreshConstant;
CV_PROP_RW double minMarkerPerimeterRate;
CV_PROP_RW double maxMarkerPerimeterRate;
CV_PROP_RW double polygonalApproxAccuracyRate;
CV_PROP_RW double minCornerDistanceRate;
CV_PROP_RW int minDistanceToBorder;
CV_PROP_RW double minMarkerDistanceRate;
CV_PROP_RW bool doCornerRefinement;
CV_PROP_RW int cornerRefinementWinSize;
CV_PROP_RW int cornerRefinementMaxIterations;
CV_PROP_RW double cornerRefinementMinAccuracy;
CV_PROP_RW int markerBorderBits;
CV_PROP_RW int perspectiveRemovePixelPerCell;
CV_PROP_RW double perspectiveRemoveIgnoredMarginPerCell;
CV_PROP_RW double maxErroneousBitsInBorderRate;
CV_PROP_RW double minOtsuStdDev;
CV_PROP_RW double errorCorrectionRate;
};

CV_EXPORTS_W void detectMarkers(InputArray image, const Ptr<Dictionary>     &dictionary, OutputArrayOfArrays corners,
                            OutputArray ids, const Ptr<DetectorParameters> &parameters = DetectorParameters::create(),
                            OutputArrayOfArrays rejectedImgPoints = noArray());


CV_EXPORTS_W void estimatePoseSingleMarkers(InputArrayOfArrays corners, float markerLength,
                                        InputArray cameraMatrix, InputArray distCoeffs,
                                        OutputArray rvecs, OutputArray tvecs);

class CV_EXPORTS_W Board {

public:

CV_WRAP static Ptr<Board> create(InputArrayOfArrays objPoints, const Ptr<Dictionary> &dictionary, InputArray ids);
/// array of object points of all the marker corners in the board
/// each marker include its 4 corners in CCW order. For M markers, the size is Mx4.
CV_PROP std::vector< std::vector< Point3f > > objPoints;

/// the dictionary of markers employed for this board
CV_PROP Ptr<Dictionary> dictionary;

/// vector of the identifiers of the markers in the board (same size than objPoints)
/// The identifiers refers to the board dictionary
CV_PROP std::vector< int > ids;
};

class CV_EXPORTS_W GridBoard : public Board {

public:

CV_WRAP void draw(Size outSize, OutputArray img, int marginSize = 0, int borderBits = 1);

CV_WRAP static Ptr<GridBoard> create(int markersX, int markersY, float markerLength,
                                     float markerSeparation, const Ptr<Dictionary> &dictionary, int firstMarker = 0);

/**
  *
  */
CV_WRAP Size getGridSize() const { return Size(_markersX, _markersY); }

/**
  *
  */
CV_WRAP float getMarkerLength() const { return _markerLength; }

/**
  *
  */
CV_WRAP float getMarkerSeparation() const { return _markerSeparation; }


private:
// number of markers in X and Y directions
int _markersX, _markersY;

// marker side lenght (normally in meters)
float _markerLength;

// separation between markers in the grid
float _markerSeparation;
};




CV_EXPORTS_W int estimatePoseBoard(InputArrayOfArrays corners, InputArray ids, const Ptr<Board> &board,
                               InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec,
                               OutputArray tvec, bool useExtrinsicGuess = false);

CV_EXPORTS_W void refineDetectedMarkers(
InputArray image,const  Ptr<Board> &board, InputOutputArrayOfArrays detectedCorners,
InputOutputArray detectedIds, InputOutputArrayOfArrays rejectedCorners,
InputArray cameraMatrix = noArray(), InputArray distCoeffs = noArray(),
float minRepDistance = 10.f, float errorCorrectionRate = 3.f, bool checkAllOrders = true,
OutputArray recoveredIdxs = noArray(), const Ptr<DetectorParameters> &parameters = DetectorParameters::create());




CV_EXPORTS_W void drawDetectedMarkers(InputOutputArray image, InputArrayOfArrays corners,
                                  InputArray ids = noArray(),
                                  Scalar borderColor = Scalar(0, 255, 0));

CV_EXPORTS_W void drawAxis(InputOutputArray image, InputArray cameraMatrix, InputArray distCoeffs,
                       InputArray rvec, InputArray tvec, float length);




CV_EXPORTS_W void drawMarker(const Ptr<Dictionary> &dictionary, int id, int sidePixels, OutputArray img,
                         int borderBits = 1);


CV_EXPORTS_W void drawPlanarBoard(const Ptr<Board> &board, Size outSize, OutputArray img,
                              int marginSize = 0, int borderBits = 1);


void _drawPlanarBoardImpl(Board *board, Size outSize, OutputArray img,
                      int marginSize = 0, int borderBits = 1);


CV_EXPORTS_AS(calibrateCameraArucoExtended) double calibrateCameraAruco(
InputArrayOfArrays corners, InputArray ids, InputArray counter, const Ptr<Board> &board,
Size imageSize, InputOutputArray cameraMatrix, InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs,
OutputArray stdDeviationsIntrinsics, OutputArray stdDeviationsExtrinsics,
OutputArray perViewErrors, int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON));



CV_EXPORTS_W double calibrateCameraAruco(
  InputArrayOfArrays corners, InputArray ids, InputArray counter, const Ptr<Board> &board,
  Size imageSize, InputOutputArray cameraMatrix, InputOutputArray distCoeffs,
  OutputArrayOfArrays rvecs = noArray(), OutputArrayOfArrays tvecs = noArray(), int flags = 0,
  TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON));


//! @}
}
}

#endif

Сами ошибки

  • Ошибка LNK2019 ссылка на неразрешенный внешний символ "struct cv::Ptr __cdecl cv::aruco::getPredefinedDictionary(enum cv::aruco::PREDEFINED_DICTIONARY_NAME)" (?getPredefinedDictionary@aruco@cv@@YA?AU?$Ptr@VDictionary@aruco@cv@@@2@W4PREDEFINED_DICTIONARY_NAME@12@@Z) в функции main
  • Ошибка LNK2019 ссылка на неразрешенный внешний символ "public: static struct cv::Ptr __cdecl cv::aruco::DetectorParameters::create(void)" (?create@DetectorParameters@aruco@cv@@SA?AU?$Ptr@UDetectorParameters@aruco@cv@@@3@XZ) в функции main
  • Ошибка LNK2019 ссылка на неразрешенный внешний символ "void __cdecl cv::aruco::detectMarkers(class cv::debug_build_guard::_InputArray const &,struct cv::Ptr const &,class cv::debug_build_guard::_OutputArray const &,class cv::debug_build_guard::_OutputArray const &,struct cv::Ptr const &,class cv::debug_build_guard::_OutputArray const &)" (?detectMarkers@aruco@cv@@YAXAEBV_InputArray@debug_build_guard@2@AEBU?$Ptr@VDictionary@aruco@cv@@@2@AEBV_OutputArray@42@2AEBU?$Ptr@UDetectorParameters@aruco@cv@@@2@2@Z) в функции main
  • Ошибка LNK2019 ссылка на неразрешенный внешний символ "void __cdecl cv::aruco::estimatePoseSingleMarkers(class cv::debug_build_guard::_InputArray const &,float,class cv::debug_build_guard::_InputArray const &,class cv::debug_build_guard::_InputArray const &,class cv::debug_build_guard::_OutputArray const &,class cv::debug_build_guard::_OutputArray const &)" (?estimatePoseSingleMarkers@aruco@cv@@YAXAEBV_InputArray@debug_build_guard@2@M00AEBV_OutputArray@42@1@Z) в функции main
  • Ошибка LNK2019 ссылка на неразрешенный внешний символ "void __cdecl cv::aruco::drawDetectedMarkers(class cv::debug_build_guard::_InputOutputArray const &,class cv::debug_build_guard::_InputArray const &,class cv::debug_build_guard::InputArray const &,class cv::Scalar)" (?drawDetectedMarkers@aruco@cv@@YAXAEBV_InputOutputArray@debug_build_guard@2@AEBV_InputArray@42@1V?$Scalar_@N@2@@Z) в функции main
  • Ошибка LNK2019 ссылка на неразрешенный внешний символ "void __cdecl cv::aruco::drawAxis(class cv::debug_build_guard::_InputOutputArray const &,class cv::debug_build_guard::_InputArray const &,class cv::debug_build_guard::_InputArray const &,class cv::debug_build_guard::_InputArray const &,class cv::debug_build_guard::_InputArray const &,float)" (?drawAxis@aruco@cv@@YAXAEBV_InputOutputArray@debug_build_guard@2@AEBV_InputArray@42@111M@Z) в функции main
  • Ошибка LNK1120 неразрешенных внешних элементов: 6

все что было сделано

Для начала скажу что библиотека находится по пути

С:\opencv

Что было сделано:

  1. Добавлен путь(C:\opencv\build\x64\vc15\bin) в переменную PATH
  2. В настройках проекта для режима Debug x64 во включаемые каталоги добавлены пути(C:\opencv\build\include; C:\opencv\build\include\opencv2) и в компоновщик в дополнительные каталоги библиотек добавлен путь(C:\opencv\build\x64\vc15\lib), во вкладке ввод компоновщика в дополнительные зависимости добавлен файл(opencv_world341d.lib).

ссылка на opencv https://sourceforge.net/projects/opencvlibrary/files/opencv-win/3.4.1/opencv-3.4.1-vc14_vc15.exe/download

  • нет это не то, используемые хедеры и либы ключенны в проект. иначе бы вообще ничего не работало – DR.zarigan Jun 09 '18 at 09:18
  • @DR.zarigan, значит не все либы включил... – Fat-Zer Jun 09 '18 at 10:15
  • @Fat-Zer, все либы что были они добелены в проект и и в linker я тоже все прописал что нужно было. – DR.zarigan Jun 09 '18 at 18:32
  • @DR.zarigan, по хорошей традиции в таких вопросах принято верить выводам программ, а не словам человека. Так вот, вывод линкера говорит, что добавлено не всё... и пока ты не приведёшь список, что и куда прописал тебе скорей всего не поверят... ЗЫ: под вопросом есть кнопка «править»; информацию такого рода крайней желательно будет привести текстом. – Fat-Zer Jun 09 '18 at 21:04
  • @Fat-Zer, дополнил, но мне все-таки кажется что ошибка в другом – DR.zarigan Jun 10 '18 at 07:38
  • Теперь вопрос на засыпку: в какой библиотеке определены символы, объявляемые в aruco.hpp? – user7860670 Jun 10 '18 at 09:43
  • Обычно opencv разбит на десяток с лишним библиотек, но я не знаю специфику дистрибутива оного и то, какие статические либы он включает под win, так что допущу, что opencv_world341d.lib включает их все... в любом случае библиотека aruco является отдельным проектом и я не вижу, упоминания, что ты её где-то подключил... – Fat-Zer Jun 10 '18 at 14:55
  • @Fat-Zer@VTT, aruco.hpp так же как и сама папка aruco находится в C:\opencv\build\include\opencv2 – DR.zarigan Jun 10 '18 at 16:31
  • @VTT а сама aruco.hpp использует <opencv2/opencv.hpp> <opencv2/aruco/dictionary.hpp> они все имеются по пути C:\opencv\build\include; кроме вектора конечно – DR.zarigan Jun 10 '18 at 16:35
  • 1
    Вы как-то не разделяете заголовочные файлы и либы. Мой предыдущий вопрос был в смысле "в какой экспортной (lib) и динамической (dll) или статической (lib) библиотеке определены символы, которые объявляются в заголовочном файле aruco.hpp" . Такой вопрос следует задавать себе при подключении любого заголовочного файла. – user7860670 Jun 10 '18 at 18:36
  • @DR.zarigan, конкретизируя мысль VTT, где-то должна быть *aruco*.{lib,dll} и её также надо скормить линкеру... – Fat-Zer Jun 11 '18 at 01:22
  • @Fat-Zer, больше нет файлов lib или dll. – DR.zarigan Jun 11 '18 at 15:56
  • @DR.zarigan, тогда надо раздобыть или собрать её... aruco.hpp ты же где-то взял... с деталями я здесь помочь не смогу т.к. в специфике win не разбираюсь... – Fat-Zer Jun 12 '18 at 05:47
  • @DR.zarigan, во первых, хочу себя поправить: aruco сейчас часть пакета contrib-библиотек opencv начиная с 3.1.0. Но в тот пакет который ты скачал они не входят. Во-вторых, из одного хедера библиотеку собрать нельзя, нужен полный пакет исходников. Где ты вообще взял этот хедер? В-третьих ещё раз повторюсь, специфику сборки под win/msvc я не знаю, так что помочь с этим вряд ли смогу. Разве что отошлю к докам. Где взять уже собранные библиотеки из opencv_contrib я тоже не подскажу... – Fat-Zer Jun 12 '18 at 10:34
  • @Fat-Zer, взят aruco из opencv_contrib с GitHub, у меня есть cpp и hpp файлы из них можно получить lib для использования в проекте или понадобится еще dll? – DR.zarigan Jun 12 '18 at 11:51
  • @DR.zarigan стоило забрать весь репозитарий и собрать его... – Fat-Zer Jun 12 '18 at 12:01
  • @Fat-Zer, собрал aruco.lib и скормил его ликеру ошибка осталась – DR.zarigan Jun 12 '18 at 19:50
  • @DR.zarigan, гм... скорей всего ты что-то сделал не так, но чтобы предположить, что именно, дальше анализировать и давать советы я уже недостаточно компетентен... – Fat-Zer Jun 13 '18 at 03:51
  • добавил все в VS но допустим когда пишу '#include <opencv2/aruco.hpp>' не видит хотя файл по этому пути существует и в настройках проекта указан путь доп. каталога включаемых файлов и в линкер все lib затолкал и путь прописал – DR.zarigan Jun 13 '18 at 18:33

0 Answers0