[英]Creating opencv Mat to 2d grid
我正在構建一個使用OpenCV Mat的搜索算法,我將Mat轉換為灰色圖像,然后檢查像素以將其標記為可行走或不可行走的坐標。 我使用矢量>網格。 當我嘗試從網格中打印nodeID時,程序突然關閉(例如grid.grid[10][10]->NodeID
)。
using namespace std;
int gridZise;
class location{
public:
int x;
int y;
};
class Node{
public:
int gridX;
int gridY;
bool walkable;
location worldPosition;
int NodeID;
int gCost;
int hCost;
Node *parent;
Node(bool _walkable, int _gridX, int _gridY)
{
walkable = _walkable;
gridX = _gridX;
gridY = _gridY;
NodeID = gridY * gridZise + gridX;
}
Node(int _gridX, int _gridY){
gridX = _gridX;
gridY = _gridY;
NodeID = gridY * gridZise + gridX;
}
int fCost(){
return gCost + hCost;
}
};
class Grid{
public:
cv::Mat map;
vector<vector<Node*> > grid;
int gridx;
int gridy;
Grid(cv::Mat _map){
map = _map;
gridx = map.cols;
gridy = map.cols;
gridZise = map.cols;
}
void CreateGrid(){
// Set up sizes. (HEIGHT x WIDTH)
grid.resize(gridy);
for (int i = 0; i < gridy; ++i)
grid[i].resize(gridx);
// build up the grid
for(int i=0; i <gridx;i++){
for(int j=0; j < gridy;j++){
int pixel_val = map.at<int>(i,j);
bool _walkable = false;
if(pixel_val > 120){//if the value of the pixel is bigger than 120 is walkable
_walkable = true;
}
grid[i][j]->walkable = _walkable;
grid[i][j]->gridX = i;
grid[i][j]->gridY = j;
}
}
}
void PrintGrid(){
for(int i=0; i <gridx;i++){
for(int j=0; j < gridy;j++){
cout << grid[i][j]->NodeID <<endl;
}
}
}
vector<Node> GetNeighbours(Node node)
{
vector<Node> neighbours;
for (int x = -1; x <=1; x++)
{
for (int y = -1; y <= 1; y++)
{
if (x == 0 && y == 0)
continue;
int checkX = node.gridX + x;
int checkY = node.gridY + y;
if(checkX >=0 && checkX < gridx && checkY >=0 && checkY < gridy)
{
Node neighbour(checkX,checkY);
neighbours.push_back(neighbour);
}
}
}
return neighbours;
}
Node nodeFromLocation(location _node){
Node currentNode = *grid[_node.x][_node.y];
return currentNode;
}
};
using namespace cv;
int main()
{
cv::Mat img;
img = imread("C:\\Users\\abdulla\\Pictures\\maze.jpg");
if(img.empty()){
cout<<"image not load "<<endl;
return -1;
}
cvtColor(img,img,CV_BGR2GRAY);
imshow("image",img);
waitKey();
Grid grid(img);
grid.PrintGrid();
return 0;
}
謝謝。
首先,擺脫using namespace std;
。 雖然它看起來很方便,但你正在為自己設置一些令人討厭的驚喜(參見這個問題)。
Grid
的構造函數使用Grid::grid
的默認構造函數,它創建一個空向量。
在PrintGrid
您會得到未定義的行為。
grid; // ok, grid is a member of Grid
grid[0]; // Returns a reference. No bounds checking is performed.
grid[0][0]; // undefined behaviour. grid[0] is outside of bounds.
有一個方法CreateGrid
在這里不相關,因為你永遠不會調用它。 但是我們假設你已經打過電話了。 然后PrintGrid會像這樣工作:
grid; // ok, grid is a member of Grid
grid[0]; // ok
grid[0][0]; // ok, return a pointer to a Node. Which you never initialized.
grid[0][0]->NodeID; // Undefined behaviour. You're trying to access a random memory location.
你真的需要將節點存儲為指針嗎? 你也可以使用vector<vector<Node>>
。 這樣,某人( std::vector<...
)將負責分配和刪除節點。 您仍然可以使用指針指向父節點,只要指針用作引用而不是所有權,這就沒問題。
如果您確實需要存儲指針,請使用智能指針 。 這樣,有人會負責刪除節點。
最后, Grid
類負責維護正確的狀態。 總是。 所以構造函數應該已經完成了CreateGrid
工作。 問題是你不能從構造函數中調用CreateGrid
,因為那時你將調用一個生命尚未開始的對象的方法(如果我錯了那個人就會糾正我)。 如果你想把它作為一個單獨的函數,你可以使CreateGrid
靜態:
class Grid {
Grid(cv::Mat _map):
map(_map),
gridx(_map.cols),
gridy(_map.cols),
gridZise(_map.cols),
{
GreateGrid(grid, map, gridx, gridy);
}
//...
static void CreateGrid(std::vector<std::vector<Node>> & grid, cv::Mat map, int gridx, int grid y) {
//...
}
//...
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.