Call functions in other files in C++ and OpenCV - c++

I know this might be a possible duplicate but I have actually gone through several posts on SO to try and solve this problem
I have the following code in OpenCV and C++
test.cpp
#include "opencv2/core/core_c.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"
#include <stdio.h>
#include <iostream>
#include <vector>
#include <math.h>
#include <string.h>
#include "draw_shapes.h"
using namespace cv;
using namespace std;
int main(){
Mat normal = imread("/INPUT 2.jpg");
Mat gray;
cvtColor(normal, gray,CV_RGB2GRAY);
Mat binary = gray > 128;
Point start = cv::Point(5.0,5.0);
Point end = cv::Point(200.0,200.0);
draw_line(binary, start, end, 0, 255, 0);
imshow("Draw_Line", binary);
while(waitKey(0)!=27){
;
}
return 0;
}
draw_shapes.cpp
#include "opencv2/core/core_c.h"
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"
#include <stdio.h>
#include <iostream>
#include <vector>
#include <math.h>
#include <string.h>
#include "draw_shapes.h"
void draw_line(cv::Mat img, cv::Point start, cv::Point end, int B, int G, int R){
int thickness = 2;
int lineType = 8;
line(img,start,end,Scalar(B,G,R),thickness,lineType);
}
void draw_rectangle(cv::Mat img, cv::Point p1, cv::Point p2, int B, int G, int R){
int thickness = 2;
int lineType = 8;
rectangle(img, p1, p2, Scalar(B,G,R),thickness, lineType);
}
draw_shapes.h
#ifndef DRAWSHAPES_H
#define DRAWSHAPES_H
void draw_line(cv::Mat, cv::Point, cv::Point, int, int, int);
void draw_rectangle(cv::Mat, cv::Point, cv::Point, int, int, int);
#endif
compile_opencv.sh
#!/bin/bash
echo "compiling $1"
if [[ $1 == *.c ]]
then
gcc -ggdb `pkg-config --cflags opencv` -o `basename $1 .c` $1 `pkg-config --libs opencv`;
elif [[ $1 == *.cpp ]]
then
g++ -ggdb `pkg-config --cflags opencv` -o `basename $1 .cpp` $1 `pkg-config --libs opencv`;
else
echo "Please compile only .c or .cpp files"
fi
echo "Output file => ${1%.*}"
./${1%.*}
I have gone through almost every post on StackOverflow related to header files and including functions from external CPP files and this is what I got.
Now, when I compile, I get
undefined reference to 'draw_line(cv::Mat, cv::Point_<int>, cv::Point_<int>, int, int, int)'
I am taking a wild guess and saying that this might be because I am not compiling draw_shapes.cpp separately, but I tried a simple int add(int x, int y) in a C file and it worked directly. Where am I going wrong here?

