全變分(TV)模型原理與C++實現

本文介紹了TV模型的基本原理,並給出了C++代碼實現。

一、TV模型原理

















二、C++實現

關於Matlab的程序實現,有一個經典的主頁: http://visl.technion.ac.il/~gilboa/PDE-filt/tv_denoising.html

有博主改成了C++代碼:見經典的變分法圖像去噪的C++實現

另有博主改成了更簡潔的版本:見【圖像處理】全分發TV圖像去噪

但精簡版的有個問題:image[i][j] += dt*(tmp_num/tmp_den+ lam*(image0[i][j] - image[i][j])); 

直接在image中迭代,這有問題,最後得到的去噪圖像跟MATLAB得到的去噪圖像有細微差別,對兩幅圖像做差值可發現差別。

本文代碼基本參照上面的版本,把代碼修改爲(之前公式有誤,已修改 2015年4月23日):

void CImageObj::Total_Variation(int iter, double dt, double epsilon, double lambda)
{
	int i, j;
	int nx = m_width, ny = m_height;
	double ep2 = epsilon * epsilon;

	double** I_t = NewDoubleMatrix(nx, ny);
	double** I_tmp = NewDoubleMatrix(nx, ny);
	for (i = 0; i < ny; i++)
		for (j = 0; j < nx; j++)
			I_t[i][j] = I_tmp[i][j] = (double)m_imgData[i][j];

	for (int t = 0; t < iter; t++)
	{
		for (i = 0; i < ny; i++)
		{
			for (j = 0; j < nx; j++)
			{
				int iUp = i - 1, iDown = i + 1;
				int jLeft = j - 1, jRight = j + 1;    // 邊界處理
				if (0 == i) iUp = i; if (ny - 1 == i) iDown = i;
				if (0 == j) jLeft = j; if (nx - 1 == j) jRight = j;

				double tmp_x = (I_t[i][jRight] - I_t[i][jLeft]) / 2.0;
				double tmp_y = (I_t[iDown][j] - I_t[iUp][j]) / 2.0;
				double tmp_xx = I_t[i][jRight] + I_t[i][jLeft] - 2 * I_t[i][j];
				double tmp_yy = I_t[iDown][j] + I_t[iUp][j] - 2 * I_t[i][j];
				double tmp_xy = (I_t[iDown][jRight] + I_t[iUp][jLeft] - I_t[iUp][jRight] - I_t[iDown][jLeft]) / 4.0;
				double tmp_num = tmp_yy * (tmp_x * tmp_x + ep2) + tmp_xx * (tmp_y * tmp_y + ep2) - 2 * tmp_x * tmp_y * tmp_xy;
				double tmp_den = pow(tmp_x * tmp_x + tmp_y * tmp_y + ep2, 1.5);

				I_tmp[i][j] += dt*(tmp_num / tmp_den + lambda*(m_imgData[i][j] - I_t[i][j]));
			}
		}  // 一次迭代

		for (i = 0; i < ny; i++)
			for (j = 0; j < nx; j++)
			{
				I_t[i][j] = I_tmp[i][j];
			}

	} // 迭代結束

	// 給圖像賦值
	for (i = 0; i < ny; i++)
		for (j = 0; j < nx; j++)
		{
			double tmp = I_t[i][j];
			tmp = max(0, min(tmp, 255));
			m_imgData[i][j] = (unsigned char)tmp;
		}

	DeleteDoubleMatrix(I_t, nx, ny);
	DeleteDoubleMatrix(I_tmp, nx, ny);
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章