数码相机照出来的照片,有什么办法可以判断是否对焦了呢? ( 积分: 100 )

  • 主题发起人 主题发起人 tsedlinux
  • 开始时间 开始时间
T

tsedlinux

Unregistered / Unconfirmed
GUEST, unregistred user!
数码相机照出来的照片 怎么能够判断照片没有散焦呢? 是什么原理呢 或是算法
 
应该没办法,数码相机都是用光学的办法。如果能用从照片判断是否对焦,那可是世界首创,可以广泛应用于数码相机、摄像机等电子光学领域。
 
楼上“KaiDa”都发话了,应该是没机会了。呵呵。
不过我的想法是要先确定焦点,然后对比焦点和周片区域的参数来判断该位置是否对准焦点。
 
有算法用于评估数码图像的对焦准确程度的,请看:
http://article.ednchina.com/2006-05/2006591240491.htm
算法很简单——计算相邻像素的亮度差值的平方和:一帧图像的数据采集都完成后,将每
一行像素的亮度差值平方和累加,就得到这一帧图像的调焦评价函数。
当然,为了对已经拍摄完成的图像进行评估,不可避免的要对图像进行分块评估,然后才
有可能得到准确的评价(因为不同的图片的评估函数值几乎不具备可比性!)。
 
2.2 优化的搜索算法

本系统采用了一种优化的爬山搜索算法。控制策略为:先根据整个行程的调焦评价函数值,获得调焦评价函数与步进电机行程的关系曲线,从曲线上可以判断选择最大的步进电机步长。在判断选择时,既要保证不会错过调焦评价函数的最大值区域,同时又要满足以最少的步数走完全程。在获得全程最大调焦评价函数区域后,将步进电机步长减小,在最大值区域内进一步搜索更精确的对焦位置。采用这一策略,既不会发生误判或找不到对焦点的情况,又能以较快的速度进行对焦。软件设计为:电机驱动镜头从起始位置出发,先以等步长走一遍全程,记录下调焦评价函数最大值时的镜头位置,然后镜头回到调焦评价函数最大值位置的前一站,换用小步长,从调焦评价函数最大值位置的前一站走到最大值位置的后一站,记录下这一全程的调焦评价函数最大值时的镜头位置,如此反复搜索,最后镜头停止在调焦评价函数最大值处,使系统实现正确对焦。采用这一方法,既可以避免电机盲目反转,又能确保系统找到正确的对焦点,而且搜索历程短,有利于快速对焦。

3 自动对焦实验结果

在聚焦镜头的移动过程中,调焦评价函数值的变
化规律是由小到大再减小,与此同时图像显示经历了从模糊到清晰再到模糊的过程。对于不同的变焦倍率,调焦评价函数的变化规律相同。在聚焦镜头的整个行程中,能够找到一个显著的最大值,这个最大值的位置与图像最清晰的位置是相对应的;在最大值的两端,数值减小得非常快,然后数值趋于稳定。

在优化的爬山搜索算法中,选取最大步长要以调焦评价函数的变化趋势为依据。在本系统中选择最大步长为30H,这样总能测到一个最大值或两个次大值中的一个数据,在第二次搜索时就一定能找到调焦评价函数的最大值
 
初始化工作完成后,系统进入数据采集和计算阶段,根据数字图像传感器提供的场同步、行同步和像素时钟等时序信号,可以方便地选取不同的对焦窗口采集数据。采集完成后,马上计算相邻像素的亮度差值的平方和,并保存到TMS320F206的RAM中。由于TMS320F206提供的重复执行指令极大地节约了运算时间,因此一行数据的差值运算根据采集窗口的不同可在一至两行的时间内完成。一帧图像的数据采集都完成后,将每一行像素的亮度差值平方和累加,就得到这一帧图像的调焦评价函数。
 
马上计算相邻像素的亮度差值的平方和
将每一行像素的亮度差值平方和累加,就得到这一帧图像的调焦评价函数。
这块不太明白 相邻像素?
1234567
假设某行(第N行)像素如上述字符串所示
是否要计算(第N行)=(2-1)^2+(3-2)^2+.........(7-6)^2
N1+N2+.....Nn=调焦评价函数
是这样么?
有没有代码可以参考一下呢
我对图像处理这块没学过
另外如何才能取到图像的亮度值? 需要转成黑白图么?
谢谢
 