(Based on Ben's comment)
This command should work:
g++ -ggdb `pkg-config --cflags opencv` test.cpp draw_shapes.cpp `pkg-config --libs opencv`
Note the backquotes around "pkg-config --cflags opencv" and "pkg-config --libs opencv". Reqular quotes ('), won't work - you really need backquotes here (`). The backquote key is just below the "Esc" key on most keyboards. Or just copy-paste them from your script.

Just as #Ben mentioned, You need to compile the draw_shapes.cpp file. The twist is, if You want to compile Your files separately You need to compile them as objects with -c switch, and then link them together. Further explanation in Your second thread

Related

Linking C++ object files embedded with Python

I have a C++ constructor file (formatting_SQ.cpp) of a header file formatting_SQ.h which I want to link to other constructor files of header files (neat.cpp nnode.cpp link.cpp etc...-> neat.h nnode.h link.h) in order to have formatting_SQ.o.
Then, I want to link my main.cpp file with this formatting_SQ.o file. The problem is: formatting_SQ is embedded with python, and as far as my understanding goes, C++ embedded with Python needs the compiling flag -lpython3.6m on Linux: such flag requires a reference to a main() function, which I don't have in formatting_SQ.cpp because it's a constructor file meant to be an object file.
So I first tried to create object files for each constructor file and then link everything together at once:
g++ -c -O3 -Wall -fPIC -fopenmp -std=c++14 -lstdc++ `python3 -m pybind11 --includes` *.cpp
g++ -o the_executable neat.o nnode.o link.o trait.o gene.o network.o innovation.o organism.o species.o genome.o population.o formatting_SQ.o main.o -fopenmp -O3 -Wall -fPIC `python3 -m pybind11 --includes` -lpython3.6m
Here comes my first question: Are these command right or is there eventually a compilation flag missing ? This gives me a segmentation fault as I try to execute ./the_executable.
Then, I tried to compile formatting_SQ.cpp independently with all other constructor files, but as expected, this doesn't work because there is no reference to main in formatting_SQ.cpp.
g++ -o temp_formatting neat.o nnode.o link.o trait.o gene.o network.o innovation.o organism.o species.o genome.o population.o formatting_SQ.o -fopenmp -O3 -Wall -fPIC `python3 -m pybind11 --includes` -lpython3.6m
So here comes my second question: how could I create a python embedded object file linking formatting_SQ.cpp with all other constructor files without having this undefined reference to main error ?
formatting_SQ.cpp
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include <Python.h>
#include <omp.h>
#include "formatting_SQ.h"
#include "neat.h"
#include "network.h"
#include "link.h"
#include "nnode.h"
#include "trait.h"
#include "gene.h"
#include "genome.h"
#include "innovation.h"
#include "organism.h"
#include "species.h"
#include "population.h"
namespace py = pybind11;
py::module compile_data = py::module::import("initialize");
main.cpp
#include <pybind11/embed.h>
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include <Python.h>
#include "formatting_SQ.h"
#include <omp.h>
namespace py = pybind11;
int main(int argc, char** argv){
....
So after some long hours of research I can conclude that the compilation method is correct but BE EXTREMELY CAREFULL with where you declare your import modules from python, because this was the problem for me
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include <Python.h>
#include <omp.h>
#include "formatting_SQ.h"
#include "neat.h"
#include "network.h"
#include "link.h"
#include "nnode.h"
#include "trait.h"
#include "gene.h"
#include "genome.h"
#include "innovation.h"
#include "organism.h"
#include "species.h"
#include "population.h"
namespace py = pybind11;
py::module compile_data = py::module::import("initialize"); DON'T DO THIS its wrong !!!
You must declare your modules locally otherwise there be some conflicts in the namespace as the same module may be imported more than once and this causes the segmentation fault.

opencv project program wont halt

I am trying to begin an opencv project. I have installed all of the dependancies etc.
I am running the following to compile the program
g++ $(pkg-config --cflags --libs opencv4) -std=c++11 main.cpp -o yourFileProgram
inside of main.cpp:
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
cv::RNG rng(12345);
int main(int argc, const char * argv[]) {
return 0;
}
The code compiles, however when I run ./yourFileProgram the exec never terminates.

‘CvLoadImage’ was not declared in this scope

I try to use OpenCV C Api in my code. I have opencv and opencv2 folder under usr/include. I can use OpenCV C++ Api. C++ code and compilation&linking commands are below :
#include <iostream>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/opencv.hpp"
using namespace cv;
int main()
{
Mat im = imread("Sobel.jpg");
return 0;
}
Compile : g++ -c main.cpp
Linking : g++ -o exe main.opkg-config --libs opencv`
Now I want to use OpenCV C-Api. My code is here :
#include <iostream>
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/opencv.hpp"
using namespace cv;
int main()
{
IplImage* pImg = CvLoadImage("Sobel.jpg");
if(pImg == NULL)
return -1;
// ... big bloat to do the same operations with IplImage
CvShowImage("Image", pImg);
cvWaitKey();
CvReleaseImage(&pImg); // Do not forget to release memory.
// end code here
return 0;
}
When I compile g++ -c main.cpp, the compiler says that ‘CvLoadImage’ was not declared in this scope
A simple spelling mistake, the function prototype is
IplImage* cvLoadImage( const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR );

Not possible to compile. Headers files.Enclosed own objects definition

Here I am with a similar question as the last time, and for which I could not find any answer.
Note that I consider important: Normally I compile my programs in opencv with the next command:
g++ -o def program.cpp `pkg-config --cflags opencv` `pkg-config --libs opencv`
This line will create an executable whose name will be def and that I will be able to use.
I am working in a project, and as it was getting bigger, I had to define some objects, just to make everything easier and possible to handle. I create one object from the files: homogra.cpp and homogra.h the comand I used for it was:
g++ -c homogra.cpp `pkg-config --cflags opencv` `pkg-config --libs opencv`
Then, I wrote in my program.cpp the line #include "homogra.h"
And I compile like:
g++ -o def program.cpp homogra.o `pkg-config --cflags opencv` `pkg-config --libs opencv`
Until now everything is working fine.
Then I create a second object(with the same compilation line as for homogra, but this time with segmentator.cpp and segmentator.h), i wrote the line #include "segmentator.h",(in program.cpp) and I compile like:
g++ -o def program.cpp .o segmentator.o `pkg-config --cflags opencv` `pkg-config --libs opencv`
Now it is not working, and it is not recognising segmentator. I checked already if segmentator was working and everything works fine if homogra is the only include in the program.cpp.
I notice something strange. If I change the lines and I write before,in the #include lines, #include "segmentator.h" and then #include "homogra.h", then the compiler, with the same line for compiling :
g++ -o def program.cpp homogra.o segmentator.o `pkg-config --cflags opencv` `pkg-config --libs opencv`
is only recognising this time segmentator and not homogra. It is maybe a little difficult to understand, I tried to explained it as better as possible.
Any help!?
Many thanks in advance.
Here is homogra.h:
using namespace cv;
using namespace std;
#ifndef _NAMES_H
#define _NAMES_H
class homogra {
public:
Mat matCalculation( Mat img, Mat img2);
void printMatrix(Mat matrix);
};
#endif
In homogra.cpp I have all the tipical includes and homogra.h:
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <sstream>
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "homogra.h"
And then the functions explained.
Object 2 is segmentator.h
using namespace cv;
using namespace std;
#ifndef _NAMES_H
#define _NAMES_H
class segmentator {
public:
void search(Mat img,vector<std::vector<cv::Point> >& contours);
void similar(vector<std::vector<cv::Point> >& contours,vector<std::vector<cv::Point> >& contours2,vector<int>& idx);
vector<Mat> separate(Mat img,Mat img2,vector<std::vector<cv::Point> >& contours,vector<std::vector<cv::Point> >& contours2,vector<int> idx);
};
#endif
And in segmentator.cpp I have again all the same includes, except homogra.h and instead of this one I have segmentator.h.
Program.cpp is image_reg.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "homogra.h"
#include "segmentator.h"
using namespace cv;
using namespace std;
int main(int argc, char ** argv )
{ //Here is the code where I try to invoque two instances of homogra and segmentator.
}
If I let homogra.h as the first to be read in the includes list of image_reg.cpp then only homogra.h is recognised, if I let at the first position segmentator, then only segmentator.h instances would be created and homogra. h would not be recognised.
Thanks
Your include header guards are wrong. They should be unique, using the name of the source file, rather than just _NAMES_H.
So in homogra.h you should have this:
#ifndef HOMOGRA_H
#define HOMOGRA_H
...
#endif
...and in segmentator.h, you should have this
#ifndef SEGMENTATOR_H
#define SEGMENTATOR_H
...
#endif
Also, it's really bad practice to have a using namespace xxx; in a header file. You make it very difficult for your headers to coexist with others.
As Jonathan Wakely points out, beginning symbols with underscores is not a great idea, either.

Boost library simple compilation with tuples

Can anyone tell me why this works (compiles and runs)
#include <iostream>
#include <boost/numeric/ublas/matrix.hpp>
//#include <boost/tuple.hpp>
//#include <boost/tuple_comparison.hpp>
//#include <boost/tuple_io.hpp>
using namespace boost;
int main ( )
{
// tuple<int, char, float> t(2, 'a', 0.9);
// std::cout << t << std::endl;
boost::numeric::ublas::matrix<double> m1;
return 0;
}
but when I uncomment the lines related to tuple, it says
boost_tuple.cpp:3:27: fatal error: boost/tuple.hpp: No such file or directory
compilation terminated.
I use the following to compile in both cases:
g++ -Wall -c -I/usr/include/boost boost_tuple.cpp
And I also checked that /usr/include/boost/tuple.hpp exists
If you want to include it as:
#include <boost/tuple.hpp>
lose the boost part in -I/usr/include/boost. Right now this is being evaluated as /usr/include/boost/boost/tuple.hpp, which is probably your problem.
EDIT:
Make sure tuple.hpp is installed where you said it is, because on my system it's located in another folder: /usr/include/boost/tuple/tuple.hpp
Which means that I need to include the file as #include <boost/tuple/tuple.hpp> and compile it as:
g++ tuple.cpp -o tuple -I /usr/include/boost
tuple.cpp:
#include <iostream>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/tuple/tuple.hpp>
using namespace boost;
int main ( )
{
tuple<int, char, float> t(2, 'a', 0.9);
boost::numeric::ublas::matrix<double> m1;
return 0;
}