最近在研究对于显微镜图像自动聚焦的方法,使用的是爬坡法进行显微镜聚焦的对于图像的评价函数查阅了相关的资料,
在百度文库找到的资料还是不错的,点击打开链接
常用的图像聚焦算法还是很全的,关键是用用程序如何实现:
代码写出来后很简单:
m_img = cvLoadImage(CT2CA(ary_filename.GetAt(i)));
cvAvgSdv(m_img,&u,&imgSdv);
CString imgSdvStr;
double FX = (imgSdv.val[0]+imgSdv.val[1]+imgSdv.val[2])/3;
if (FX > m_dResult)
{
m_dResult = FX;
m_Paht = ary_filename.GetAt(i);
}
对于这中聚焦方法,直接遍历像素中的数据,求两个邻域的差分和即可
double FX = 0;
m_img = cvLoadImage(CT2CA(ary_filename.GetAt(i)));
for (int j = 0 ; j < m_img->height-1 ; j++)
{
for (int k = 0 ; k < m_img->width-1; k=k+4)
{
FX +=fabs((double)(((uchar*)(m_img->imageData + m_img->widthStep * j))[k]-((uchar*)(m_img->imageData + m_img->widthStep * j))[k+4]))
+ fabs((double)(((uchar*)(m_img->imageData + m_img->widthStep * j))[k]-((uchar*)(m_img->imageData + m_img->widthStep * (j+1)))[k]));
}
}
// CString RE;
// RE.Format(_T("%f"),FX);
// MessageBox(RE);
if (FX > m_dResult)
{
m_dResult = FX;
m_Paht = ary_filename.GetAt(i);
}
Release();
思路与以上一致,就是公式不一样
double FX = 0;
m_img = cvLoadImage(CT2CA(ary_filename.GetAt(i)));
for (int j = 0 ; j < m_img->height-1 ; j++)
{
for (int k = 0 ; k < m_img->width-1; k=k+4)
{
FX +=fabs((double)(((uchar*)(m_img->imageData + m_img->widthStep * j))[k]-((uchar*)(m_img->imageData + m_img->widthStep * (j+1)))[k+4]))
+ fabs((double)(((uchar*)(m_img->imageData + m_img->widthStep * j))[k+4]-((uchar*)(m_img->imageData + m_img->widthStep * (j+1)))[k]));
}
}
if (FX > m_dResult)
{
m_dResult = FX;
m_Paht = ary_filename.GetAt(i);
}
Release();
思路一致,就是按照公式来呗~
m_img = cvLoadImage(CT2CA(ary_filename.GetAt(i)));
for (int j = 1 ; j < m_img->height-1 ; j++)
{
for (int k = 1 ; k < m_img->width-1; k=k+4)
{
int Sx = (int)(uchar*)(m_img->imageData + m_img->widthStep * (j-1))[k+4]
+ (int)(uchar*)(m_img->imageData + m_img->widthStep * (j+1))[k+4]
- (int)(uchar*)(m_img->imageData + m_img->widthStep * (j-1))[k-4]
- (int)(uchar*)(m_img->imageData + m_img->widthStep * (j+1))[k-4]
+2*(int)(uchar*)(m_img->imageData + m_img->widthStep * j )[k+4]
-2*(int)(uchar*)(m_img->imageData + m_img->widthStep * j )[k-4];
int Sy = (int)(uchar*)(m_img->imageData + m_img->widthStep * (j+1))[k-4]
+(int)(uchar*)(m_img->imageData + m_img->widthStep * (j+1))[k+4]
-(int)(uchar*)(m_img->imageData + m_img->widthStep * (j-1))[k-4]
-(int)(uchar*)(m_img->imageData + m_img->widthStep * (j-1))[k+4]
+2*(int)(uchar*)(m_img->imageData + m_img->widthStep * (j+1))[k]
-2*(int)(uchar*)(m_img->imageData + m_img->widthStep * (j-1))[k] ;
FX = sqrtl(Sx*Sx + Sy*Sy);
}
}
下面就是能能量频谱的方法了.感觉对于显微镜聚焦的效果不好,就不讲了~
还有一种是文中提出的方法,使用拉普拉斯算子,并增加了两个阈值;
double FX = 0.0;
double temp = 0.0;
m_img = cvLoadImage(CT2CA(ary_filename.GetAt(i)));
for (int j = m_step ; j < m_img->height-m_step ; j++)
{
for (int k = m_step*4 ; k < m_img->width-m_step*4; k=k+4)
{
temp = fabs((double)(2*(int)((uchar*)(m_img->imageData + m_img->widthStep * (j))[k])
- (int)((uchar*)(m_img->imageData + m_img->widthStep * (j))[k-4*m_step])
- (int)((uchar*)(m_img->imageData + m_img->widthStep * (j))[k+4*m_step])))
+ fabs( (double)(2*(int)((uchar*)(m_img->imageData + m_img->widthStep * (j))[k])
- (int)((uchar*)(m_img->imageData + m_img->widthStep * (j-m_step))[k])
- (int)((uchar*)(m_img->imageData + m_img->widthStep * (j+m_step))[k])));
if (temp >= m_T)
{
FX += temp;
}
}
}
本文的相关程序是使用VC2010编写的,
源代码下载;http://download.csdn.net/detail/cc7829290/5303830
可能需要重新配置openCV路径才能重新编译
演示程序下载:http://download.csdn.net/detail/cc7829290/5303852
在没有安装openCV的电脑上可以使用
水平有限,有更好的聚焦方法,欢迎交流~~