首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

OpenCV cvmGet 僅支持浮點型矩陣:8U 類型讀取崩潰解決方案

     編輯:程式設計綜合問答

OpenCV C 接口函數 cvmGet 僅支持單通道浮點型矩陣(32F/64F),對 8U(無符號 8 位)等整數類型矩陣調用會導致運行時崩潰(R6010 abort)。本文說明原因並給出正確訪問方式。

錯誤現象


CvMat* mat = cvCreateMat(100, 100, CV_8UC1); // 8U 類型
double val = cvmGet(mat, 10, 10); // 崩潰:R6010 abort()

根本原因

cvmGet 官方文檔明確聲明:

Returns the particular element of single-channel floating-point matrix.

內部實現直接按 float* 或 double* 解引用數據指針,8U 類型數據佈局不匹配,導致非法內存訪問。

正確訪問 8U 矩陣元素

方法一:C 接口 - 指針運算(推薦)


CvMat* mat = cvCreateMat(100, 100, CV_8UC1);
// 獲取行指針
uchar* ptr = (uchar*)cvPtr1D(mat, row, NULL);
// 訪問列
uchar value = ptr[col];
// 或一行代碼
uchar value = ((uchar*)(mat->data.ptr + row * mat->step))[col];

方法二:C++ 接口 - Mat::at<>()(現代、類型安全)


cv::Mat mat(100, 100, CV_8UC1);
uchar value = mat.at(row, col); // 編譯期類型檢查
mat.at(row, col) = 255; // 寫入

方法三:C 接口 - cvGet1D/cvGet2D(通用但較慢)


CvScalar s = cvGet2D(mat, row, col);
uchar value = (uchar)s.val[0];

類型對應表

OpenCV 類型C 對應類型C++ 對應類型cvmGet 支持
CV_8U / CV_8UC1uchar / unsigned charuchar❌
CV_16Uushortushort❌
CV_32Sintint❌
CV_32Ffloatfloat✅
CV_64Fdoubledouble✅

遷移建議:全面使用 C++ 接口


// 舊代碼(C 接口)
IplImage* img = cvLoadImage("test.jpg");
CvMat* mat = cvCreateMat(img->height, img->width, CV_32FC1);
cvConvert(img, mat);
double v = cvmGet(mat, 10, 10);

// 新代碼(C++ 接口)
cv::Mat img = cv::imread("test.jpg", cv::IMREAD_GRAYSCALE);
img.convertTo(img, CV_32F); // 如需浮點
float v = img.at(10, 10); // 類型安全、IDE 提示、無崩潰風險

總結

cvmGet 僅限單通道浮點矩陣(32F/64F)。8U/16U/32S 等整數類型必須使用指針運算(C 接口)或 Mat::at<>()(C++ 接口)。強烈建議新項目全面遷移至 C++ cv::Mat,享受類型安全、自動內存管理、現代 C++ 特性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved