Я использую следующий код для добавления шума к изображению (прямо из ссылки на OpenCV, стр. 449 - объяснение cv::Mat::begin
):
void
simulate_noise(Mat const &in, double stddev, Mat &out)
{
cv::Size s = in.size();
vector<double> noise = generate_noise(s.width*s.height, stddev);
typedef cv::Vec<unsigned char, 3> V4;
cv::MatConstIterator_<V4> in_itr = in.begin<V4>();
cv::MatConstIterator_<V4> in_end = in.end<V4>();
cv::MatIterator_<V4> out_itr = out.begin<V4>();
cv::MatIterator_<V4> out_end = out.end<V4>();
for (; in_itr != in_end && out_itr != out_end; ++in_itr, ++out_itr)
{
int noise_index = my_rand(noise.size());
for (int j = 0; j < 3; ++j)
(*out_itr)[j] = (*in_itr)[j] + noise[noise_index];
}
}
Ничего слишком сложного:
in
и out
выделяются cv::Mat
объекты одинаковых размеров и типа - итерируют по входному изображению
in
- в каждой позициивыберите случайное значение из
noise
(my_rand(int n)
возвращает случайное число в [0..n-1]
- , суммируйте пиксель из
in
со значением случайного шума - , поместите результат суммирования в
out
Мне не нравится этот код, потому что следующее утверждение кажется неизбежным:
typedef cv::Vec<unsigned char, 3> V4;
В нем жестко заданы две вещи:
- Изображения имеют 3 канала
- Глубина канала 8bpp
Если я получу typedef
неправильно (например, неверная глубина канала или неправильное количество каналов), то моя программаsegfaults. Первоначально я использовал typedef cv::Vec<unsigned char, 4> V4
для обработки изображений с произвольным числом каналов (максимальный OpenCVsupport - это 4), но это вызвало ошибку segfault.
Можно ли как-то избежать жесткого кодирования двух вещей выше?В идеале я хочу что-то общее, как:
typedef cv::Vec<in.type(), in.size()> V4;