根据论文试试自动对焦-----草稿

要从一个视野的不同高度拍的一组图片中选出最清晰的一张,看了论文《基于边缘特征的光学图像清晰度判定》,试了下,好像比之前的效果好。

int AutoFocus::gradientdimg(Mat &grayimg)
{
	if(!grayimg.data)
	{
		cout<<"error:invalid image..."<<endl;
		return -1;
	}

	for(int r=0;r!=mysize_.height-2;r++)
	{
		for(int c=0;c!=mysize_.width-2;c++)
		{
			gradient_dimg.ptr<float>(r)[c]=sqrt(
					( (int(grayimg.ptr<uchar>(r)[c])-int(grayimg.ptr<uchar>(r)[c+2])) * (int(grayimg.ptr<uchar>(r)[c])-int(grayimg.ptr<uchar>(r)[c+2])) )
					+ ( (int(grayimg.ptr<uchar>(r)[c])-int(grayimg.ptr<uchar>(r+2)[c])) * (int(grayimg.ptr<uchar>(r)[c])-int(grayimg.ptr<uchar>(r+2)[c])))
					);
		}
	}

	return 0;
}
int AutoFocus::directiongradient()
{
	float direction_s[4]={0};
	float d1=0,d2=0,d3=0,d4=0,m1=0,m3=0;
	int gray_divide=0;
	int edges=0;
	int clears=0;

	float m1sum=0,m3sum=0,gray_dividesum=0;
	for(int r=3;r<mysize_.height-3;r+=10)
	{
		for(int c=3;c<mysize_.width-3;c+=10)
		{

			//angle :0
			direction_s[0]=gradient_dimg.ptr<float>(r)[c]+gradient_dimg.ptr<float>(r)[c-1]+gradient_dimg.ptr<float>(r)[c-2]+
					gradient_dimg.ptr<float>(r)[c+1]+gradient_dimg.ptr<float>(r)[c+2];
			//angle:45
			direction_s[1]=gradient_dimg.ptr<float>(r)[c]+gradient_dimg.ptr<float>(r-1)[c+1]+gradient_dimg.ptr<float>(r-2)[c+2]+
								gradient_dimg.ptr<float>(r+1)[c-1]+gradient_dimg.ptr<float>(r+2)[c-2];
			//angle:90
			direction_s[2]=gradient_dimg.ptr<float>(r)[c]+gradient_dimg.ptr<float>(r-1)[c]+gradient_dimg.ptr<float>(r-2)[c]+
								gradient_dimg.ptr<float>(r+1)[c]+gradient_dimg.ptr<float>(r+2)[c];
			//angle:135
			direction_s[3]=gradient_dimg.ptr<float>(r)[c]+gradient_dimg.ptr<float>(r-1)[c-1]+gradient_dimg.ptr<float>(r-2)[c-2]+
								gradient_dimg.ptr<float>(r+1)[c+1]+gradient_dimg.ptr<float>(r+2)[c+2];


			//最大梯度边缘 以及法向量方向
			//angle 0
			if(direction_s[0]>direction_s[1] && direction_s[0]>direction_s[2] && direction_s[0]>direction_s[3])
			{
				uchar gray_max=srcimg_gray_.ptr<uchar>(r-3)[c];
				uchar gray_min=srcimg_gray_.ptr<uchar>(r-3)[c];
				for(short num=1;num<7;num++)
				{
					uchar gray_current=srcimg_gray_.ptr<uchar>(r-3+num)[c];
					if(gray_max<gray_current)
					{
						gray_max=gray_current;
					}
					if(gray_min>gray_current)
					{
						gray_min=gray_current;
					}
				}
				gray_divide=int(gray_max-gray_min);

				//if this is the true edge
				if(gray_divide>gray_thresh)
				{
					++edges;

					//judge if the true edge is clear or not...
					d1=abs(srcimg_gray_.ptr<uchar>(r-1)[c]-srcimg_gray_.ptr<uchar>(r-2)[c]);
					d2=abs(srcimg_gray_.ptr<uchar>(r)[c]-srcimg_gray_.ptr<uchar>(r-1)[c]);
					d3=abs(srcimg_gray_.ptr<uchar>(r+1)[c]-srcimg_gray_.ptr<uchar>(r)[c]);
					d4=abs(srcimg_gray_.ptr<uchar>(r+2)[c]-srcimg_gray_.ptr<uchar>(r+1)[c]);
					m1=std::max(std::max(d1,d2),std::max(d3,d4))/2/gray_divide;
					m3=std::max(d1+d2+d3,d2+d3+d4)/2/gray_divide;

					if(m1>m1_thresh && m3>m3_thresh)
					{
						//it is clear
						++clears;
					}
				}
			}

			//angle 90
			if(direction_s[2]>direction_s[0] && direction_s[2]>direction_s[1] && direction_s[2]>direction_s[3])
			{
				uchar gray_max=srcimg_gray_.ptr<uchar>(r)[c-3];
				uchar gray_min=srcimg_gray_.ptr<uchar>(r)[c-3];
				for(short num=1;num<7;num++)
				{
					uchar gray_current=srcimg_gray_.ptr<uchar>(r)[c-3+num];
					if(gray_max<gray_current)
					{
						gray_max=gray_current;
					}
					if(gray_min>gray_current)
					{
						gray_min=gray_current;
					}
				}
				gray_divide=int(gray_max-gray_min);

				//if this is the true edge
				if(gray_divide>gray_thresh)
				{
					++edges;

					//judge if the true edge is clear or not...
					d1=abs(srcimg_gray_.ptr<uchar>(r)[c-1]-srcimg_gray_.ptr<uchar>(r)[c-2]);
					d2=abs(srcimg_gray_.ptr<uchar>(r)[c]-srcimg_gray_.ptr<uchar>(r)[c-1]);
					d3=abs(srcimg_gray_.ptr<uchar>(r)[c+1]-srcimg_gray_.ptr<uchar>(r)[c]);
					d4=abs(srcimg_gray_.ptr<uchar>(r)[c+2]-srcimg_gray_.ptr<uchar>(r)[c+1]);
					m1=std::max(std::max(d1,d2),std::max(d3,d4))/2/gray_divide;
					m3=std::max(d1+d2+d3,d2+d3+d4)/2/gray_divide;

					if(m1>m1_thresh && m3>m3_thresh)
					{
						//it is clear
						++clears;
					}
				}
			}

			//angle 45
			if(direction_s[1]>direction_s[0] && direction_s[1]>direction_s[2] && direction_s[1]>direction_s[3])
			{
				uchar gray_max=srcimg_gray_.ptr<uchar>(r-3)[c-3];
				uchar gray_min=srcimg_gray_.ptr<uchar>(r-3)[c-3];
				for(short num=1;num<7;num++)
				{
					uchar gray_current=srcimg_gray_.ptr<uchar>(r-3+num)[c-3+num];
					if(gray_max<gray_current)
					{
						gray_max=gray_current;
					}
					if(gray_min>gray_current)
					{
						gray_min=gray_current;
					}
				}
				gray_divide=int(gray_max-gray_min);

				//if this is the true edge
				if(gray_divide>gray_thresh)
				{
					++edges;

					//judge if the true edge is clear or not...
					d1=abs(srcimg_gray_.ptr<uchar>(r-1)[c-1]-srcimg_gray_.ptr<uchar>(r-2)[c-2]);
					d2=abs(srcimg_gray_.ptr<uchar>(r)[c]-srcimg_gray_.ptr<uchar>(r-1)[c-1]);
					d3=abs(srcimg_gray_.ptr<uchar>(r+1)[c+1]-srcimg_gray_.ptr<uchar>(r)[c]);
					d4=abs(srcimg_gray_.ptr<uchar>(r+2)[c+2]-srcimg_gray_.ptr<uchar>(r+1)[c+1]);
					m1=std::max(std::max(d1,d2),std::max(d3,d4))/2/gray_divide;
					m3=std::max(d1+d2+d3,d2+d3+d4)/2/gray_divide;

					if(m1>m1_thresh && m3>m3_thresh)
					{
						//it is clear
						++clears;
					}
				}
			}

			//angle 135
			if(direction_s[3]>direction_s[0] && direction_s[3]>direction_s[2] && direction_s[3]>direction_s[1])
			{
				uchar gray_max=srcimg_gray_.ptr<uchar>(r+3)[c-3];
				uchar gray_min=srcimg_gray_.ptr<uchar>(r+3)[c-3];
				for(short num=1;num<7;num++)
				{
					uchar gray_current=srcimg_gray_.ptr<uchar>(r+3-num)[c-3+num];
					if(gray_max<gray_current)
					{
						gray_max=gray_current;
					}
					if(gray_min>gray_current)
					{
						gray_min=gray_current;
					}
				}
				gray_divide=int(gray_max-gray_min);

				//if this is the true edge
				if(gray_divide>gray_thresh)
				{
					++edges;

					//judge if the true edge is clear or not...
					d1=abs(srcimg_gray_.ptr<uchar>(r+1)[c-1]-srcimg_gray_.ptr<uchar>(r+2)[c-2]);
					d2=abs(srcimg_gray_.ptr<uchar>(r)[c]-srcimg_gray_.ptr<uchar>(r+1)[c-1]);
					d3=abs(srcimg_gray_.ptr<uchar>(r-1)[c+1]-srcimg_gray_.ptr<uchar>(r)[c]);
					d4=abs(srcimg_gray_.ptr<uchar>(r-2)[c+2]-srcimg_gray_.ptr<uchar>(r-1)[c+1]);
					m1=std::max(std::max(d1,d2),std::max(d3,d4))/2/gray_divide;
					m3=std::max(d1+d2+d3,d2+d3+d4)/2/gray_divide;

					if(m1>m1_thresh && m3>m3_thresh)
					{
						//it is clear
						++clears;
					}
				}
			}


			m1sum+=m1;

		}
	}

	float average_m1=m1sum/edges;
	float clear_ratio=float(clears)/edges;
	standard_value[0]=clear_ratio;
	standard_value[1]=average_m1;

	return 0;
}

