c++ - 错误 LNK2019 : unresolved external symbol Visual Studio 2013 with openCV

标签 c++ opencv visual-studio-2013

我将 OpenCV 2.4.10 与 Visual Studio 2013 一起用于我的代码。但是我收到以下链接错误:

1>Pathfinding.obj : error LNK2019: unresolved external symbol "public: class cv::Vec & __cdecl cv::Mat::at >(int,int)" (??$at@V?$Vec@E$02@cv@@@Mat@cv@@QEAAAEAV?$Vec@E$02@1@HH@Z) referenced in function "private: struct Pathfinding::Point2A * __cdecl Pathfinding::GetNeighbors(struct Pathfinding::Point2A,int &)" (?GetNeighbors@Pathfinding@@AEAAPEAUPoint2A@1@U21@AEAH@Z)

1>C:\Users\ysingh\Documents\DstarLite\OpenCV\Astar\x64\Debug\Astar.exe : fatal error LNK1120: 1 unresolved externals ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

这里是头文件(请参见类定义中的struct Point2A),上面的错误是指:

#include<opencv2\core\core.hpp>
#include<opencv2\imgproc\imgproc.hpp>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<string>



class Pathfinding
{
private :
//Two dimensional , integer -based point structure , contains additional variables for pathfinding calculation

**struct Point2A**
{
    // x, y the coordinates of the point
    //dir is the direction from the previous point . see directions coding below

    int x, y, dir;


    //level: the cost of route from start to this point
    //fscore: the essence of the A* algorithm, value is : [level] + [in air distance from destination] * astar_weight

    float fScore, level;

    //Constructors
    Point2A() : x(0), y(0), fScore(0), dir(0){};
    Point2A(int _x, int _y, float _level = 0.f, int _dir = 0) :x(_x), y(_y), level(_level), fScore(0), dir(_dir) {};

    //== operator overload
    bool operator == (const Point2A other);

};

//CompByPos : struct used in the stl map<Point2A, Point2A> during the pathfinding
//it only contains a comparator function
//we need this, because every point is unique by position, but not by fscore

struct CompByPos
{

    bool operator()(const Point2A a, const Point2A b) const;
};

//CompByFScore : contains a comparating function, which works by fscore
//it gives priority for the smaller fScore
//used in stl priority_queue<Point2A>

struct CompByFScore
{
    bool operator()(const Point2A a, const Point2A b);
};

//mapimg is the map got, pathmap is the same, but the pixels of the path are colored
//pathmap is only valid after calculate path
//blurmap is matimg blurred with opencv function, its used in keeping away from walls

cv::Mat mapimg, pathmap, blurmap;


//astar_weight is the multiplier of A* coefficient
//wall_weight is used in keeping away from walls features

float astar_weight, wall_weight;

//no comment
Point2A start, dest;

//daigonal decides if a pixel (which is a node) has 4 or 8 neighbours
//see direction coding below
//calculated decides if the Pathfinding object has valid path for current map and settings

bool diagonal, calculated;

//mrows and mcols refers to the size of mapimg
//blursize is used in avaoiding wall avoidance feature

int mrows, mcols, blur_size;

//stores the list of directions for the path
std::string dir;


//calculated Eucledian Distance between two points a and b

float Distance(Point2A a, Point2A b);

//returns an array of the points surrounding point p
//the length of the array is not constant, because the function performs
//OnMap checks too. use arraySize ref variable to get the size of the array returned

Point2A* GetNeighbors(Point2A p, int& arraySize);

// Function sets default values
void InitValues();

//Checks if point p is wall
//Class support black and white maps, where black pixels are wall

bool IsWall(Point2A p);

//Function decides if coordinates of this point are on map or not 
bool OnMap(int x, int y);

public:

enum ErrorCodes 
{
    NoError = 0,
    NoMap,
    StartIsWall,
    DestIsWall,
    NoPath,
    AlreadyCalculated

};

static const int diagonalDirX[];
static const int diagonalDirY[];
static const int nonDiagonalDirX[];
static const int nonDiagonalDirY[];

//constructor :sets default values diagonal = true, astar coefficient 0.3
Pathfinding();

