我是Linux编程的初学者,这是我的问题。 我的项目是C ++在Linux环境下编写的OpenCV项目。为了编译,我使用CMake构建一个Makefile并运行。为了说清楚,我也是玩CMake的新手。
首先,我有一个main.cpp,它可以启动所有内容:
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cstdio>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <map>
#include <vector>
#include <cmath>
#include <dirent.h>
#include <algorithm>
#include <string.h>
using namespace std;
#include "constants.h"
#include "readData.cpp"
#include "features.cpp"
#include "featuresRGBD.cpp"
bool USE_HOG = true;
// print error message
void errorMsg(string message) {
cout << "ERROR! " << message << endl;
exit(1);
}
正如我们所看到的,我已经包含了一些预定义文件:constants.h,readData.cpp,features.cpp和featuresRGBD.cpp
在constaints.cpp中,我设置了一些常量变量:
const int SLEEP_TIME = 0;
const int JOINT_NUM = 11;
const int JOINT_DATA_ORI_NUM = 9;
const int JOINT_DATA_POS_NUM = 3;
const int JOINT_DATA_NUM = (JOINT_DATA_ORI_NUM+JOINT_DATA_POS_NUM);
const int JOINT_DATA_TYPE_NUM = 2; // two types : orientation and xyz position
const int TORSO_JOINT_NUM = 2;
const int HEAD_JOINT_NUM = 0;
const int POS_JOINT_NUM = 4;
const int POS_JOINT_DATA_NUM = 3;
const int POS_LEFT_HAND_NUM = 0;
const int POS_RIGHT_HAND_NUM = 1;
const int POS_LEFT_FOOT_NUM = 2;
const int POS_RIGHT_FOOT_NUM = 3;
const int X_RES = 320;
const int Y_RES = 240;
const int RGBD_data = 4;
// 30 fps
const int frameStoreNum = 66;
const int compareFrame[] = {0, -5, -9, -14, -20, -27, -35, -44, -54, -65};
const int compareFrameNum = sizeof(compareFrame)/sizeof(compareFrame[0]);
在readData.cpp中,我使用constants.cpp中的一些常量实现了我的方法
bool READ_FROM_PNG = true;
class readData {
private:
int currentFrameNum;
int currentFrameNum_RGBD;
int lastFrame;
string dataLocation;
string dataLocation_mirrored;
string fileName;
string fileName_skeleton;
string fileName_RGBD;
string curActivity;
map<string, string> data_act_map;
ifstream* file;
ifstream* file_RGBD;
bool mirrored;
// print error message
void errorMsg(string message, bool exitProgram) {
cout << "ERROR! " << message << endl;
printf("\tcurrentFrameNum = %d\n", currentFrameNum);
printf("\tcurrentFrameNum_RGBD = %d\n", currentFrameNum_RGBD);
if (exitProgram) {
exit(1);
}
}
void errorMsg(string message) {
errorMsg(message, true);
}
bool parseChk(bool chk, bool skeleton) {
if (!chk) {
if (skeleton) {
errorMsg("parsing error. (skeleton)", true);
} else {
errorMsg("parsing error. (RGBD) - IGNORE THIS ERROR!! (all random dataset will hit this error)", false);
}
return false;
}
return true;
}
// read skeleton data file
void prepareSkeletonData() {
curActivity = data_act_map[fileName];
if (!mirrored) {
fileName_skeleton = dataLocation + fileName + ".txt";
} else {
fileName_skeleton = dataLocation_mirrored + fileName + ".txt";
}
printf("\tOpening \"%s\" (%s)\n", (char*)fileName_skeleton.c_str(), (char*)curActivity.c_str());
file = new ifstream((char*)fileName_skeleton.c_str(), ifstream::in);
currentFrameNum = -99;
}
void closeSkeletonData() {
file->close();
printf("\tskeleton file closed\n");
}
// return true if data retrieving was successful
bool readNextLine_skeleton(double **data, double **pos_data, int **data_CONF, int *data_pos_CONF) {
string line;
bool file_ended = true;
if (getline(*file,line)) {
file_ended=false;
stringstream lineStream(line);
string element;
int jointCount=0;
int joint_dataCount = 0;
int pos_jointCount = 0;
int pos_joint_dataCount = 0;
parseChk(getline(lineStream, element, ','), true);
currentFrameNum = atoi((char*)element.c_str());
if (element.compare("END") == 0) {
file_ended = true;
return false;
}
while (getline(lineStream, element, ',')) {
double e = strtod((char*)element.c_str(), NULL);
if (jointCount < JOINT_NUM) {
data[jointCount][joint_dataCount] = e;
joint_dataCount++;
if (joint_dataCount == JOINT_DATA_ORI_NUM) {
parseChk(getline(lineStream, element, ','), true); // ori conf value
data_CONF[jointCount][0] = atoi((char*)element.c_str());
} else if (joint_dataCount >= JOINT_DATA_NUM) {
parseChk(getline(lineStream, element, ','), true); // pos conf value
data_CONF[jointCount][1] = atoi((char*)element.c_str());
jointCount++;
joint_dataCount = 0;
}
} else {
// pos only joints
if (pos_jointCount >= POS_JOINT_NUM) {
errorMsg("PARSING ERROR!!!!!");
}
pos_data[pos_jointCount][pos_joint_dataCount] = e;
pos_joint_dataCount++;
if (pos_joint_dataCount >= POS_JOINT_DATA_NUM) {
parseChk(getline(lineStream, element, ','), true); // pos conf value
data_pos_CONF[pos_jointCount] = atoi((char*)element.c_str());
pos_jointCount++;
pos_joint_dataCount = 0;
}
}
}
// check if there is more data in current frame..
if (getline(lineStream, element,',')) {
errorMsg("more data exist in skeleton data ..\n");
}
}
if (currentFrameNum == -99) {
errorMsg("file does not exist or empty!!");
}
return !file_ended;
}
// read RGBD data file
void prepareRGBDData() {
fileName_RGBD = dataLocation + fileName + "_rgbd.txt";
printf("\tOpening \"%s\" (%s)\n", (char*)fileName_RGBD.c_str(), (char*)curActivity.c_str());
file_RGBD = new ifstream((char*)fileName_RGBD.c_str(), ifstream::in);
currentFrameNum = -99;
}
void closeRGBDData() {
file_RGBD->close();
printf("\tRGBD file closed\n");
}
// return true if data retrieving was successful
bool readNextPNG(int ***data) {
stringstream ss;
ss << currentFrameNum;
fileName_RGBD = dataLocation + fileName + "/RGB_" + ss.str() +".png";
string fileName_Depth = dataLocation + fileName + "/Depth_" + ss.str() +".png";
if (currentFrameNum == 1) {
printf("\tOpening \"%s\" and so forth..\n",
(char*)fileName_RGBD.c_str());
printf("\tOpening \"%s\" and so forth..\n",
(char*)fileName_Depth.c_str());
}
// Load an image from file
cv::Mat rgbImage = cv::imread((char*)fileName_RGBD.c_str(),1);
cv::Mat colorArr[3];
cv::split(rgbImage, colorArr);
cv::Mat depthImage = cv::imread((char*)fileName_Depth.c_str(),-1);
if (rgbImage.data == NULL) {
printf("ERROR! Unable to open file %s.\n", (char*)fileName_RGBD.c_str());
exit(1);
}
if (depthImage.data == NULL) {
printf("ERROR! Unable to open file %s.\n", (char*)fileName_Depth.c_str());
exit(1);
}
for (int y=0; y<Y_RES; y++){
// opencv uses BGR order
uchar* Bptr = colorArr[0].ptr<uchar>(y);
uchar* Gptr = colorArr[1].ptr<uchar>(y);
uchar* Rptr = colorArr[2].ptr<uchar>(y);
ushort* IRptr = depthImage.ptr<ushort>(y);
for(int x=0;x<X_RES; x++){
// our data is stored in RGB order
data[x][y][0] = Rptr[x];
data[x][y][1] = Gptr[x];
data[x][y][2] = Bptr[x];
data[x][y][3] = IRptr[x];
}
}
return true;
}
// return true if data retrieving was successful
bool readNextLine_RGBD(int ***IMAGE) {
string line;
char* line_c;
bool file_ended = true;
if (getline(*file_RGBD,line)) {
file_ended = false;
line_c = (char*)line.c_str();
char* element = strtok(line_c, ",");
if (element == NULL || strcmp(element,"END") == 0) {
file_ended = true;
return false;
}
currentFrameNum_RGBD = atoi(element);
if (currentFrameNum != currentFrameNum_RGBD) {
printf("skeleton: %d rgbd: %d\n", currentFrameNum, currentFrameNum_RGBD);
errorMsg("FRAME NUMBER BETWEEN SKELETON AND RGBD DOES NOT MATCH!!!!!!!!! (READING RGBD)");
}
for (int y=0;y<Y_RES;y++) {
for (int x=0;x<X_RES;x++) {
for (int d = 0; d<RGBD_data; d++) {
element = strtok(NULL, ","); // passing NULL keeps tokenizing previous call
if (element == NULL) {
file_ended = true;
return false;
}
int e = atoi(element);
if (!mirrored) {
IMAGE[x][y][d] = e;
} else {
IMAGE[x][(Y_RES-1)-y][d] = e;
}
}
}
}
// check if there is more data in current frame..
element = strtok(NULL, ",");
if (element != NULL) {
printf("line_c = %s\n", line_c);
errorMsg("more data exist in RGBD data ..\n");
}
}
return !file_ended;
}
public:
// return true if data retrieving was successful
bool readNextFrame(double **data, double **pos_data, int **data_CONF, int *data_pos_CONF, int ***IMAGE) {
if (currentFrameNum % 100 == 0) {
printf("\t\t(progress..) frame num = %d\n", currentFrameNum);
}
bool status = readNextLine_skeleton(data,pos_data, data_CONF, data_pos_CONF);
if (!status) {
printf("\t\ttotal number of frames = %d\n", lastFrame);
return false;
}
bool status_RGBD;
if (!READ_FROM_PNG) {
status_RGBD = readNextLine_RGBD(IMAGE);
} else {
status_RGBD = readNextPNG(IMAGE);
}
if (status_RGBD) {
lastFrame = currentFrameNum;
} else {
printf("\t\ttotal number of frames = %d\n", lastFrame);
}
return status_RGBD;
}
readData(string dataLoc, string fileN, map<string, string> d_a_map, int i, bool mirrored, string dataLoc_mirrored) {
if (!mirrored) {
printf("%d. ", i);
} else {
printf("%d(M). ", i);
}
dataLocation = dataLoc;
dataLocation_mirrored = dataLoc_mirrored;
fileName = fileN;
data_act_map = d_a_map;
this->mirrored = mirrored;
prepareSkeletonData();
if (!READ_FROM_PNG) {
prepareRGBDData();
}
}
readData() {
}
~readData(){
closeSkeletonData();
if (!READ_FROM_PNG) {
closeRGBDData();
}
printf("\n");
}
};
继续其他文件,我也使用一些预定义的常量。 然后,我编写CMakeLists.txt以构建MakeFiles,如下所示:
cmake_minimum_required(VERSION 2.8)
project( FeatureExtractor )
find_package( OpenCV REQUIRED )
add_executable( FeatureExtractor main.cpp readData.cpp features.cpp featuresRGBD.cpp HOG.cpp HOGFeaturesOfBlock.cpp)
target_link_libraries( FeatureExtractor ${OpenCV_LIBS} )
由于我在某处阅读,他们说&#34; CMake自动处理依赖关系,因此不需要列出标题&#34;所以我没有在配置CMakeLists.txt中提到头文件(constaint.h)。
然后,当我运行命令来组合和构建Makefile
时,我遇到了这个错误make
Scanning dependencies of target FeatureExtractor
[ 16%] Building CXX object CMakeFiles/FeatureExtractor.dir/main.cpp.o
[ 33%] Building CXX object CMakeFiles/FeatureExtractor.dir/readData.cpp.o
/home/minhthanh/Downloads/Test/readData.cpp:11:5: error: ‘string’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:12:5: error: ‘string’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:13:5: error: ‘string’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:14:5: error: ‘string’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:15:5: error: ‘string’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:16:5: error: ‘string’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:17:5: error: ‘map’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:18:5: error: ‘ifstream’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:19:5: error: ‘ifstream’ does not name a type
/home/minhthanh/Downloads/Test/readData.cpp:24:19: error: ‘string’ has not been declared
/home/minhthanh/Downloads/Test/readData.cpp:34:19: error: ‘string’ has not been declared
/home/minhthanh/Downloads/Test/readData.cpp:287:21: error: expected ‘)’ before ‘dataLoc’
/home/minhthanh/Downloads/Test/readData.cpp:317:2: error: expected ‘}’ at end of input
/home/minhthanh/Downloads/Test/readData.cpp: In member function ‘void readData::errorMsg(int, bool)’:
/home/minhthanh/Downloads/Test/readData.cpp:25:9: error: ‘cout’ was not declared in this scope
/home/minhthanh/Downloads/Test/readData.cpp:25:41: error: ‘endl’ was not declared in this scope
/home/minhthanh/Downloads/Test/readData.cpp:26:59: error: ‘printf’ was not declared in this scope
/home/minhthanh/Downloads/Test/readData.cpp:30:19: error: ‘exit’ was not declared in this scope
/home/minhthanh/Downloads/Test/readData.cpp: In member function ‘bool readData::parseChk(bool, bool)’:
/home/minhthanh/Downloads/Test/readData.cpp:43:59: error: invalid conversion from ‘const char*’ to ‘int’ [-fpermissive]
/home/minhthanh/Downloads/Test/readData.cpp:24:10: error: initializing argument 1 of ‘void readData::errorMsg(int, bool)’ [-fpermissive]
/home/minhthanh/Downloads/Test/readData.cpp:45:119: error: invalid conversion from ‘const char*’ to ‘int’ [-fpermissive]
/home/minhthanh/Downloads/Test/readData.cpp:24:10: error: initializing argument 1 of ‘void readData::errorMsg(int, bool)’ [-fpermissive]
/home/minhthanh/Downloads/Test/readData.cpp: In member function ‘void readData::prepareSkeletonData()’:
/home/minhthanh/Downloads/Test/readData.cpp:54:9: error: ‘curActivity’ was not declared in this scope
/home/minhthanh/Downloads/Test/readData.cpp:54:23: error: ‘data_act_map’ was not declared in this scope
虽然这是一个很长的列表,但我想问题是我在main.cpp中包含的一些库和文件在下面的文件中无法识别(readData.cpp,features.cpp,...)。
如何配置或修改以下我包含的文件可以识别那些预定义的文件和库?
答案 0 :(得分:2)
问题是CMake单独编译readData.cpp,并且没有包含<string>
和using namespace std;
,因此它不会编译。
当你在main.cpp中包含readData.cpp,features.cpp,featuresRGBD.cpp等时(你可以看到编译)然后你不需要在CMake中设置它们进行单独的编译,即从中删除它们CMake add_executable(...
行。
但一般情况下通常以另一种方式执行,即分别编译每个* .cpp,不包括在main.cpp中,并且每个#include ...
只包含他们需要的东西。