bool imgProcess::deNoiseTem(Mat src, Mat &dst)
{
temImg.push_back(src);
dst = src.clone();
if (temImg.size() < 2)
{
return false;
}
else
{
int dstHeight = dst.rows;
int dstWith = dst.cols;
float weight[2] = { 0 };
for (int h = 0; h < dstHeight; h++)
{
for (int w = 0; w < dstWith; w++)
{
int Sad = 0 ;
Sad = abs(temImg[0].at<Vec3b>(h, w)[0] - src.at<Vec3b>(h, w)[0])
+ abs(temImg[0].at<Vec3b>(h, w)[1] - src.at<Vec3b>(h, w)[1])
+ abs(temImg[0].at<Vec3b>(h, w)[2] - src.at<Vec3b>(h, w)[2]);
weight[0] = 0.5f * (1.f * Sad / MAX_SAD_THRESH);
weight[0] = weight[0] > 0.5f ? 0.5f : weight[0];
weight[0] = 0.5f - weight[0];
weight[1] = 1 - weight[0];
for (int i = 0; i < 3; i++)
{
dst.at<Vec3b>(h, w)[i] = 0;
dst.at<Vec3b>(h, w)[i] = static_cast<unsigned char>(
weight[0] * temImg[0].at<Vec3b>(h, w)[i]
+ weight[1] * src.at<Vec3b>(h, w)[i]);
}
}
}
temImg.pop_back();
temImg.push_back(dst);// update the last element to the filtered;
vector<Mat>::iterator k = temImg.begin();
temImg.erase(k);//删除第一个元素
}
return true;
}
时域去噪思想:
- 计算前一帧与当前帧的像素差和, 即三通道绝对差的和作为距离标准;
- 当前帧像素由前一帧和当前帧的加权和得到;
- 上一帧的权值最大为0.5;
- 上一帧的权值由SAD(sum of absolute difference)和差值阈值MAX_SAD_THRESH决定;
- 当前帧的输出计算结果(时域滤波后)进入vector, 作为下一帧的参考帧;
注意点:
- 时域滤波只利用了2帧,不需要更多的前帧信息,这是因为时域滤波结果作为下一帧的输入,对未来帧的影响一直在,只是影响会越来越小;
- 当前帧的权值设置至少为0.5, 如果再小, 可能会出现拖影现象;
- MAX_SAD_THRESH不可以过大,否则也会出现拖影现象,比如,MAX_SAD_THRESH为50时, sad计算结果为40, 那么上一帧的权值为w0 = 0.5 - 0.5 * (40 / 50) = 0.1; 当 MAX_SAD_THRESH为100,w0 = 0.3; 很明显,sad为40时(个人认为比较大了), 为了不产生拖影,肯定更小的MAX_SAD_THRESH(50)更合适;
- 当sad 为MAX_SAD_THRESH时, 上一帧权值为0, 当sad = 0时, 上一帧和当前帧的权值都为0.5;
去噪前后的结果对比如下的GIF,一开始是未去噪,点击denoise后明细噪声变少!