Сглаживание гистограммы - PullRequest
2 голосов
/ 02 июля 2010

У меня, вероятно, довольно простой вопрос, но я все еще не уверен!

На самом деле я хочу только сгладить гистограмму, и я не уверен, какой из следующих методов верен.Буду ли я делать это так:

vector<double> mask(3);
mask[0] = 0.25; mask[1] = 0.5; mask[2] = 0.25;

vector<double> tmpVect(histogram->size());
for (unsigned int i = 0; i < histogram->size(); i++)
  tmpVect[i] = (*histogram)[i];

for (int bin = 1; bin < histogram->size()-1; bin++) {
  double smoothedValue = 0;
  for (int i = 0; i < mask.size(); i++) {
    smoothedValue += tmpVect[bin-1+i]*mask[i];
  }
  (*histogram)[bin] = smoothedValue;
}

Или вы обычно делаете это так?:

vector<double> mask(3);
mask[0] = 0.25; mask[1] = 0.5; mask[2] = 0.25;

for (int bin = 1; bin < histogram->size()-1; bin++) {
  double smoothedValue = 0;
  for (int i = 0; i < mask.size(); i++) {
    smoothedValue += (*histogram)[bin-1+i]*mask[i];
  }
  (*histogram)[bin] = smoothedValue;
}

Мой квест: есть ли смысл копировать гистограмму в дополнительном векторево-первых, чтобы при сглаживании по бин i я мог использовать исходное значение i-1 или просто smoothedValue += (*histogram)[bin-1+i]*mask[i];, чтобы вместо уже использованного сглаженного i-1 использовалось исходное значение.

С уважением и спасибо за ответ.

1 Ответ

3 голосов
/ 02 июля 2010

Ваша интуиция права: вам нужен временный вектор. В противном случае вы в конечном итоге будете использовать частично старые значения и частично новые значения, и результат будет неверным. Попробуйте сами на бумаге с простым примером.

Существует два способа написания этого алгоритма:

  1. Сначала скопируйте данные во временный вектор; затем прочитайте и напишите histogram. Это то, что вы сделали в своем первом фрагменте кода.
  2. Чтение из histogram и запись во временный вектор; затем скопируйте из временного вектора обратно в histogram.

Чтобы предотвратить ненужное копирование данных, вы можете использовать vector::swap. Это чрезвычайно быстрая операция, которая меняет содержимое двух векторов. Используя приведенную выше стратегию 2, это приведет к:

vector<double> mask(3);
mask[0] = 0.25; mask[1] = 0.5; mask[2] = 0.25;

vector<double> newHistogram(histogram->size());

for (int bin = 1; bin < histogram->size()-1; bin++) {
  double smoothedValue = 0;
  for (int i = 0; i < mask.size(); i++) {
    smoothedValue += (*histogram)[bin-1+i]*mask[i];
  }
  newHistogram[bin] = smoothedValue;
}

histogram->swap(newHistogram);
...