(((
当然,为了对已经拍摄完成的图像进行评估,不可避免的要对图像进行分块评估,然后才
有可能得到准确的评价(因为不同的图片的评估函数值几乎不具备可比性!)。
)))
这个问题 我可以尝试图像的重复的采集 即对一个场景在不同的对焦位置进行采集 也是用步进电机来调焦
 
如果你可以控制步进电机,那就一切OK了:) [:D]
 
一个画面,有不同景深,到底是对焦最近的景物,还是最远的,这是很主观的,一般
对画面中央的景物,如果能操纵镜头,先摄远中近三幅图,并去中央的一个范围进行
来对比,可以肯定,对焦较好的一幅比散焦的更清晰,意味着其的颜色数更丰富,因
为画面模糊,像素颜色变化就会不大,所以通过反复采样,一定能够得到对焦最好的
画面,遗憾的是,这很难实时进行,所以相机的自动对焦都不是这样做的。
 
像机的自动对焦是有个AF灯 相机是用它实现的
便我所用的SONY DSR PD150P摄像机它实现的对焦方法应该是依据如creation-zy兄所说的方法吧或者是相类似的
 
来自:chuguozhen, 时间:2002-10-1 22:23:00, ID:1357197
以下是c++代码,改成Delphi的应该很容易的
void Form1::DoContrast(int s)//调整对比度
{
int XX;
BYTE *ptr;
Graphics::TBitmap *tmpBitmap=new Graphics::TBitmap();
tmpBitmap->Assign((TPersistent*)Image->Picture->Graphic);
tmpBitmap->PixelFormat=pf24bit;
for (int y = 0; y < tmpBitmap->Height; y++)
{
ptr =(BYTE *) tmpBitmap->ScanLine[y];
for (int x = 0; x < tmpBitmap->Width*3; x+=3){
XX=((ptr[x+2]-128)*s+12800)/100;
XX=MAX(XX,0);XX=MIN(XX,255);ptr[x+2]=XX;
XX=((ptr[x+1]-128)*s+12800)/100;
XX=MAX(XX,0);XX=MIN(XX,255);ptr[x+1]=XX;
XX=((ptr[x]-128)*s+12800)/100;
XX=MAX(XX,0);XX=MIN(XX,255);ptr[x+0]=XX;
}
}
Image->Picture->Graphic=tmpBitmap;
delete tmpBitmap;

}
//---------------------------------------------------------------------------
void TMainForm::DoBright(int b)//调整亮度
{
int XX;
BYTE *ptr;
Graphics::TBitmap *tmpBitmap=new Graphics::TBitmap();
tmpBitmap->Assign((TPersistent*)Image->Picture->Graphic);
tmpBitmap->PixelFormat=pf24bit;
for (int y = 0; y < tmpBitmap->Height; y++)
{
ptr =(BYTE *) tmpBitmap->ScanLine[y];
for (int x = 0; x < tmpBitmap->Width*3; x+=3){
XX=ptr[x+2]+b;
XX=MAX(XX,0);XX=MIN(XX,255);ptr[x+2]=XX;
XX=ptr[x+1]+b;
XX=MAX(XX,0);XX=MIN(XX,255);ptr[x+1]=XX;
XX=ptr[x]+b;
XX=MAX(XX,0);XX=MIN(XX,255);ptr[x+0]=XX;
}
}
Image->Picture->Graphic=tmpBitmap;
delete tmpBitmap;
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::N12Click(TObject *Sender)//调整色彩平衡
{
int XX;
BYTE *ptr;
Graphics::TBitmap *tmpBitmap=new Graphics::TBitmap();
tmpBitmap->Assign((TPersistent*)Image->Picture->Graphic);
tmpBitmap->PixelFormat=pf24bit;
Form2->TrackBar1->Position=0;
Form2->TrackBar2->Position=0;
Form2->TrackBar3->Position=0;

if (Form->ShowModal()==IDOK){
for (int y = 0; y < tmpBitmap->Height; y++)
{
ptr =(BYTE *) tmpBitmap->ScanLine[y];
for (int x = 0; x < tmpBitmap->Width*3; x+=3){
XX=ptr[x+2]+CForm->TrackBar1->Position;
XX=MAX(XX,0);XX=MIN(XX,255);ptr[x+2]=XX;
XX=ptr[x+1]+CForm->TrackBar2->Position;
XX=MAX(XX,0);XX=MIN(XX,255);ptr[x+1]=XX;
XX=ptr[x]+CForm->TrackBar3->Position;
XX=MAX(XX,0);XX=MIN(XX,255);ptr[x+0]=XX;
}
}
Image->Picture->Graphic=tmpBitmap;
}
delete tmpBitmap;
}
//---------------------------------------------------------------------------
void __fastcall Form1::BlurButtonClick(TObject *Sender)//模糊效果,也应该是柔化吧
{
int flt[9];
flt[0]=5;flt[1]=5;flt[2]=5;
flt[3]=5;flt[4]=60;flt[5]=5;
flt[6]=5;flt[7]=5;flt=5;
DoFilter(flt,100);
}
//---------------------------------------------------------------------------


void Form1::DoFilter(int * flt, int Div)
{
int XX[3];
BYTE *ptr,*ptru,*ptrd,*ptr1;
Graphics::TBitmap *Bitmap=new Graphics::TBitmap();
Graphics::TBitmap *tmpBitmap=new Graphics::TBitmap();
Bitmap->Assign((TPersistent*)Image->Picture->Graphic);
Bitmap->PixelFormat=pf24bit;
tmpBitmap->Assign((TPersistent*)Image->Picture->Graphic);
tmpBitmap->PixelFormat=pf24bit;
for (int y = 1; y < tmpBitmap->Height-1; y++)
{
ptr=(BYTE *)Bitmap->ScanLine[y];
ptr1=(BYTE *)tmpBitmap->ScanLine[y];
ptru=(BYTE *)tmpBitmap->ScanLine[y-1];
ptrd=(BYTE *)tmpBitmap->ScanLine[y+1];
for (int x=3;x<(tmpBitmap->Width-1)*3;x+=3){
XX[0]=0;XX[1]=0;XX[2]=0;
for (int i=-1;i<=1;i++)
for (int j=0;j<3;j++)
XX[j]+=ptr1[x+3*i+j]*flt[4+i];
for (int i=-1;i<=1;i++)
for (int j=0;j<3;j++)
XX[j]+=ptru[x+3*i+j]*flt[1+i];
for (int i=-1;i<=1;i++)
for (int j=0;j<3;j++)
XX[j]+=ptrd[x+3*i+j]*flt[7+i];
for (int i=0;i<3;i++){
XX=XX/Div;
XX=MAX(XX,0);
XX=MIN(XX,255);
ptr[x+i]=XX;
}
}
}
Image->Picture->Graphic=Bitmap;
delete tmpBitmap;
delete Bitmap;
}

void __fastcall Form1::SharpButtonClick(TObject *Sender)//锐化效果处理
{
int flt[9];
flt[0]=0;flt[1]=-5;flt[2]=0;
flt[3]=-5;flt[4]=30;flt[5]=-5;
flt[6]=0;flt[7]=-5;flt=0;
DoFilter(flt,10);
}
//---------------------------------------------------------------------------


void __fastcall TMainForm::EnchaseButtonClick(TObject *Sender)//雕刻效果处理
{
int flt[9];
flt[0]=-15;flt[1]=-15;flt[2]=0;
flt[3]=-15;flt[4]=15;flt[5]=15;
flt[6]=0;flt[7]=15;flt=0;
DoFilter(flt,10);
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::P1Click(TObject *Sender)
{
float AspectRatio,OutputWidth, OutputHeight;
if (!PrintDialog1->Execute()) return;
Printer()->BeginDoc();
OutputWidth = Image->Picture->Width;
OutputHeight = Image->Picture->Height;
AspectRatio = OutputWidth / OutputHeight;
if (OutputWidth < Printer()->PageWidth&amp;&amp;OutputHeight < Printer() ->PageHeight){
if (OutputWidth < OutputHeight){
OutputHeight = Printer()->PageHeight;
OutputWidth = OutputHeight * AspectRatio;
}
else{
OutputWidth = Printer()->PageWidth;
OutputHeight = OutputWidth / AspectRatio;
}
}
if (OutputWidth > Printer()->PageWidth){
OutputWidth = Printer()->PageWidth;
OutputHeight= OutputWidth / AspectRatio;
}
if (OutputHeight > Printer()->PageHeight){
OutputHeight = Printer()->PageHeight;
OutputWidth = OutputHeight * AspectRatio;
}
Printer()->Canvas->StretchDraw(Rect(0,0,
floor(OutputWidth), floor(OutputHeight)),
Image->Picture->Graphic);
}
//---------------------------------------------------------------------------
代码如上 我晕 看不懂这些算法 哪个和计算:
{
马上计算相邻像素的亮度差值的平方和
将每一行像素的亮度差值平方和累加,就得到这一帧图像的调焦评价函数。
}
有关啊
 
设有三幅二维图像,经过灰度化处理之后,变成如下三个二维数字矩阵(数字代表亮度):

Lights:array[0..2,0..4] of Single;
a) b) c)
0 2 3 2 0 0 1 2 1 0 0 0 0 0 0
1 4 6 4 1 0 3 16 3 0 0 0 30 0 0
0 2 3 2 0 0 1 2 1 0 0 0 0 0 0