 //constructor, argument map is the map on which algorithm is implemented
Pathfinding(cv::Mat map, bool _diagonal = true);

//Set OpenCV Mat image as the map
void SetMap(cv::Mat map);

////sets the A* pathfinding coefficient. 0.f means Dijkstra's algorithm, anything else is A* (positive values recommended).
//The bigger the value, the more the algorithm steers towards the destination
//but setting it too high can result in suboptimal path
//after changing that, have to call CalculatePath again

void SetAWeight(float weight);

//if set to true, each pixel has 8 connected neighbor, else only 4 - see GetDirections() comment
//after changing that, have to call CalculatePath again
void SetDiagonal(bool _diagonal);

//sets the value of how much the algorithm tries to avoid going near walls. 
//weight: the amount the walls push away the route. default 10.f
//0.f disables the feature
//avoidZoneLevel: the size of the zone surrounding the walls, in which the upper effect works. default: 5
void SetWallWeight(float weight, int avoidZoneLevel);

//sets the start point. the coordinate system is the OpenCV/image default, the origin is the upper left corner of the image.
//start and destination points have to be set after the map image!
void SetStart(int x, int y);
void SetDestination(int x, int y);

//returns the map, on which the calculated path is marked red
//call this after CalculatePath(), otherwise returns empty map
cv::Mat GetPathMap();

// returns a std::string of numbers, which represent the directions along the path.Direction coding(relative to p) :
    //call after CalculatePath()
    //if diagonal is set to true                if diagonal == false
    //      [0] [1] [2]                                 [3]
    //      [3] [p] [4]                             [2] [p] [0]
    //      [5] [6] [7]                                 [1]
std::string GetDirections();

//evaluates the algorithm. It's a separate function because it takes some time
//check out the ErrorCodes enum to decode the returned values
ErrorCodes CalculatePath();
};

我还附加了这个类的.cpp

#include "Pathfinding.h"

bool Pathfinding::Point2A::operator==(const Point2A other) {

return x == other.x && y == other.y;
}

bool Pathfinding::CompByPos::operator()(const Point2A a, const Point2A b) const 
{

if (a.x == b.x)
    return a.y > b.y;
else
    return a.x > b.x;
  }

bool Pathfinding::CompByFScore::operator()(const Point2A a, const Point2A b) 
    {

return a.fScore > b.fScore;
   }

float Pathfinding::Distance(Point2A a, Point2A b) 
{

float x = static_cast<float>(a.x - b.x);
float y = static_cast<float>(a.y - b.y);
return sqrtf(x*x + y*y);
 }

Pathfinding:: Point2A* Pathfinding::GetNeighbors(Point2A p, int& arraySize)
{

arraySize = 0;
uchar size;

if (diagonal)
    size = 8;
else
    size = 4;

Point2A* ret = new Point2A[size];
for (int i = 0; i < size; i++) {

    int x, y;
    if (diagonal)
   {

        x = p.x + diagonalDirX[i];
        y = p.y + diagonalDirY[i];
    }
    else 
    {
        x = p.x + nonDiagonalDirX[i];
        y = p.y + nonDiagonalDirY[i];
    }

    if (!OnMap(x, y))
        continue;

    float level = p.level + 1.f + (255 - blurmap.at<cv::Vec3b>(y, x)[2]) / 255.f * wall_weight;
    Point2A n = Point2A(x, y, level, i);

    if (diagonal && (i == 0 || i == 2 || i == 5 || i == 7))
        n.level += 0.414213f;

    ret[arraySize] = n;
    arraySize++;
}
return ret;
}

void Pathfinding::InitValues()
{

astar_weight = 0.3f;
wall_weight = 10.f;
blur_size = 11;
diagonal = true;
calculated = false;
 }

bool Pathfinding::IsWall(Point2A p) 
 {

if (mapimg.at<cv::Vec3b>(p.y, p.x) == cv::Vec3b(0, 0, 0))
    return true;
return false;
}

