0

I have installed OpenCV. I have been able to compile some code but sometimes it does not work. The example below does not work.

#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/gpu/gpu.hpp"

int main (int argc, char* argv[])
{
    try
    {
        cv::Mat src_host = cv::imread("building.jpg", CV_LOAD_IMAGE_GRAYSCALE);
        cv::gpu::GpuMat dst, src;
        src.upload(src_host);

        cv::gpu::threshold(src, dst, 128.0, 255.0, CV_THRESH_BINARY);

        cv::Mat result_host = dst;
        cv::imshow("Result", result_host);
        cv::waitKey();
    }
    catch(const cv::Exception& ex)
    {
        std::cout << "Error: " << ex.what() << std::endl;
    }
    return 0;
}

I get the following errors when I compile with

gcc Test.cpp $(pkg-config --cflags --libs opencv)

gcc Test.cpp $(pkg-config --cflags --libs opencv)
Undefined symbols for architecture x86_64:
"std::allocator<char>::allocator()", referenced from:
  _main in ccnzUIww.o
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)", referenced from:
  _main in ccnzUIww.o
"std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()", referenced from:
  _main in ccnzUIww.o
"std::terminate()", referenced from:
  _main in ccnzUIww.o
"std::allocator<char>::~allocator()", referenced from:
  _main in ccnzUIww.o
"cv::gpu::GpuMat::upload(cv::Mat const&)", referenced from:
  _main in ccnzUIww.o
"cv::gpu::Stream::Null()", referenced from:
  _main in ccnzUIww.o
"cv::gpu::threshold(cv::gpu::GpuMat const&, cv::gpu::GpuMat&, double, double, int, cv::gpu::Stream&)", referenced from:
  _main in ccnzUIww.o
"cv::gpu::GpuMat::operator cv::Mat() const", referenced from:
  _main in ccnzUIww.o
"___cxa_begin_catch", referenced from:
  _main in ccnzUIww.o
"std::cout", referenced from:
  _main in ccnzUIww.o
"std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from:
  _main in ccnzUIww.o
"std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)", referenced from:
  _main in ccnzUIww.o
"std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))", referenced from:
  _main in ccnzUIww.o
"___cxa_end_catch", referenced from:
  _main in ccnzUIww.o
"std::ios_base::Init::Init()", referenced from:
  __static_initialization_and_destruction_0(int, int)in ccnzUIww.o
"std::ios_base::Init::~Init()", referenced from:
  ___tcf_0 in ccnzUIww.o
"cv::gpu::GpuMat::release()", referenced from:
  cv::gpu::GpuMat::~GpuMat()in ccnzUIww.o
"___gxx_personality_v0", referenced from:
  Dwarf Exception Unwind Info (__eh_frame) in ccnzUIww.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

I have also tried:

  • gcc Test.cpp $(pkg-config --cflags --libs opencv) -m32
  • gcc Test.cpp $(pkg-config --cflags --libs opencv) -m64
  • nvcc Test.cpp $(pkg-config --cflags --libs opencv)

But this also give errors. I have looked for answers on stackoverflow and found this. Compiling OpenCV CUDA program In this answer the solution is to use this command:

g++ Test.cpp `pkg-config --cflags --libs opencv` -lopencv_gpu

And it works! I have tried giving the same argument to the gcc and nvcc compiler but then I get errors again. This is a problem since I have to use the nvcc compiler because I want to use OpenCV in a CUDA project.

I have little experience with C and C++ so there is a possibility that it is something obvious :)

Community
  • 1
  • 1
Mads Andersen
  • 3,123
  • 5
  • 38
  • 44
  • 6
    OpenCV is C++, your example program is definitely C++, *not* C. Compiling it with a C compiler don't make sense. It can be done with gcc, but it makes a whole load of extra work for you for no reason. – Flexo Sep 26 '11 at 14:54
  • Thanks! But I need to use the nvcc compiler since in the future I could add some CUDA code inside that file. – Mads Andersen Sep 26 '11 at 15:10
  • 1
    Use `nvcc` to compile and `g++` to link then. – Flexo Sep 26 '11 at 15:15
  • Ok. I guess I can just add CUDA code to CUDA files and C/C++ code to C/C++ files and then just compile and link them separately. – Mads Andersen Sep 26 '11 at 15:49

2 Answers2

6

For compiling and linking C code you should use gcc

For compiling and linking C++ code you should use g++

Although gcc can often correctly guess what language to compile a file as, it can usually not link to the needed libraries.

PlasmaHH
  • 15,673
  • 5
  • 44
  • 57
  • Thanks. That was obvious. But CUDA supports C++ so why does nvcc not check this. And how to solve this? ;) – Mads Andersen Sep 26 '11 at 15:09
  • @bobjink: I can only guess, but I think that nvcc works the same here as gcc: It can properly compile, but not link. So you should use nvcc just to compile (`cc -c foo.cxx -o foo.o`) and then use g++ to link (`g++ -o app foo.o bar.o xxx.o`) – PlasmaHH Sep 26 '11 at 15:53
  • Thanks. Now I understand it better. I tried: 1: nvcc -c Test.cpp -o Test.o 2: g++ -o app Test.o `pkg-config --cflags --libs opencv` -lopencv_gpu but got the error: ld: warning: ignoring file Test.o, file was built for i386 which is not the architecture being linked (x86_64) so I guess it doesnt work. – Mads Andersen Sep 26 '11 at 16:45
  • Sounds like you either want -m32 on the g++ call or -m64 on the nvcc line. – Flexo Sep 26 '11 at 23:44
0

I think that these commands will work, because it worked in my computer (Ubuntu+OpenCV +Eclipse)

huynhngoctan@ubuntu:~/workspace$ g++ SiftDescriptor.cpp $(pkg-config --cflags --libs opencv) -lopencv_gpu

huynhngoctan@ubuntu:~/workspace$ ./a.out box.png box_in_scene.png

HNT_BK
  • 3
  • 3