使用如下代码计算亮度矩阵的调焦评价函数:
Result:=0;
for i:=1 to High(Lights)-1 do
for j:=1 to High(Lights)-1 do
begin //考虑相邻的4个像素的两度差值
d:=Lights[j]-Lights[i-1][j]
Result:=Result+d*d;
d:=Lights[j]-Lights[i+1][j]
Result:=Result+d*d;
d:=Lights[j]-Lights[j-1]
Result:=Result+d*d;
d:=Lights[j]-Lights[j+1]
Result:=Result+d*d;
end;

经过计算,三幅图的评估结果分别为:
a) 3^2+(2^2)*3 + (2^2)*2+(3^2)*2 + 3^2+(2^2)*3 = 68
b) 3^2+(2^2)*2+13^2 + (13^2)*2+(14^2)*2 + 3^2+(2^2)*2+13^2 = 1102
c) 30^2 + (30^2)*4 + 30^2 = 5400

经过计算,c的调焦评价函数值最高,是最清晰的图像。


由于BitMap通常都很大(像素高达上百万),为了进行高速的计算,可以利用ScanLine,
我在上面给出帖子链接,主要就是为了演示这种技术。

另外,普通数码相机的AF灯,主要功能是向相机正前方很小的范围内发射红外线光束,照
亮被摄物体,而DC内部的红外线敏感器件根据这一小块区域的红外线亮度图以及步进电机的
配合,就能够完成自动对焦的过程。由此可知,在很多情况下,我们只需要对图像中央区域
很小一部分区域(例如:100*100)进行评估即可,而不必花费数十倍的时间对整幅图像进
行计算、评估。
 
