相关文章推荐
性感的黄豆  ·  python ...·  1 月前    · 
风流的奔马  ·  luajit 64位 for ...·  1 年前    · 
尝试用刀刃法计算MTF

尝试用刀刃法计算MTF

高等数学没学好,使用网上的源码跑了一遍,尝试理解MTF计算过程。

ROI图片选取一个60*30的区域

数据归一化

gamma处理的原因是人眼对暗色更敏感,但是亮度只能存0~255,所以我们希望挤压量的部分,多存一点暗的部分。没错,就是 非线性存储。

硬盘上存的美图照片都是“偏亮的”

如果是直接取的raw图,就不需要做这个处理了(我下面的图片数据没有做gamma处理)。

图片数据

对应图片原始数据,这里用excel色阶功能做了下处理。

表格中取值为Blue通道(这里是调试时候为了图省事弄的,后面应该要取灰度值算最终的MTF)

找准确的刃边(找重心的方式)

// 求质心C
	// C = Σx*(f(x+1)-f(x))/Σ(f(x+1)-f(x))
	for (j = 0; j < size_y; j++)
		dt = 0.0;
		dt1 = 0.0;
		for (i = 0; i < size_x - 1; i++)
			dt2 = farea[(j * (long)size_x) + (i + 1)] - farea[(j * (long)size_x) + i];  // 计算每个点的导数
			dt += dt2 * (double)i; // 
			dt1 += dt2;
		shifts[j] = dt / dt1; // 质心
	}

找质心的目的是为了拟合“黑白分界线”。

计算“刀刃”的直线

// 线性回归 y = a + bx
unsigned short SfrDataProces::fit(unsigned long ndata, double* x, double* y, double* b, double* a, double* R2, double* avar, double* bvar)
	unsigned long i;
	double t, sxoss, syoss, sx = 0.0, sy = 0.0, st2 = 0.0;
	double ss, sst, sigdat, chi2, siga, sigb;
	*b = 0.0;
	for (i = 0; i < ndata; i++)
		sx += x[i];
		sy += y[i];
	ss = (double)ndata;
	sxoss = sx / ss;
	syoss = sy / ss;
	for (i = 0; i < ndata; i++)
		t = x[i] - sxoss;
		st2 += t * t;
		*b += t * y[i];
	*b /= st2;         /* slope  */
	*a = (sy - sx * (*b)) / ss; /* intercept */
	siga = sqrt((1.0 + sx * sx / (ss * st2)) / ss);
	sigb = sqrt(1.0 / st2);
	chi2 = 0.0;
	sst = 0.0;
	for (i = 0; i < ndata; i++) {
		chi2 += SQR(y[i] - (*a) - (*b) * x[i]);
		sst += SQR(y[i] - syoss);
	sigdat = sqrt(chi2 / (ndata - 2));
	siga *= sigdat;