Undefined reference to cv::Mat::Mat() - c++

I made a simple c++ code that reads the webcam image and display it. However, when I compile, I get the error - 'Undefined reference to cv::Mat::Mat()'. I don't know why it shows two Mat's. Here is my code:
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include <stdlib.h>
int main() {
cv::VideoCapture cap(0);
if (!cap.isOpened){
std::cout << "Error opening camera" << std::endl;
}
cv::Mat img;
while(1){
cap >> img;
cv::imshow("output", img);
cv::waitKey(1);
}
}
This is how I compile it
g++ example.cpp `pkg-config --libs opencv4`
I can't figure out why the error shows up. Any help is appreciated!

This works on my Linux:
g++ main.cpp -I/usr/include/opencv4/ -lopencv_core -lopencv_videoio -lopencv_highgui
While this is not portable, (using cmake would do the trick, but you'd need to learn cmake first), I'll give you a hint how you can discover this yourself.
Whenever you see an error like Undefined reference to cv::Mat::Mat(), go to the documentation at https://docs.opencv.org/ , chose the newest version (here: https://docs.opencv.org/4.5.5/ ), enter, in the "search" window, the name of a class/function the linker cannot find (here: Mat), read the header that defines it (here: #include<opencv2/core/mat.hpp>), then the missing library will have the name libopencv_core.* or libopencv_mat.*. Find whichever is in your machine (e.g. inside /user/lib) and link it, omitting the extension and the beginning lib in the name. In my case the library location, with the full path, is /usr/lib/libopencv_core.so, so I link it with -lopencv_core. Then you need to find the remaining libs in the same way.
Learn how to automatize this, e.g. via a Makefile, CMakeLists.txt or just a simple bash script.

Related

Compiling OpenCV Based Script With G++

I want to begin writing saying that I know that this topic has been talked about multiple times. I can see several posts with similar titles as I'm typing this now. The reason that I'm asking this question once again is because I've tried what those posts stay, and it still won't work. I've copied a simple script that upscales an image using opencv in C++ to begin the learning journey and to make a script that I hope to use in the future very often, maybe even share on GitHub. With that being said, here's more detail about my issue.
In my IDE, Visual Studio Code, my include path has been set to "/opt/homebrew/Cellar/opencv/4.6.0/include/opencv4/".
I've tried using the -I arguments, -l arguments, whatever this is: "pkg-config --cflags --libs opencv4", but none of that worked.
The only time that I could get it to work is using the following command, but even then, g++ returned: fatal error: too many errors emitted, stopping now [-ferror-limit=] 41 warnings and 20 errors generated.
Here's the program that I have:
#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main() {
Mat frame = imread("/Users/karsoneskind/Desktop/Programming/C++/ibootimformer/tests/image.jpg");
namedWindow("Output", 0);
namedWindow("Input", 0);
Mat output;
resize(frame, output, Size(1000, 200), 0, 0);
imshow("Output", output);
imshow("Input", frame);
waitKey(0);
}
Edit: This is the command in terminal I used to try to compile the code:
g++ test.cpp -o test pkg-config --cflags --libs opencv4

Including external libraries in CodeRunner 2 app?

