视频的时域去噪

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;
}

时域去噪思想:

  1. 计算前一帧与当前帧的像素差和, 即三通道绝对差的和作为距离标准;
  2. 当前帧像素由前一帧和当前帧的加权和得到;
  3. 上一帧的权值最大为0.5;
  4. 上一帧的权值由SAD(sum of absolute difference)和差值阈值MAX_SAD_THRESH决定;
  5. 当前帧的输出计算结果(时域滤波后)进入vector, 作为下一帧的参考帧;

注意点:

  1. 时域滤波只利用了2帧,不需要更多的前帧信息,这是因为时域滤波结果作为下一帧的输入,对未来帧的影响一直在,只是影响会越来越小;
  2. 当前帧的权值设置至少为0.5, 如果再小, 可能会出现拖影现象;
  3. 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)更合适;
  4. 当sad 为MAX_SAD_THRESH时, 上一帧权值为0, 当sad = 0时, 上一帧和当前帧的权值都为0.5;

去噪前后的结果对比如下的GIF,一开始是未去噪,点击denoise后明细噪声变少!

猜你喜欢

转载自blog.csdn.net/myzhouwang/article/details/84708599