前面一篇,花费了很大力气的代码来实现显示一幅bmp图像和感兴趣区域(ROI)图像截取,它是值得的,因为你不能光说不练。借这个东风,自动对焦的代码如下:
int[,] 差分图像x = new int[_RoiH, _RoiW];//感兴趣区域(ROI)的高度和宽度
int[,] 差分图像y = new int[_RoiH, _RoiW];
int[,] 梯度图像 = new int[_RoiH, _RoiW];
for (int i = 0; i < (_RoiH - 1); i++)
{
for (int j = 0; j < (_RoiW - 1); j++)
{
int n0 = (i * _RoiW + j);//感兴趣区域(ROI)截取的图像
差分图像x[i, j] = Math.Abs(tempImage3[n0] - tempImage3[n0 + 1]);//横向两个相邻像素做差取绝对值
差分图像y[i, j] = Math.Abs(tempImage3[n0] - tempImage3[n0 + _RoiW]);//纵向两个相邻像素做差取绝对值
}
}
for (int i = 0; i < _RoiH - 1; i++)
{
for (int j = 0; j < _RoiW - 1; j++)
{
梯度图像[i, j] = 差分图像x[i, j] + 差分图像y[i, j];//不要被名字挡住去路,继续
梯度图像[i, j] = 梯度图像[i, j] > 255 ? 255 : 梯度图像[i, j];
}
}
for (int i = 0; i < _RoiW; i++)//有一行未处理
{
梯度图像[0, i] = 0;
梯度图像[_RoiH - 1, i] = 0;
}
for (int j = 0; j < _RoiH; j++)//有一列未处理
{
梯度图像[j, 0] = 0;
梯度图像[j, _RoiW - 1] = 0;
}
//求和梯度图
long msum = 0;
for (int j = 0; j < _RoiH; j++)
for (int i = 0; i < _RoiW; i++)
{
msum += 梯度图像[j, i];
}
Msum.Text = msum.ToString();//这个结果就能测量感兴趣区域的清晰度
在此,你是否看到两个像素做差的巨大威力?当你总结后,他还隐藏了另一种巨大的威力,我们在谈线图像时,再说。若能与我心而戚戚焉,那么你就远远超过了我,我几年后才回过头看到。
前面谈到感兴趣区域是W*H(长*高)的一个矩形,那么他截取的图像是W(列)*H(行),即roi矩形和ROI图像是一一对应的。
常说的感兴趣区域(ROI)实质指这两层意思,这很重要。下面做一个变化,当你习惯了一种模式,而要做出改变时,是很难的,因为你想不到。如果你想到了,这便是新生。
如果h==1,那么你的感兴趣区域(ROI)就变成一行W(列)的图像了,我们给他一个名字,线图像。他包含了两层意思,一条线,一条图像。
我们前面设计的感兴趣区域(ROI)实质可以由这条线图像拉长变宽,移动带走。是否感到他有点像孙大圣的金箍棒。感兴趣区域除了能截取图像,还能干什么?我们同样在拷问线图像。
a,像孙大圣一样,让他旋转起来,当下只有拉长变宽,移动。
b,线图像还不能感知图像颜色灰度的变化。即感知能力。
c,隐藏了另一种巨大的威力。
(待续..............)下面是自动对焦效果: