6

Within an OpenCV project normally cv::String is used in functions, e.g. a simple putText. However, when using functions of std std::string is in charge. E.g. in the case

ifstream stream(filepath);
string line;
getline(stream, line, '\n');

it is necessary to have a std::string as cv::String throws an error. In the vice versa case using an OpenCV function std::string is properly converted to cv::String and following code does work:

string Str = "Test";
putText(img, Str, Point(10, 10), FONT_HERSHEY_PLAIN, 1, Scalar::all(255), 1);

Questions

Why does OpenCV has an own String-Class? I think there may be some differences useful for OpenCV, while all (or most?) functionality of std::string is still possible for cv::String. But it seems that std::string can be converted to cv::String (which I have tested at least for putText.

The documentations show similar functions but also some differences like the related functions static bool operator> (const String &lhs, const String &rhs) and similar:

http://docs.opencv.org/3.1.0/d1/d8f/classcv_1_1String.html for cv::String http://www.cplusplus.com/reference/string/string/ for std::string

Am I missing something?

Is there a reason why I should use both versions of Strings in one project or would it be acceptable to only use std::string in terms of better readability? (As long as not using e.g. the related functions mentioned earlier)

Edit: This question here addresses a similar problem with QString and string and the recommendation is to use std::string where possible. I wonder if this is also valid for OpenCV.

Phann
  • 1,283
  • 16
  • 25

3 Answers3

6

Why does OpenCV have its own string class? OpenCV is a pretty old library (first release June 2000). At that point, standard libraries were less reliable, and the OpenCV team probably decided they would rather write their own. The MFC team made the same decision a few years earlier, as did the Qt team and the wxWidgets team. This proliferation of "string" classes is exactly why the standards committee defined std::string - but it was too late.

If you can get away with using just one string class throughout the project - go for it. Often you can't; for example, given a function which return a cv::String, there is no automatic conversion to std::string. given a function which takes a cv::String by non-const reference, you need an actual cv::String object to pass. (Edit: Jonas points out that there is an automatic conversion from cv::String to std::string.)

Also note that your call to putString may actually use a cv::String - it is implicitly constructed from std::string via the converting constructor. If (and only if) you have a performance hot-spot, those unnecessary conversions may be a problem.

  • 1
    Note that `cv::String` has `operator std::string() const;`, from: https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/cvstd.hpp – Jonas Aug 24 '17 at 10:09
  • the age of opencv really might be a point, especially because initially openCV war plain C! – Micka Aug 24 '17 at 10:51
  • @Jonas: Thanks! I missed that in the documentation I looked at. – Martin Bonner supports Monica Aug 24 '17 at 11:01
  • Well, since C++17 you shouldn't ever use a constant string-reference as an argument, whatever string-type you use. Instead, it should be a `std::string_view` by value. – Deduplicator Aug 24 '17 at 11:03
  • 1
    @Deduplicator: C++17 is not yet an official ISO standard. ... and I bet OpenCV won't change their function signatures. (Although it would be nice if they added another one and made the rest be inline forwards to it.) – Martin Bonner supports Monica Aug 24 '17 at 11:11
4

If you know that you construct a string to use it with openCV functions only and you don't need to manipulate it in a fancy way, I would use cv::String to avoid multiple casting and possibly minimizing number of dependencies used in project.

If, on the other hand, you are planning to use your string all around your application or you are planning to play with it before passing it to a function, I would stick to std::string as it comes with all the algorithms of the standard library that you can use with it, and, again, to avoid multiple casting.

To me it's ok to use both versions in different parts of the same application if it's convenient. Just be consistent about your usage of them, e.g. if you choose the above approach, don't use std::string if its sole purpose is to serve openCV functions and vice versa.

As for why openCV developers decided to have their own version of string, I can only guess, and I would guess that they assumed that even if today the basic functionality is the same, having their own version opens new possibilites for introducing new features without breaking already existing code tomorrow. It's a fairly common design approach to wrap other classes within your own, especially when you are writing a library, even if your classes initially don't offer additional functions - just to leave the door open in case you wanted to use different library one day to implement some features or adding new ones by yourself.

KjMag
  • 2,650
  • 16
  • 16
2

The changelog of OpenCV 4.0 states:

Thanks to the extended C++11 standard library, we could get rid of hand-crafted cv::String and cv::Ptr. Now cv::String == std::string and cv::Ptr is a thin wrapper on top of std::shared_ptr.

Phann
  • 1,283
  • 16
  • 25