This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Cannot get OpenCV to compile because of undefined references?
(8 answers)
Closed 12 months ago.
I'm trying to compile a c++ file into a shared library (extension .so) and it's ok, I can generate the shared library perfectly, the problem comes when I try to use the shared library through Java with JNI, it gives me "undefined symbol : _ZN2cv3MatC1Ev" error.
OBSERVATIONS: I'm using g++ to compile. To run the Java class I'm using the oracle-jdk-8.
Compile from c++ to .so file with g++:
g++ -c -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux ../main.cpp -I./ -I/usr/local/include/opencv4/opencv2 -L/usr/local/lib/ -I/usr/local/include/opencv4 -lopencv_objdetect -lopencv_features2d -lopencv_imgproc -lopencv_highgui -lopencv_core -lopencv_videoio -lopencv_calib3d -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_highgui -lopencv_imgproc -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_video -lopencv_imgcodecs -I./../ -I/usr/local/include/opencv4/opencv2/core -fPIC -o libfpp.o
g++ -shared -I/usr/lib/jvm/java-8-openjdk-amd64/include -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux -I./ -I/usr/local/include/opencv4/opencv2 -L/usr/local/lib/ -I/usr/local/include/opencv4 -lopencv_objdetect -lopencv_features2d -lopencv_imgproc -lopencv_highgui -lopencv_core -lopencv_videoio -lopencv_calib3d -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_highgui -lopencv_imgproc -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_video -lopencv_imgcodecs -I./../ -I/usr/local/include/opencv4/opencv2/core -fPIC -o fpp.so libfpp.o -lc
My c++ file and header:
main.cpp
#include <iostream>
#include <jni.h>
#include <Main.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <string>
#include <vector>
#define PIC_PATH "/home/isomeister/cap2.jpg"
using namespace std;
using namespace cv;
//VideoCapture cap(0);
vector<Point> biggerContour;
vector<double> barCodeXPos;
int t1 = 204, t2 = 255, t3 = 0;
/**
* #brief save the gived frame in a file.
*
* #param video The frame in format of cv::Mat.
* #param resolution The resolution that the picture must be saved.
*/
void takePicture(Mat video, Size resolution) {
Mat dst;
resize(video, dst, resolution);
//imwrite(PIC_PATH, dst);
}
void getCountours(Mat img, Mat source) {
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(img, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
//drawContours(source, contours, -1, Scalar(255, 0, 255), 2);
int biggerArea = 0;
for (int i = 0; i < contours.size(); i++) {
//cout << "\nX " << boundingRect(contours[i]).x << "Y " << boundingRect(contours[i]).y << "W ", boundingRect(contours[i]).width, "H ", boundingRect(contours[i]).height;
//cout << "| Area: " << boundingRect(contours[i]).area() << "\n";
if (boundingRect(contours[i]).y > 40 || boundingRect(contours[i]).x > 155) {
if (boundingRect(contours[i]).y < 10) {
continue;
}
continue;
}
int area = contourArea(contours[i]);
barCodeXPos.push_back(boundingRect(contours[i]).x);
if (area > biggerArea) {
biggerArea = area;
biggerContour = contours[i];
cout << "\nX " << boundingRect(biggerContour).x << " Y " << boundingRect(biggerContour).y << " W ", boundingRect(biggerContour).width, " H ", boundingRect(biggerContour).height;
cout << "| Area: " << boundingRect(biggerContour).area() << "\n";
continue;
}
/*
circle(res, Point(20, 17), 10, Scalar(173, 24, 11), FILLED);
circle(res, Point(81, 31), 10, Scalar(250, 228, 85), FILLED);
circle(res, Point(145, 30), 10, Scalar(35, 233, 250), FILLED);
*/
}
}
int getPos() {
sort(barCodeXPos.begin(), barCodeXPos.end());
for (int j = 0; j < barCodeXPos.size(); j++) {
cout << " Barcodex Pos: " << barCodeXPos[j] << "\n";
if (boundingRect(biggerContour).x == barCodeXPos[j]) {
cout << "Game element in the: ";
if (j == 0) {
cout << "left \n";
return 0;
} else if (j == 1) {
cout << "right \n";
return 1;
} else if (j == 2) {
cout << "center \n";
return 2;
} else {
return -1;
}
}
}
return -2;
}
/**
* #brief
*
* #param path
* #param redSide
*/
void recognize(Mat path, bool redSide) {
Mat res, gray, tresh;
resize(path, res, Size(200, 200));
cvtColor(res, gray, COLOR_BGR2GRAY);
threshold(gray, gray, t1, t2, t3);
getCountours(gray, res);
cout << "AREA BIG CONTOUR: " << boundingRect(biggerContour).area() << "\n";
circle(res, Point(boundingRect(biggerContour).x, boundingRect(biggerContour).y), 10, Scalar(255, 0, 255), FILLED);
//drawContours(res, biggerContour, -1, Scalar(255, 0, 255), 2);
//imshow("resized", res);
//imshow("marked", gray);
//waitKey(0);
}
/*int main(int, char **) {
cout << "Code initialized (C++)!";
return 0;
}*/
JNIEXPORT jint JNICALL Java_Main_fpp
(JNIEnv *, jobject) {
Mat source;
//cap.read(source);
//cout << "Capturing image...";
//takePicture(source, Size(150, 200));
cout << "Recognizing image...";
recognize(imread(PIC_PATH), false);
return getPos();
}
void say_hello(){
std::cout << "Hello, from ffp!\n";
}
Main.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Main */
#ifndef _Included_Main
#define _Included_Main
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Main
* Method: fpp
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_Main_fpp
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Java class
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
static {
System.loadLibrary("fpp");
}
private native int fpp();
public static void main(String[] args) {
System.out.println(System.getProperty("java.library.path"));
try {
System.out.println("java test");
int junk = new Main().fpp();
System.out.println("C exit: " + junk);
} catch (Exception ex) {
System.out.println(ex);
}
}
}
This is my dir tree (root dir is untitled)
This is the content of CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0)
project(untitled)
set(CMAKE_CXX_STANDARD 11)
find_package (OpenCV 4.5.2 REQUIRED)
include_directories ("/usr/local/include/opencv4/")
add_executable(untitled main.cpp)
This is my code in main.cpp:
#include <iostream>
#include <string>
#include <sstream>
#include <opencv4/opencv2/core.hpp>
#include <opencv4/opencv2/highgui.hpp>
using namespace cv;
using namespace std;
int main(int argc, const char** argv) {
Mat color = imread("./lenna.png");
Mat gray = imread("./lenna.png", 0);
imwrite("./lennaGray.png", gray);
int myRow = color.cols - 1;
int myCol = color.rows - 1;
Vec3b pixel = color.at<Vec3b>(myRow, myCol);
cout << "Pixel value (B, G, R): (" << (int)pixel[0] << ", " << (int)pixel[1] << ", " << (int)pixel[2] << ")" << endl;
imshow("Lenna BGR", color);
imshow("Lenna Gray", gray);
waitKey(0);
return 0;
}
This is the entire error when I ran make command:
But if I ran my code in terminal by this command:
g++ main.cpp -o main -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_imgcodecs -I/usr/local/include/opencv4 && ./main
then it worked.
I don't know what happened, I just learned OpenCV and I am using Ubuntu 20.04 and OpenCV-4.5.2.
I'm trying to open a video file in Opencv C++, but it doesn't work in a weird way.
I'm on Fedora, and opencv is installed through dnf's opencv-devel package.
Here is the test code I'm using :
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/videoio/videoio.hpp>
int main(int argc, char *argv[])
{
std::string imagePath = "/home/me/picture.png";
cv::Mat image = cv::imread(imagePath);
std::cout << image << std::endl;
std::string videoPath = "/home/me/video.mp4";
cv::VideoCapture cap{ videoPath };
if(!cap.isOpened())
{
std::cout << "Error while opening video" << std::endl;
return -1;
}
cv::Mat startFrame;
cap >> startFrame;
std::cout << startFrame;
cap.release();
return 0;
}
Then, I Compile it with the libraries:
g++ -c -Wall -Wno-unknown-pragmas -I/usr/include/opencv4/ -o dist/obj/main.o src/main.cpp
g++ -lopencv_core -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lopencv_videoio dist/obj/main.o -o dist/bin/main
And when I run it, the image is read fine, but the video shows an error.
However, when I run it as sudo, the video reads just fine. I searched around a lot and couldn't find someone with a similar problem, so I'm posting this here.
Also, the python version works fine, so it shouldn'ttm be a codec problem.
I am compiling an example for OpenCV with the following code:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
if( argc != 2)
{
cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;
return -1;
}
Mat image;
image = imread(argv[1], CV_LOAD_IMAGE_COLOR); // Read the file
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
namedWindow( "Display window", WINDOW_AUTOSIZE );// Create a window for display.
imshow( "Display window", image ); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}
The compilation code is:
g++ -I/usr/local/include/opencv2 `pkg-config --cflags --libs opencv` -L /usr/local/share/OpenCV/3rdparty/lib/ opencv.cpp -o opencv -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_features2d -lopencv_imgcodecs
If I omit one of the libraries I add additionally, I get linking errors. When trying to run the program, I get an"Invalid machine code" error. How can that be solved?
I'm developing a project using opencv3.0 with extra module found in opencv_contrib github. Im using Xcode 7.0, Yosemite 10.10.
I have done the setting in Xcode
Header Search path :
/Users/kimloonghew/Documents/opencv/opencv-3.0.0/build/include /usr/local/Cellar/libiomp/20150401/include/libiomp/omp.h /usr/local/include
Library Search path :
/Users/kimloonghew/Documents/opencv/opencv-3.0.0/build/lib /usr/local/lib
Other Linker Flag : -lopencv_calib3d -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_shape -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videoio -lopencv_videostab -lopencv_nonfree -lopencv_ml -lopencv_xfeatures2d
Here the code below:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <dirent.h>
#include <string>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/ml/ml.hpp>
using namespace std;
using namespace cv;
int main(int argc, const char * argv[]) {
int minHessin = 400;
string dir = "/Users/DYKLhew/Documents/Food_proj/MIT/foodcamimages/TRAIN", filepath;
DIR *dp;
struct dirent *dirp;
struct stat filestat;
dp = opendir(dir.c_str());
SurfFeatureDetector detector(minHessin);
//Ptr<xfeatures2d::SURF> detector = xfeatures2d::SURF::create(minHessin);
vector<KeyPoint> keypoints, keypoints_scene;
Mat descriptors_object, descriptor_scene;
Mat img;
cout << "------- build vocabulary ---------\n";
cout << "extract descriptors.."<<endl;
int count = 0;
while (count++ < 15 && (dirp = readdir(dp))) {
filepath = dir + "/" + dirp->d_name;
if(stat( filepath.c_str(), &filestat )) continue;
if(S_ISDIR(filestat.st_mode)) continue;
img = imread(filepath);
detector.detect(img, keypoints);
cout << ".";
}
cout << endl;
closedir(dp);
cout << "Total descriptors : " << count << endl;
//BOWKMeansTrainer bowtrainer(150);
return 0;
}
When I run the file, it BUILD fail with the errors detected in featuares2d.hpp files. Errors as below
1) Unknown type name 'AlgorigthmInfo'; did you mean 'Algorigthm'?
2) No template named 'vector'; did you mean 'std::vector?'
Anything i did wrong when setup or installing opencv? or any linkpath i have to define?
Appreciated, for your advice. Thanks
Issues Solved:
Xcode compiler is smart and it able to predict solutions it match to your current machine configuration. If you just follow the suggestion given from the Xcode compiler, the issues was solve.
System not recognise AlgorigthmInfo, you may change to Algorigthm as well as vector to std::vector.
Now is completely working well openCV in my machine.
Hope, this will help some others if facing same issues.