0

I'm a newbie to C++ and QT creator. While trying to compile a program using OpenCV 3.0.0, on QT creator 3.4.1, on Mac OS X 10.10.4 I get the following errors:

ATopenCV.pro

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = QTopenCV
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h \
    colordetector.h

FORMS    += mainwindow.ui
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.10

INCLUDEPATH += /usr/local/include/

LIBS += -L/usr/local/lib
LIBS += -lopencv_core
LIBS += -lopencv_imgproc
LIBS += -lopencv_highgui
LIBS += -lopencv_ml
LIBS += -lopencv_video
LIBS += -lopencv_features2d
LIBS += -lopencv_calib3d
LIBS += -lopencv_objdetect
LIBS += -lopencv_flann
LIBS += -lopencv_imgcodecs

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <opencv2/opencv.hpp>
#include <QFileDialog>
#include "colordetector.h"

MainWindow::MainWindow(QWidget *parent)
   : QMainWindow(parent), ui(new Ui::MainWindow)
   {
      ui->setupUi(this);
      ui->pushButton_2->setEnabled(false);

   }
   MainWindow::~MainWindow()
   {

delete ui; }
void MainWindow::on_pushButton_clicked()
{

    QString fileName = QFileDialog::getOpenFileName(this, tr("Open image"), ".", tr("Image Files (*.png *.jpg *.bmp)"));
          image= cv::imread(fileName.toUtf8().data());

          if (image.data)
          {
              ui->pushButton_2->setEnabled(true);
          }

}

void MainWindow::on_pushButton_2_clicked()
{
    ColorDetector cdetect;
    cdetect.setTargetColor(230, 190, 130);
    cv::Mat result1;
    double duration;
    duration= static_cast<double>(cv::getTickCount());
    result1= cdetect.process(image);
    duration= static_cast<double>(cv::getTickCount()) - duration;
    duration /= cv::getTickFrequency();
    std::cout <<"Duration is "<< duration << " second" << std::endl;
    cv::imshow("Final", result1);
}

colordetector.h

if !defined COLORDETECT
#define COLORDETECT

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

class ColorDetector {

  private:

      // minimum acceptable distance
      int maxDist;

      // target color
      cv::Vec3b target;

      // image containing color converted image
      cv::Mat converted;
      bool useLab;

      // image containing resulting binary map
      cv::Mat result;

  public:

      // empty constructor
      // default parameter initialization here
      ColorDetector() : maxDist(100), target(0,0,0), useLab(false) {}

      // extra constructor for Lab color space example
      ColorDetector(bool useLab) : maxDist(100), target(0,0,0), useLab(useLab) {}

      // full constructor
      ColorDetector(uchar blue, uchar green, uchar red, int mxDist=100, bool useLab=false): maxDist(mxDist), useLab(useLab) {

          // target color
          setTargetColor(blue, green, red);
      }

      // Computes the distance from target color.
      int getDistanceToTargetColor(const cv::Vec3b& color) const {
          return getColorDistance(color, target);
      }

      // Computes the city-block distance between two colors.
      int getColorDistance(const cv::Vec3b& color1, const cv::Vec3b& color2) const {

          return abs(color1[0]-color2[0])+
                    abs(color1[1]-color2[1])+
                    abs(color1[2]-color2[2]);

          // Or:
          // return static_cast<int>(cv::norm<int,3>(cv::Vec3i(color[0]-color2[0],color[1]-color2[1],color[2]-color2[2])));

          // Or:
          // cv::Vec3b dist;
          // cv::absdiff(color,color2,dist);
          // return cv::sum(dist)[0];
      }

      // Processes the image. Returns a 1-channel binary image.
      cv::Mat process(const cv::Mat &image);

