これを分解しましょう。
まず、あなたが構築しているマトリックスの種類は、一般に「長方形マトリックス」、
- すべての行が同じ長さを持つことにより、
- すべての列が同じ長さを持っていると呼ばれるものです
- 床の長さはすべて同じです。
これは、このレベルでポインタ間接を使用する理由がないことを意味します。
だから、私たちの最初のリファクタリング:あなたは正しいインデックスにアクセスするのに役立ちます機能をお勧めします
unsigned short *cost = new short[leftImg.rows * leftImg.cols * disparityRange]{};
unsigned short *aggreg = new short[rightImg.rows * rightImg.cols * disparityRange]{};
//All of this is now irrelevant and unnecessary.
//for(int row=0; row<leftImg.rows; row++) {
//cost[row] = new unsigned short*[leftImg.cols];
//aggreg[row] = new unsigned short*[rightImg.cols];
//for(int col=0; col<leftImg.cols; col++) {
//cost[row][col] = new unsigned short[disparityRange]();
// fill_n(cost[row][col], disparityRange, 0);
//aggreg[row][col] = new unsigned short[disparityRange]();
//}
//}
:calculatePixelCost
でそう
size_t get_index(size_t i, size_t j, size_t k, size_t rows, size_t cols, size_t floors) {
return i * cols * floors + j * floors + k;
}
は、この代わりのようなコードを記述します。
void calculatePixelCost(unsigned short *cost, cv::Mat& leftImg, cv::Mat& rightImg, int dRange) {
for(int i=0; i<leftImg.rows; i++)
for(int j=0; j<rightImg.cols; j++)
for(int d=0; d<dRange; d++) {
cost[get_index(i, j, d, leftImg.rows, leftImg.cols, dRange)] = calculatePixelBT(leftImg, rightImg, i, j, d);
}
}
このコードは、問題の絞り込みに役立ちます。しかし、私たちは少し良くすることができます。
このように、裸で暴露されているあなたのポインタを持ってはいけません。子供たちがあなたのコードを見ているかもしれません!
私たちはC++の土地にいるので、このような状況を処理する正しい方法は、物事をクラスにまとめることです。とにかく適切な "3次元マトリックス"オブジェクトが必要なので、適切なマトリックスクラスを作ってみましょう。
class matrix {
size_t _rows, _columns, _floors;
//We'll use a std::vector object so that we no longer see any naked pointers.
std::vector<short> values;
public:
matrix(size_t rows, size_t columns, size_t floors) :
_rows(rows), _columns(columns), _floors(floors),
values(_rows * _columns * _floors)
{}
short & operator()(size_t row, size_t column, size_t floor) {
if(row >= _rows || column >= _columns || floor >= _floors)
throw std::runtime_error("Invalid access to matrix!");
return values[row * _columns * _floors + column * _floors + floor];
}
short const& operator()(size_t row, size_t column, size_t floor) const {
if(row >= _rows || column >= _columns || floor >= _floors)
throw std::runtime_error("Invalid access to matrix!");
return values[row * _columns * _floors + column * _floors + floor];
}
//We will not implement a resize function, as the logic of how it should work
//hasn't been established. It's probably better to simply allow new matrices
//to overwrite this one using the default-defined copy and move constructors.
//void resize(size_t rows, size_t columns, size_t floors);
bool operator==(matrix const& m) const {
if(!(_rows == m._rows && _columns == m._columns && _floors == m._floors)) return false;
return values == m.values;
}
size_t rows() const {return _rows;}
size_t columns() const {return _columns;}
size_t floors() const {return _floors;}
};
次に、あなたのコード内でこの行列を使用します。
matrix cost{leftImg.rows, leftImg.cols, disparityRange};
matrix aggreg{rightImg.rows, rightImg.cols, disparityRange};
としてだけでなく、ここに:
void calculatePixelCost(matrix & cost, cv::Mat& leftImg, cv::Mat& rightImg, int dRange) {
for(int i=0; i<leftImg.rows; i++)
for(int j=0; j<rightImg.cols; j++)
for(int d=0; d<dRange; d++) {
cost(i, j, d) = calculatePixelBT(leftImg, rightImg, i, j, d);
}
}
はそれが理解することですどのくらいに簡単か?ええ、それはもっと前のことですが、コードが何をしているのか、それがなぜ必要なのかを簡単に推論することができます。
まだチェックアウトする必要があるものがたくさんあります。たとえば、三重ネストされたforループへの依存は不審であり、最低限、リファクタリングする方がよいでしょう。しかし、そのことはあなたの問題を解決するためにあまり重要ではありません。
少なくともこの新しいコードでは、問題が発生している領域を簡単に識別できるはずです。
[mcve]の作成に時間がかかる場合は、問題を自分で解決するか、ここで質問する*良い*質問があります。 –
3スターのプログラマーにならないでください。 1Dベクトルを使用し、それらの1D位置に 'row'、' col'と 'disparity'をマップします。 –
C言語ではなくC言語を使っているなら、あなたの特定の神格を愛するために、手動でメモリを管理する代わりにベクトルを使用してください。 'std :: vector>>'は、推論するのがずっと簡単です。 –
cdhowie