int AutoFocus::judgeMaxLaplace(bool down_up)
{
	float maxLaplace,sec_max;
	int max_ind,sec_ind;

	if(imgs_clear_one_view_[0]>=imgs_clear_one_view_[1])
	{
		maxLaplace=imgs_clear_one_view_[0];
		max_ind=0;
		sec_max=imgs_clear_one_view_[1];
		sec_ind=1;
	}
	else
	{
		maxLaplace=imgs_clear_one_view_[1];
		max_ind=1;
		sec_max=imgs_clear_one_view_[0];
		sec_ind=0;
	}

	bool useless_max=false;
	for (int j = 2; j != cImgsNumber1View_; j++)
	{
		if (imgs_clear_one_view_[j] > maxLaplace)
		{
			if(useless_max==true)
			{
				sec_max=maxLaplace;
				sec_ind=max_ind;
			}
			maxLaplace = imgs_clear_one_view_[j];
			max_ind = j;
			useless_max=true;
		}
		if (imgs_clear_one_view_[j] > sec_max && imgs_clear_one_view_[j]<maxLaplace)
		{
			sec_max = imgs_clear_one_view_[j];
			sec_ind = j;
		}
	}

	if(imgs_m1_one_view_[max_ind]<imgs_m1_one_view_[sec_ind])
	{
		return sec_ind;
	}
	else
	{
		return max_ind;
	}

}

目前测了大概一千多组图,效果还行。像这种复杂的也还行。

但随着测试复杂程度增加,估计会出现找不准的情况,还要改善,让其更具有鲁棒性。或者要换一种更加好的算法?!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

元气少女缘结神

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值