我用下面的代码一些噪音添加到图像时确定的模板类型(直出的OpenCV参考,449页 - 的cv::Mat::begin
说明):访问OpenCV的垫块元件
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
对象和在输入图像0123键入- 迭代
- 在每个位置,从
in
挑从noise
的随机值(my_rand(int n)
返回一个随机数在[0..n-1]
- 总和像素与随机噪声值
- 就把求和结果转换成
out
我不喜欢这样的代码,因为下面的说法似乎不可避免:
typedef cv::Vec<unsigned char, 3> V4;
它具有硬编码的两件事情:
- 的图像有3个渠道
- 通道深度为8bpp的
如果我得到这个错误typedef
(例如通道深度错误或通道数量错误),那么我的程序段错误。我最初使用typedef cv::Vec<unsigned char, 4> V4
来处理任意数量的通道(最大OpenCV支持4)的图像,但这导致了段错误。
有没有什么办法可以避免硬编码上述两件事?理想情况下,我想要的东西是一样的:
typedef cv::Vec<in.type(), in.size()> V4;
感谢您的回复。我可能最终会使用像你提到的行指针,但我有点说,看到迭代器去,因为这是使用它们的理想场所。此外,即使我模板函数,我仍然必须在编译时指定它的类型名称,这实际上只是将问题移到代码中的另一个点。也许我有点愤世嫉俗,但对我来说,在编译时指定这些信息似乎首先会失去模板和多态性的观点。 – misha 2011-01-20 10:12:05
它不会“只是”移动问题 - 如果你没有模板功能,你必须复制整个代码的类型。另外,你的根本问题是你试图在不知道它包含什么的情况下对图像进行操作,并且注定会失败(例如,对于整数值图像需要不同的噪声而不是实值图像。 ,如果generate_noise返回平均值为0的高斯噪声,那么噪声会产生一个偏差,使图像变暗(因为整数舍入_down_) – etarion 2011-01-20 10:27:17