bool Pathfinding::OnMap(int x, int y) 
{

if (x >= 0 && y >= 0 && x < mcols && y < mrows)
    return true;
return false;
}

 const int Pathfinding::diagonalDirX[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
 const int Pathfinding::diagonalDirY[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
 const int Pathfinding::nonDiagonalDirX[] = { 1, 0, -1, 0 };
 const int Pathfinding::nonDiagonalDirY[] = { 0, 1, 0, -1 };

Pathfinding::Pathfinding() 
   {

InitValues();
   }

Pathfinding::Pathfinding(cv::Mat map, bool _diagonal)
 {

InitValues();
SetMap(map);
diagonal = _diagonal;
}

void Pathfinding::SetMap(cv::Mat map) 
{

if (!map.empty()) 
        {

    mapimg = map;
    calculated = false;
    mrows = map.rows;
    mcols = map.cols;
    GaussianBlur(mapimg, blurmap, cv::Size(blur_size, blur_size), 0);
       }
   }

void Pathfinding::SetAWeight(float weight)
     {

if (astar_weight != weight)  
      {

    astar_weight = weight;
    calculated = false;
       }
  }

void Pathfinding::SetDiagonal(bool _diagonal)
     {

if (diagonal != _diagonal) 
      {

    diagonal = _diagonal;
    calculated = false;
       }
  }

void Pathfinding::SetWallWeight(float weight, int avoidZoneLevel)
     {

if (wall_weight == weight && blur_size == 2 * avoidZoneLevel + 1)
    return;

wall_weight = weight;
if (avoidZoneLevel >= 0)
    blur_size = 2 * avoidZoneLevel + 1;
calculated = false;
    }

void Pathfinding::SetStart(int x, int y) 
         {

if (!mapimg.empty()) 
        {

    if (OnMap(x, y))
      {

        start = Point2A(x, y);
        calculated = false;
       }
     }
  }

void Pathfinding::SetDestination(int x, int y)  
 {

if (!mapimg.empty()) 
  {

    if (OnMap(x, y)) 
 {

        dest = Point2A(x, y);
        calculated = false;
       }
   }
  }

cv::Mat Pathfinding::GetPathMap() 
 {

if (calculated) return pathmap;
else return cv::Mat();
  }

std::string Pathfinding::GetDirections() 
 {

if (calculated) return dir;
else return std::string();
 }

Pathfinding::ErrorCodes Pathfinding::CalculatePath() 
{

if (calculated)
    return AlreadyCalculated;

if (mapimg.empty())
    return NoMap;

if (IsWall(start))
    return StartIsWall;

if (IsWall(dest))
    return DestIsWall;

dir = std::string();
mapimg.copyTo(pathmap);
int **closedSet = new int*[mrows];
float **openSet = new float*[mrows];
for (int i = 0; i < mrows; i++) {

    closedSet[i] = new int[mcols];
    openSet[i] = new float[mcols];
    for (int j = 0; j < mcols; j++) {

        closedSet[i][j] = 0;
        openSet[i][j] = -1.0f;
       }
   }

    std::priority_queue<Pathfinding::Point2A, std::vector<Point2A>, CompByFScore> openSetQue[2];
int osq = 0;
std::map <Pathfinding::Point2A, Pathfinding::Point2A, CompByPos> cameFrom;

start.fScore = Distance(start, dest);
openSetQue[osq].push(start);
openSet[start.y][start.x] = 0.0f;
while (openSetQue[osq].size() != 0) {
    Point2A current = openSetQue[osq].top();
    if (current == dest) {
        while (cameFrom.size() != 0) {

            pathmap.at<cv::Vec3b>(current.y, current.x) = cv::Vec3b(0, 0, 255);
            dir = std::to_string(current.dir) + dir;
            auto it = cameFrom.find(current);
            Point2A keytmp = current;
            if (it == cameFrom.end()) {
                for (int i = 0; i < mrows; i++) {

                    delete openSet[i];
                    delete closedSet[i];
                }
                delete openSet;
                delete closedSet;
                calculated = true;
                dir = dir.substr(1, dir.length() - 1);
                return NoError;
            }
            current = cameFrom[current];
            cameFrom.erase(keytmp);
        }
    }
    openSetQue[osq].pop();
    closedSet[current.y][current.x] = 1;
    int arraySize;
    Point2A *neighbors = GetNeighbors(current, arraySize);

    for (int i = 0; i < arraySize; i++) {

        Point2A neighbor = neighbors[i];

        if (closedSet[neighbor.y][neighbor.x] == 1)
            continue;

        if (IsWall(neighbor)) {

            closedSet[neighbor.y][neighbor.x] = 1;
            continue;
        }
        float ngScore = neighbor.level;

        if (openSet[neighbor.y][neighbor.x] == -1.0f || ngScore < openSet[neighbor.y][neighbor.x]) {

            cameFrom[neighbor] = current;
            neighbor.fScore = ngScore + Distance(neighbor, dest) * astar_weight;

            if (openSet[neighbor.y][neighbor.x] == -1.0f) {
                openSet[neighbor.y][neighbor.x] = ngScore;
                openSetQue[osq].push(neighbor);
            }
            else {
                openSet[neighbor.y][neighbor.x] = ngScore;
                while (!(neighbor == openSetQue[osq].top())) {

                    openSetQue[1 - osq].push(openSetQue[osq].top());
                    openSetQue[osq].pop();
                }
                openSetQue[osq].pop();
                if (openSetQue[osq].size() >= openSetQue[1 - osq].size()) {
                    osq = 1 - osq;
                }
                while (!openSetQue[osq].empty()) {
                    openSetQue[1 - osq].push(openSetQue[osq].top());
                    openSetQue[osq].pop();
                }
                osq = 1 - osq;
                openSetQue[osq].push(neighbor);
               }
           }
       }
    delete neighbors;
    }
return NoPath;
}

这也是我的主文件 .cpp :

#include"Pathfinding.h"
#include<opencv2\highgui\highgui.hpp>
#include<iostream>


Pathfinding pathfinding;
cv::Mat mapimg;


void DisplayMap()
{
cv::Mat tmp;
cv::imshow("Path", tmp);
}

int main()
{
//Open and load the map

mapimg = cv::imread("test.png");
pathfinding.SetMap(mapimg);
pathfinding.SetWallWeight(0.f, 0);
pathfinding.SetStart(1, 1);
pathfinding.SetDestination(39, 53);
pathfinding.SetDiagonal(false);
DisplayMap();

 }

我想我在 .cpp 中的函数定义中使用了 Pathfinding 类两次(即 .cpp 文件中的第 29 行 > Pathfinding::Point2A* Pathfinding::GetNeighbors(Point2A p, int& arraySize)

我的目的不是向人们扔一堆代码,而是给他们一个完整的问题图,以便人们可以给我一些有用的建议。对此我深表歉意。

我的截止日期临近,我的时间很紧张。有人可以建议我一些解决方案。

最佳答案

我认为您的项目设置是问题所在(您写的是一个有效的简约示例,因此您确实使用了正确的库和包含)。

请检查 include 和 lib 路径的计算结果(在配置站点中检查)。也许您看到它们是相对路径或宏设置错误。

通常,“UNRESOLVED EXTERNAL”错误意味着您没有链接正确的库(32/64 调试/发布这些是 4 种不同的组合!)或者库的路径错误。

关于c++ - 错误 LNK2019 : unresolved external symbol Visual Studio 2013 with openCV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44117087/

相关文章:

ember.js - 如何将 ember cli 与 Visual Studio 结合使用

c++ - 如何围绕任意点旋转一组二维形状

c++ - 如何使用 C 或 C++ 获取目录中的文件列表?

c++ - OpenCV 从图像中获取人脸并使用模型进行预测

java - 如何使用opencv编辑图像以使用OCR读取文本

android - OpenCV Android Studio 模块导入问题

c# - Microsoft visual studio 2013 is busy 错误

用作数组安全包装的结构体的 C++ 性能

c++ - 在循环外存储 C++ 数组

git - 无法在 Visual Studio 2013 中同步 Git