我注意到 OpenCV 4 已经发布,其中一个区别是 API 更改为符合 C++11 标准。
这意味着什么?
我应该如何更改我的代码以与这个版本兼容?
我认为最大的不同之处在于,OpenCV 4.0
使用更多的C++11特性。现在cv::String == std::string
,而cv::Ptr
是对std::shared_ptr
的轻量级包装。
Opencv 4.0删除了文件夹include/opencv
,只保留了include/opencv2
。许多OpenCV 1.x的C API已被删除。受影响的模块包括objdetect、photo、video、videoio、imgcodecs、calib3d
。不建议使用旧的宏定义或未命名的枚举,应改用命名枚举。
//! include/opencv2/imgcodes.hpp
namespace cv
{
//! @addtogroup imgcodecs
//! @{
//! Imread flags
enum ImreadModes {
IMREAD_UNCHANGED = -1, //!< If set, return the loaded image as is (with alpha channel, otherwise it gets cropped).
IMREAD_GRAYSCALE = 0, //!< If set, always convert image to the single channel grayscale image (codec internal conversion).
IMREAD_COLOR = 1, //!< If set, always convert image to the 3 channel BGR color image.
IMREAD_ANYDEPTH = 2, //!< If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.
IMREAD_ANYCOLOR = 4, //!< If set, the image is read in any possible color format.
IMREAD_LOAD_GDAL = 8, //!< If set, use the gdal driver for loading the image.
IMREAD_REDUCED_GRAYSCALE_2 = 16, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/2.
IMREAD_REDUCED_COLOR_2 = 17, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/2.
IMREAD_REDUCED_GRAYSCALE_4 = 32, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/4.
IMREAD_REDUCED_COLOR_4 = 33, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4.
IMREAD_REDUCED_GRAYSCALE_8 = 64, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/8.
IMREAD_REDUCED_COLOR_8 = 65, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8.
IMREAD_IGNORE_ORIENTATION = 128 //!< If set, do not rotate the image according to EXIF's orientation flag.
};
// ...
}
比如,在读取图片时,应该是这个样子:
cv::Mat img = cv::imread("test.png", cv::IMREAD_COLOR);
除了新功能之外,大多数C++ API保持不变。然而我发现最大的区别是cv2.findContours
(在Python OpenCV
中):
在OpenCV 3.4版本中:
findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> image, contours, hierarchy
在OpenCV 4.0中:
findContours(image, mode, method[, contours[, hierarchy[, offset]]]) -> contours, hierarchy
使用2.x、3.x、4.x的另一种选择是:
cnts, hiers = cv2.findContours(...)[-2:]
一些链接:
enum class
或 enum struct
可能更好,因为它们是有作用域的。但由于代码库非常庞大,存在很多使用无作用域枚举的代码。如果将 enum
更改为 enum class
,则使用 cv::IMREAD_COLOR
的现有代码将编译失败,除非修改为 cv::ImreadModes::IMREAD_COLOR
。而且,在将 C++ OpenCV API
封装到 Python|Java|C#
中时,仍然存在许多与 enum
更改相关的错误。所以他们只是保持原样吗?我不太确定。 - Kinght 金enum struct
问题在GitHub上的链接:https://github.com/opencv/opencv/pull/13471 - Kinght 金要使用,需要clang版本3.3及更高版本,并添加标志OpenCV现在是C++11库,需要符合C++11的编译器
-std=c++11
。g++ 4.3及更高版本也是如此。std::string
而不是cv::String
和其他c++11功能。但不用担心,cv::String
仍然可以使用,但现在是std::string
的别名。智能指针等类似。cvCvtColor
)都有它们在C++中的等效函数cv::cvtColor
(具有相同的功能)。此外,还支持从旧式C类型转换为C++类型,您可以在这里看到。希望你不会用这种方式度过假期 :D - kocica我认为最关键的影响是需要使用c++11编译器。
此外,它可能不会改变接口,但允许他们利用更新的语言更改,如智能指针等。
findContours
回归到返回一对值(就像2.x版本中没有修改输入图像时那样),而不是3.x版本中的三个值。 - Dan Mašek