2

I have recently been working with the OpenCV framework (ver. 3.4.3) for Xcode (ver. 10.0), with which I am attempting to create a depth map from stereo images (based on the steps outlined in this tutorial; albeit not in Python). I have created the following function as an attempt:

+ (UIImage *)to3D:(UIImage *)ui1 :(UIImage *)ui2 {
  Mat cv1(ui1.size.width, ui1.size.height, CV_8UC4);
  Mat cv2(ui2.size.width, ui2.size.height, CV_8UC4);
  Mat dsp(ui2.size.width, ui2.size.height, CV_8UC4);

  UIImageToMat(ui1, cv1, true);
  UIImageToMat(ui2, cv2, true);

  StereoBM *stereo = StereoBM::create(16, 15);
  stereo -> StereoBM::compute(cv1, cv2, dsp);

  return MatToUIImage(dsp);
}

I have included this function as part of my OpenCV setup (based on this article).

When I attempt to build the solution, however, I am met with this error:

Undefined symbols for architecture arm64:
  "cv::StereoMatcher::compute(cv::_InputArray const&, cv::_InputArray const&, cv::_OutputArray const&)", referenced from:
      +[OpenCV to3D::] in OpenCV.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Looking up the error title, I discovered this StackOverflow question and went through some of the responses. Although some of the solutions are slightly outdated, I verified that the Other Linker Flags attribute contained the $(inherited) argument, and that the target membership for the aforementioned file was enabled. I also tried changing the C++ Standard Library attribute, to no effect.

Since the StereoBM::create() code does not cause any issues, and both the syntax highlighter and code auto-completer respond to the StereoBM::compute() code as expected, I am unsure how to resolve this issue.

EndoM8rix
  • 56
  • 7

1 Answers1

1

After some additional searching, I have been able to resolve the issue. Since I was using a raw pointer, instead of cv::Ptr<T> (outlined here) I was not correctly creating a valid instance of the abstract class.

I adapted my code to the following:

+ (UIImage *)to3D:(UIImage *)ui1 :(UIImage *)ui2 {
  Mat cv1(ui1.size.width, ui1.size.height, CV_8UC4);
  Mat cv2(ui2.size.width, ui2.size.height, CV_8UC4);
  Mat dsp(ui2.size.width, ui2.size.height, CV_8UC4);

  UIImageToMat(ui1, cv1, true);
  UIImageToMat(ui2, cv2, true);

  Ptr<StereoBM> stereo = StereoBM::create(16, 15); // changed type to Ptr<StereoBM>
  stereo -> compute(cv1, cv2, dsp); // removed StereoBM:: namespace

  return MatToUIImage(dsp);
}

Note that while this did resolve my issue, I did discover additional unrelated issues with my implementation (most notably the lack of memory release and incompatible image formats) which I resolved separately. I decided not to include those changes in my solution code as they do not affect the issue in question.

EndoM8rix
  • 56
  • 7