I've always used Xcode to compile OpenCV based code in c++. The procedure in Xcode was quite simple, I just had to mention the paths and add the necessary lib files to the project. Theres this app called CodeRunner 2 for macOS. Theres no proper documentation on how to include external libraries to compile code in this app. Is it possible to link OpenCV headers and compile them in CodeRunner ? If yes, could someone post the steps?
You can run OpenCV in CodeRunner by setting up a new language. Go to Preferences -> Languages, right-click C++, and select Duplicate. Name the new language "C++ OpenCV". On the right side of the preferences window, click Settings then the Edit Script button. Look for this line (or something similar):
xcrun clang++ -x c++ -lc++ -o "$out" "${files[#]}" "${#:1}"
Add the clang++ command line parameters for OpenCV after "$out". Here's my version:
xcrun clang++ -x c++ -lc++ -o "$out" -I/usr/local/opt/opencv3/include -L/usr/local/opt/opencv3/lib -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs -lopencv_videoio -lopencv_calib3d "${files[#]}" "${#:1}"
Modify the -I and -L parameters to match your OpenCV install path. On this machine I used Homebrew to install OpenCV so it was installed in /usr/local/opt. On other machines I've compiled from source so OpenCV is installed in /usr/local/lib.
Modify the -l parameters to include the libraries you typically use.
After saving the compile script, go back to Preferences -> Languages and select the Templates button. You can set up a template for OpenCV programs. Here's mine:
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
using namespace std;
int main(int argc, char *argv[]) {
cv::Mat image;
// read an image
if (argc < 2)
image = cv::imread("img.jpg");
else
image = cv::imread(argv[1]);
if (!image.data) {
std::cout << "Image file not found\n";
return 1;
}
// create image window named "asdfasdf"
cv::namedWindow("asdfasdf");
// show the image on window
cv::imshow("asdfasdf", image);
// wait for key
cv::waitKey(0);
return 0;
}
The previous reply by SSteve is great and also helps me sort out linking Boost library in CodeRunner.
Because the solution in the previous reply is specific to OpenCV library, a carelessly adding to the clang++ command line for external libraries in general might just generate massive building errors, which was the case when I tried to link Boost library.
Here, I want to clarify the unclear bit in SSteve's reply so everyone knows how and where to modify the command line before compiling their code with external library in Mac OS system.
I will use my case to explain, but in some point I will inform you of the tricky bits in CodeRunner setting or general command line typing.
I use macport to install the Boost library by
sudo port install boost
header file is located at /opt/local/include
library is located at /opt/local/lib/
If you cannot find the specific sub-library in Boost, open your terminal and type
cd /opt/local/lib/
find . -iname "*boost*"
and you should see all sub-libraries of Boost ( static library ends with .a and dynamic library ends with .dylib ) as below.
Before you start to modify the original command line ( supporting c++ 14 version ) such as
xcrun clang++ -x c++ -std=c++14 -stdlib=libc++ -lc++ -o "$out" "${files[#]}" "${#:1}" ${CR_DEBUGGING:+-g}
you need to know the directory of header file is after -I and the directory of Boost library is after -L, like
-I /opt/local/include/
-L /opt/local/lib/
In order to use a compiled static or dynamic sub-library in Boost ( see figure above ), you have to include it specifically after -L /opt/local/lib/. However, simply copying the library name without file extension either .a or .dylib would never let CodeRunner find the library you expect to run !!!
The detail is explained here and I just quota the important bit below
clang -dynamiclib -o libtest.dylib file1.o file2.o -L/some/library/path -lname_of_library_without_lib_prefix
To run such an example code in Boost Quickstart Document
#include <boost/regex.hpp>
#include <iostream>
#include <string>
int main()
{
std::string line;
boost::regex pat( "^Subject: (Re: |Aw: )*(.*)" );
while (std::cin)
{
std::getline(std::cin, line);
boost::smatch matches;
if (boost::regex_match(line, matches, pat))
std::cout << matches[2] << std::endl;
}
}
the way to include <boost/regex.hpp> now is by
xcrun clang++ -x c++ -std=c++14 -stdlib=libc++ -lc++ -o "$out" -I /opt/local/include/ -L /opt/local/lib -lboost_regex-mt "${files[#]}" "${#:1}" ${CR_DEBUGGING:+-g}
By using this command line, you should be able to compile the example code with Boost library.
Just remember to replace the prefix -lib with -l and exclude the file extension in the command line.
At last, there are some alternative solution to include the external library by using Xcode, which is in here

OpenCV: Undefined reference to xcb_poll_for_reply

As of late I have been getting the following error whenever I try to compile any program that uses the open cv libraries, I use g++ to compile:
g++ Example.cpp -o Ex `pkg-config opencv --cflags --libs`
No matter the content of the file (I have checked with programs that worked a couple of weeks ago) I always get the following error:
/usr/lib64/libX11.so.6: undefined reference to `xcb_poll_for_reply64'
/usr/lib64/libX11.so.6: undefined reference to `xcb_wait_for_reply64'
Do you have any idea of what might be the cause? (and how to fix it)
An example program that fails to compile:
#include "path/opencv2/highgui/highgui.hpp"
#include "path/opencv/highgui.h"
using namespace cv;
int main (int argc, char * argv[])
{
Mat image = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE) ;
return 0;
}
Add -lxcb to your command line (this will instruct the linker linking w/ the xcb library). Please make sure the 64b version of xcb is in the linker path (you can always put it explicitly via the -L switch)
The error was caused by some changes done to the libX11.so.6, talked with the FE machines support and they fixed it.

