opencv — дизайн FIR-фильтра в C ++ с использованием коэффициентов из MATLAB, фильтр не дает правильных результатов

Я работаю над проектом в OpenCV, так как я новичок в этой области, я столкнулся с несколькими проблемами с ним. Мне нужно спроектировать полосовой FIR-фильтр 128-го порядка, для которого я использовал коэффициенты, рассчитанные через MATLAB. Я нашел следующий код онлайн.

const int taps = 129;
double buffer[129] = {0.0};
int offset = 0;
double input;

double coefficients[] =

{
0.0005,0.0004,0.0002,0.0000,-0.0001,-0.0000,0.0001,0.0004,0.0007,0.0011,
0.0015,0.0017,0.0018,0.0016,0.0011,0.0006,0.0001,-0.0003,-0.0002,0.0003,
0.0011,0.0022,0.0032,0.0038,0.0038,0.0031,0.0015,-0.0005,-0.0026,-0.0044,
-0.0053,-0.0050,-0.0037,-0.0016,0.0007,0.0023,0.0027,0.0012,-0.0022,-0.0072,
-0.0127,-0.0178,-0.0212,-0.0220,-0.0199,-0.0153,-0.0093,-0.0036,-0.0001,-0.0003,
-0.0053,-0.0147,-0.0274,-0.0408,-0.0519,-0.0573,-0.0545,-0.0419,-0.0197,0.0102,
0.0442,0.0779,0.1064,0.1254,0.1321,0.1254,0.1064,0.0779,0.0442,0.0102,-0.0197,
-0.0419,-0.0545,-0.0573,-0.0519,-0.0408,-0.0274,-0.0147,-0.0053,-0.0003,-0.0001,-0.0036,
-0.0093,-0.0153,-0.0199,-0.0220,-0.0212,-0.0178,-0.0127,-0.0072,-0.0022,0.0012,0.0027,
0.0023,0.0007,-0.0016,-0.0037,-0.0050,-0.0053,-0.0044,-0.0026,-0.0005,0.0015,0.0031,
0.0038,0.0038,0.0032,0.0022,0.0011,0.0003,-0.0002,-0.0003,0.0001,0.0006,0.0011,
0.0016,0.0018,0.0017,0.0015,0.0011,0.0007, 0.0004,0.0001,-0.0000,-0.0001,0.0000,
0.0002,0.0004,0.0005
};double filter( double input)

{
double output = 0;for(int i= taps-1; i>0 ; i-- )
{
buffer[i] = buffer[i-1];
}

buffer[0] = input;for(int j = 0; j<taps; j++ )
{

output += (coefficients[j]*buffer[j]);

}
return output;
}

Я пытаюсь использовать фильтр, как описано во фрагменте кода ниже.
FilterTrajectory — это вектор вектора, в котором я хочу сохранить отфильтрованные значения. YCoordinates — это вектор вектора, содержащий данные для фильтрации. Размерность координат Y [1000×266]

// Calling FIR filter function filter
// filtering all 266 values across 1000 frames.

const int numFrames = 1000;

//featuresPrevious.size() = 266 (predefined fixed value)

vector<vector<double>> filteredTrajectory;
filteredTrajectory.resize(numFrames-1);

for (int i = 0; i<numFrames-1; i++)

{

filteredTrajectory[i].resize(featuresPrevious.size());

for (int j = 0; j<featuresPrevious.size(); j++)

{

filteredTrajectory[i][j] = filter (Ycoordinates[i][j]);

}

}

Когда я запускаю этот код, отфильтрованные значения не совпадают со значениями в MATLAB. Однако, если я отфильтрую только одно значение во всех 1000 фреймах, я получу совпадающие результаты с MATLAB (см. Код ниже).

// Filtering value at index Ycoordinates[i][0] across all frames

filteredTrajectory.resize(numFrames-1);

for (int i = 0; i<numFrames-1; i++)

{

filteredTrajectory[i].resize(1);

filteredTrajectory[i][0] = filter (Ycoordinates[i][0]);

}

Какие могут быть возможные недостатки в коде, которые дают неправильные результаты при фильтрации всех траекторий внутри цикла, но сопоставляют результаты при индивидуальной фильтрации.

3

Решение

Matlab-х filter это одномерный фильтр. Когда предоставляется вход, который представляет собой двумерную матрицу, он фильтрует каждый столбец независимо (по умолчанию, если dim параметр не установлен или установлен в 1; установка dim до 2 будет делать то же самое, но для каждой строки), по существу сбрасывая состояние КИХ между каждым обработанным столбцом (или строкой).

Таким образом, для достижения правильного результата вы также должны сбросить состояние фильтра, в котором вы храните buffer между каждым набором значений, которые будут отфильтрованы установкой сброса буфера в нули:

void reset_buffer()
{
for(int i=0; i<taps ; i++ )
{
buffer[i] = 0.0;
}
}

Кроме того, фильтр должен видеть каждое значение, принадлежащее одному и тому же набору, последовательно (т. Е. Не чередуя значения с функцией фильтрации), поэтому важен порядок цикла. В зависимости от того, хотите ли вы отфильтровать размерность данных по столбцам или строкам, вы можете использовать одну из следующих функций:

// Filter along columns, similar to Matlab's filter(coefficients, 1, data, [], 1)
void filterDim1()
{
for (int i = 0; i<numFrames-1; i++)
{
filteredTrajectory[i].resize(featuresPrevious.size());
}
for (int j = 0; j<featuresPrevious.size(); j++)
{
for (int i = 0; i<numFrames-1; i++)
{
filteredTrajectory[i][j] = filter (Ycoordinates[i][j]);
}
reset_buffer();
}
}
// Filter along rows, similar to Matlab's filter(coefficients, 1, data, [], 2)
void filterDim2()
{
for (int i = 0; i<numFrames-1; i++)
{
filteredTrajectory[i].resize(featuresPrevious.size());
for (int j = 0; j<featuresPrevious.size(); j++)
{
filteredTrajectory[i][j] = filter (Ycoordinates[i][j]);
}
reset_buffer();
}
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]