OpenCV 2.x迁移至3.x:cvGetMat函数替代方案咨询
cvGetMat()函数 Hey, I see you're hitting this error:
‘cvGetMat’ was not declared in this scope CvMat srcstub, *src = cvGetMat( srcarr, &srcstub ); ^~~~~~~~
That's totally expected—cvGetMat() got dropped from OpenCV 3.x's C API. But there are two great workarounds, depending on whether you can shift to the recommended C++ interface or need to keep your code in pure C.
推荐方案:切换到C++接口的cv::cvarrToMat()
If you're open to migrating to the C++ API (which is the way to go since OpenCV has been prioritizing it for years), cv::cvarrToMat() does exactly what cvGetMat() used to do, but without the hassle of stub variables. It converts old C-style arrays (IplImage* or CvMat*) directly to cv::Mat objects seamlessly.
Here's how to update your code snippet:
#include <opencv2/opencv.hpp> void cvCanny3(const void* srcarr, void* dstarr, void* dxarr, void* dyarr, int aperture_size) { // Convert C-style input arrays to cv::Mat objects cv::Mat src = cv::cvarrToMat(static_cast<const CvArr*>(srcarr)); cv::Mat dst = cv::cvarrToMat(static_cast<CvArr*>(dstarr)); cv::Mat dx = cv::cvarrToMat(static_cast<CvArr*>(dxarr)); cv::Mat dy = cv::cvarrToMat(static_cast<CvArr*>(dyarr)); // Your existing logic can now use these cv::Mat instances—you can even switch to C++ versions of OpenCV functions here for better long-term support // ... }
纯C代码兼容方案
If you absolutely need to retain pure C code, you'll have to replicate what cvGetMat() did manually by checking the input type and creating a CvMat header for image inputs.
Here's the adjusted code:
#include <opencv2/imgproc/imgproc_c.h> void cvCanny3(const void* srcarr, void* dstarr, void* dxarr, void* dyarr, int aperture_size) { CvMat* src; // Check if input is already a CvMat if (CV_IS_MAT(srcarr)) { src = (CvMat*)srcarr; } // Handle IplImage inputs by creating a CvMat header pointing to the image data else if (CV_IS_IMAGE(srcarr)) { IplImage* src_img = (IplImage*)srcarr; src = cvCreateMatHeader(src_img->height, src_img->width, CV_MAKETYPE(src_img->depth, src_img->nChannels)); cvSetData(src, src_img->imageData, src_img->widthStep); } // Handle invalid input types else { return; } // Repeat the same logic for dst, dx, and dy CvMat* dst; if (CV_IS_MAT(dstarr)) { dst = (CvMat*)dstarr; } else if (CV_IS_IMAGE(dstarr)) { IplImage* dst_img = (IplImage*)dstarr; dst = cvCreateMatHeader(dst_img->height, dst_img->width, CV_MAKETYPE(dst_img->depth, dst_img->nChannels)); cvSetData(dst, dst_img->imageData, dst_img->widthStep); } else { return; } // ... Apply the same handling for dx and dy ... // Note: You don't need to free the created CvMat headers—they just reference the original image's data, so no memory leaks here // Proceed with your existing C-style OpenCV logic // ... }
Key Notes:
- Prioritize the C++ approach: OpenCV's C API is deprecated and will likely be completely removed in future versions, so migrating to C++ will save you from more compatibility issues down the line.
- The error you're seeing is just OpenCV telling you that
cvGetMat()no longer exists in 3.x+—the workarounds above replicate its original functionality without relying on the removed function.
内容的提问来源于stack exchange,提问作者lonewolf07