undefined reference to glfwSetErrorCallback

I'm trying to use the GLFW library, but am having difficulty with compiling a simple program. I went to the GLFW website and download the latest release, then using "How to build & install GLFW 3 and use it in a Linux project" I built and installed it.
Here's my code:
#include <GLFW/glfw3.h>
#include <iostream>
using std::cout;
using std::endl;
void GLFW_error(int error, const char* description)
{
fputs(description, stderr);
}
void run()
{
cout << "pooch" << endl;
}
int main()
{
glfwSetErrorCallback(GLFW_error);
if (!glfwInit()) exit(EXIT_FAILURE);
run();
glfwTerminate();
return 0;
}
Using the command line:
bulletbill22#ROBOTRON ~/Desktop $ g++ -std=c++11 -lglfw source.cpp
yields
source.cpp:function main: error: undefined reference to 'glfwSetErrorCallback'
glfwSetErrorCallback is taken from their tutorial for "Setting an error callback".
Inclusion of -glfw3 results in /usr/bin/ld: error: cannot find -lglfw3
Even though everything seemed to be installed correctly, I suspect the problem may lie somewhere with the installation of the GLFW library because I'm not used to CMake and don't entirely understand how it works. I'm frustrated because the answer must be simple, but I'm not sure which keywords are really relevant when googling the problem; mostly the results are people who were incorrectly compiling with CMake, which I'm not compiling with in this case.
It seems that the directories for the glfw3.h header and libglfw3.so (and/or libglfw3.a) library are not in the default path.
You can check with by adding the -v option to the g++ options. Locate the directory where the glfw3.h header is found - call this $GLFW_INCDIR - it typically ends with .../GLFW. Locate the directory where the library is found - call this $GLFW_LIBDIR. Try:
g++ -std=c++11 -I$GLFW_INCDIR source.cpp -o pooch -L$GLFW_LIBDIR -lglfw3
If all the library dependencies are satisfied, this hopefully results in a program called pooch.
One other thing: GLFW3 is a C library, and the callback function arguments are expected to be C functions. So your callback should have 'C' linkage, i.e.,
extern "C" void GLFW_error(int error, const char* description) ...
Also, if you're having trouble with cmake, you may have ccmake installed. Try ccmake . in the top-level directory of the GLFW3 package for 'interactive' configuration.

I can compile with SDL1.2 but not with SDL2 (C::B)

I've been learning SDL for a little time, and now I've decided to try out SDL2, mainly to try its hardware acceleration. But the problem is, I can't compile it at all, while the same code compiled correctly with SDL1.2.
The sample code is:
#include "SDL/SDL.h"
int main( int argc, char *args[] )
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Quit();
return 0;
}
With the original linker settings: -lmingw32 -lSDLmain -lSDL
everything compiles.
But as soon as I change #include "SDL/SDL.h" to #include "SDL2/SDL.h"
and change linker settings to
-lmingw32 -lSDL2main -lSDL2
I get the errors:
obj\Debug\main.o||In function `SDL_main':|
main.cpp|5|undefined reference to `SDL_Init'|
main.cpp|8|undefined reference to `SDL_Quit'|
libmingw32.a(main.o):main.c:(.text.startup+0xa7)||undefined reference to `WinMain#16'|
I've got SDL1.2 installed in C:/SDL-1.2.15 and SDL2 installed in C:/SDL2
In search directories, I added both SDL1.2 and SDL2 Include and Lib folders.
I'm not sure if this will work, but if you are using the "x86_64-w64-mingw32" folder, try using the other one (the one with i686) this helped me. I was having the EXACT same problem as you, and using literally, to the line, the same test code as you. I hope this helps.