哇,真是高手如云,路过帮顶
 
早期没有发明红外二极管,自动对焦用超声波雷达,现在都是用红外雷达来作测距,
是根据发出红外脉冲,和接收反射光两种信号之间的相差来测距的。红外线的距离
和抗干扰都没激光好,但在相机上用足以,电路也很简单,甚至无需电脑就可以调
焦,无需分析亮度图。
 
哈哈!终于露馅了:P原来是红外雷达啊[:D]那为什么偶的柯达夜间对焦总是很慢呢?[:(]

继续顶~~ :)
 
慢不一定就是在对焦,照相机还要自动调光圈,适用亮度和对比度等等,光线较
暗时,感光器件采光不足,会花更多时间,要知道,数码相机的自动对焦功能是
从传统相机移植过来,已经很成熟的旧技术。
 
TO Qsmile
当你用镜头组实现把远景拉近的时候 用眼睛来实现两组镜头的对焦是很难的 几乎每个镜片的行程都要走一遍
可拉远近的镜头组里有4片镜片 其中第2 4片是步进电机控制的
可以人为的控制粗调 即景物拉远拉近 ,但精调有时是人力顾不上的 所以只能用软件实现
 
这很难的,做到也只能很粗,怎么不用红外反射来测距,用激光则会超精确,另外因为红外向是不可见光,但感光器件仍会产生电压,反映到照片上变成可见,会污染照片,所以相机的镜头都有过滤红外的镀膜,一般不会有红外线亮度图了。
 
后退
顶部