在下面的代碼中,我想在回圈中為 Mat 變數的元素賦值。我得到下面的運行時錯誤。
pair<Mat, Mat> meshgrid(vector<int> x, vector<int> y) {
int sx = (int)x.size();
int sy = (int)y.size();
Mat xmat = Mat::ones(sy, sx, CV_16U);
Mat ymat = Mat::ones(sy, sy, CV_16U);
for (int i = 0; i < sx; i ) {
for (int j = 0; j < sy; j ) {
xmat.at<int>(i, j) = j; //<------- here is place of error.
cout << j << "\t";
}
cout << endl;
}
for (int i = 0; i < sx; i ) {
for (int j = 0; j < sy; j ) {
ymat.at<int>(i, j) = i; //<------- here is place of error.
cout << j << "\t";
}
cout << endl;
}
return make_pair(xmat, ymat);
}
除錯時的這張圖;
在此處輸入影像描述
這是我得到的運行時錯誤:
OpenCV(...) 錯誤:斷言失敗 (((((sizeof(size_t)<<28)|0x8442211) >> ((traits::Depth<_Tp>::value) & ((1 << 3) - 1))*4) & 15) == elemSize1()) 在 cv::Mat::at,檔案 ...\include\opencv2\core\mat.inl.hpp,第 1108 行
謝謝您的回答。
uj5u.com熱心網友回復:
首先請注意,在 SO 中,最好避免添加指向影像的鏈接。盡可能嘗試將資訊復制粘貼為文本。這特別適用于您收到的錯誤。
我假設您打算生成類似于numpy.meshgrid, 和Matlabmeshgrid的輸出。
您的代碼中有幾個錯誤:
- 使用
cv::MatCV_16U 型別(即 16 位無符號值)進行初始化,但是當您使用您訪問的元素時at(int它是 32 位有符號的)。您應該將其更改為at<unsigned short>(或將型別更改cv::Mat為 32 位有符號 -CV_32S)。 cv::Mat您用錯誤的大小初始化了:xmat大小為(sy, sx),但ymat大小為(sy, sy)。- 您用于訪問 mat 元素的索引 (row, col) 不正確。為了更容易正確使用,我將維度的名稱更改為
rows,cols,并將回圈索引更改為iRow,iCol。 - 矩陣中的值應該來自
x和y向量中的值(而不是索引)。
請參閱下面的更新代碼(以及其后有關更改的注釋):
#include <opencv2/core/core.hpp>
#include <vector>
#include <iostream>
std::pair<cv::Mat, cv::Mat> meshgrid(std::vector<unsigned short> const & x, std::vector<unsigned short> const & y)
{
int cols = static_cast<int>(x.size());
int rows = static_cast<int>(y.size());
cv::Mat xmat(rows, cols, CV_16U);
cv::Mat ymat(rows, cols, CV_16U);
for (int iRow = 0; iRow < rows; iRow) {
auto * pRowData = xmat.ptr<unsigned short>(iRow);
for (int iCol = 0; iCol < cols; iCol) {
pRowData[iCol] = x[iCol];
std::cout << pRowData[iCol] << "\t";
}
std::cout << std::endl;
}
std::cout << std::endl;
for (int iRow = 0; iRow < rows; iRow) {
auto * pRowData = ymat.ptr<unsigned short>(iRow);
for (int iCol = 0; iCol < cols; iCol) {
pRowData[iCol] = y[iRow];
std::cout << pRowData[iCol] << "\t";
}
std::cout << std::endl;
}
return std::make_pair(std::move(xmat), std::move(ymat));
}
int main()
{
std::vector<unsigned short> xxx{ 1,2 };
std::vector<unsigned short> yyy{ 10,11,12 };
auto p = meshgrid(xxx, yyy);
return 0;
}
輸出:
1 2
1 2
1 2
10 10
11 11
12 12
一些注意事項:
- 我可能誤解了你想在
cv::Mat's. 但至少現在你的代碼不會崩潰。您可以根據需要更改分配的值。 - 使用一個接一個
at地訪問cv::Mat元素是非常低效的,因為at每次訪問都包含一些驗證。cv::Mat使用方法效率更高ptr,它為您提供指向行資料的指標。然后您可以使用此指標更有效地遍歷行 - 見上文 - 在任何方法中,逐行遍歷
cv::Mat(而不是逐列)更有效。這會導致您訪問連續記憶體,并減少快取未命中的數量。 - 在您的真實代碼中,最好將計算與 I/O 分開。因此,如果您的
meshgrid函式只創建矩陣會更好。如果需要,請在外面列印。 - 無需將
cv::Mats 初始化為 1,因為之后我們立即為所有元素設定值。 - 在我的代碼中
x,并y通過 const 參考傳遞給函式。它更有效(避免復制)并且還強制編譯器驗證向量沒有被修改。 - 最好避免
using namespace std- 請參閱此處為什么“使用命名空間 std;” 被認為是不好的做法?. 出于類似的原因,我也建議避免using namespace cv使用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/472811.html