      cv::Mat operator()(const cv::Mat &image) {

          cv::Mat input;
          input = image;
          if (useLab) { // Lab conversion
              cv::cvtColor(image, input, CV_BGR2Lab);
          }

          cv::Mat output;
          // compute absolute difference with target color
          cv::absdiff(input,cv::Scalar(target),output);
          // split the channels into 3 images
          std::vector<cv::Mat> images;
          cv::split(output,images);
          // add the 3 channels (saturation might occurs here)
          output= images[0]+images[1]+images[2];
          // apply threshold
          cv::threshold(output,  // input image
                      output,  // output image
                      maxDist, // threshold (must be < 256)
                      255,     // max value
                 cv::THRESH_BINARY_INV); // thresholding type

          return output;
      }

      // Getters and setters

      // Sets the color distance threshold.
      // Threshold must be positive, otherwise distance threshold
      // is set to 0.
      void setColorDistanceThreshold(int distance) {

          if (distance<0)
              distance=0;
          maxDist= distance;
      }

      // Gets the color distance threshold
      int getColorDistanceThreshold() const {

          return maxDist;
      }

      // Sets the color to be detected
      void setTargetColor(uchar blue, uchar green, uchar red) {

          // BGR order
          target = cv::Vec3b(blue, green, red);

          if (useLab) {
              // Temporary 1-pixel image
              cv::Mat tmp(1, 1, CV_8UC3);
              tmp.at<cv::Vec3b>(0, 0) = cv::Vec3b(blue, green, red);

              // Converting the target to Lab color space
              cv::cvtColor(tmp, tmp, CV_BGR2Lab);

              target = tmp.at<cv::Vec3b>(0, 0);
          }
      }

      // Sets the color to be detected
      void setTargetColor(cv::Vec3b color) {

          target= color;
      }

      // Gets the color to be detected
      cv::Vec3b getTargetColor() const {

          return target;
      }
};


#endif

Compiler output

14:27:06: Running steps for project QTopenCV...
14:27:06: Configuration unchanged, skipping qmake step.
14:27:06: Starting: "/usr/bin/make" 
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -headerpad_max_install_names -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk -mmacosx-version-min=10.10 -Wl,-rpath,/Users/apple/Qt5.4.2/5.4/clang_64/lib -o QTopenCV.app/Contents/MacOS/QTopenCV main.o mainwindow.o moc_mainwindow.o   -F/Users/apple/Qt5.4.2/5.4/clang_64/lib -L/usr/local/lib -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_flann -lopencv_imgcodecs -framework QtWidgets -framework QtGui -framework QtCore -framework DiskArbitration -framework IOKit -framework OpenGL -framework AGL 
Undefined symbols for architecture x86_64:
  "ColorDetector::process(cv::Mat const&)", referenced from:
      MainWindow::on_pushButton_2_clicked() in mainwindow.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [QTopenCV.app/Contents/MacOS/QTopenCV] Error 1
14:27:06: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project QTopenCV (kit: Desktop Qt 5.4.2 clang 64bit)
When executing step "Make"
14:27:06: Elapsed time: 00:00.

What I was trying to do is: Give a color, find it and its nearby color (within a threshold) in an image, mask those color in white. The function was contained in the header file colorselection.h . Please help me!

1 Answers1

1

Undefined symbols for architecture x86_64: "ColorDetector::process(cv::Mat const&)

This is telling you that the implementation for the function ColorDetector::process can't be found.

MainWindow::on_pushButton_2_clicked() in mainwindow.o

And the function is being called in MainWindow::on_pushButton_2_clicked()

You've declared it in colordetector.h, so either the implementation is missing in colordetector.cpp, or it doesn't match the definition declared in the header.

TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85
  • 1
    Or you can implement cv::Mat process(const cv::Mat &image) in colordetector.h as it is done for other functions – demonplus Jul 15 '15 at 08:13
  • @demonplus, very true, though a separate implementation file [would be better](http://stackoverflow.com/questions/333889/why-have-header-files-and-cpp-files-in-c) ;O) – TheDarkKnight Jul 15 '15 at 08:13
  • 1
    Agree, let's move all the implementations to colordetector.cpp then – demonplus Jul 15 '15 at 08:15
  • Thank everyone for helping me out of this. There is indeed a typo in my colordetector.cpp file and I overlooked it. If you guys ever come to Vietnam, I'll give you a cookies ha ha :D – Trần Xuân Trường Jul 15 '15 at 12:48