mpe*_*kov 6 c++ opencv iterator image-processing
我正在使用以下代码为图像添加一些噪声(直接来自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];
}
}
Run Code Online (Sandbox Code Playgroud)
没有什么过于复杂:
in并out分配cv::Mat相同尺寸和类型的对象innoise(my_rand(int n)返回一个随机数)[0..n-1]in与随机噪声值相加out我不喜欢这段代码,因为下面的陈述似乎是不可避免的:
typedef cv::Vec<unsigned char, 3> V4;
Run Code Online (Sandbox Code Playgroud)
它有两个硬编码:
如果我typedef弄错了(例如错误的频道深度或错误的频道数),那么我的程序会出现段错误.我最初用于typedef cv::Vec<unsigned char, 4> V4处理具有任意数量通道的图像(OpenCV支持的最大值为4),但这会导致段错误.
有什么办法可以避免硬编码上面的两件事吗?理想情况下,我想要一些通用的东西:
typedef cv::Vec<in.type(), in.size()> V4;
Run Code Online (Sandbox Code Playgroud)
我知道这来晚了。但是,真正解决您问题的方法是使用 OpenCV 功能来做您想做的事情。
cv::Mat_<double>(noise);out = in + noise;或cv::add(in, noise, out);这种方法的另一个优点是 OpenCV 可能会使用多线程、SSE 或其他方法来加速这种大规模元素操作,而您却没有。您的代码更简单、更干净,而且 OpenCV 会为您完成所有讨厌的类型处理。
问题是您需要在运行时确定通道的类型和数量,但模板在编译时需要这些信息。cv::split您可以通过使用和cv::merge或将迭代更改为来避免对通道数进行硬编码
for(int row = 0; row < in.rows; ++row) {
unsigned char* inp = in.ptr<unsigned char>(row);
unsigned char* outp = out.ptr<unsigned char>(row);
for (int col = 0; col < in.cols; ++col) {
for (int c = 0; c < in.channels(); ++c) {
*outp++ = *inp++ + noise();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您想摆脱类型的依赖性,我建议将上述内容放入模板化函数中,并根据矩阵的类型从您的函数中调用它。
| 归档时间: |
|
| 查看次数: |
5163 次 |
| 最近记录: |