相机自动对焦(草稿)

这个需求很简单。本来用了很多别的方法,比如PSNR、std、Sobel,但都不如同事说的laplace好,所以直接用opencv的laplace好了。

TickMeter tm;
	tm.start();
	ofstream file("result0.51.txt", ios::out);
	for (int num = 1; num <= 3; num++)
	{
		bool flag = true;
		float lap[40];
		memset(lap, 0, 40 * sizeof(float));
		for (int i = 0; i <= 39; i++)
		{
			sprintf(filename, "focusing\\%d\\%d.bmp", num, i);
			Mat srcimg00 = imread(filename);
			if (!srcimg00.data)
			{
				flag = false;
				break;
			}
			Mat srcimg = myresize2(srcimg00);
			Mat srcimggray;
			cvtColor(srcimg, srcimggray, CV_RGB2GRAY);
			Mat imageSobel;
			Laplacian(srcimggray, imageSobel, srcimggray.depth(), 1, 1);
			double meanValue = 0.0;
			meanValue = sum(imageSobel)[0];
			lap[i] = meanValue;
		}

		float minmse = lap[0];
		int ind = 0;
		for (int j = 1; j <= 39; j++)
		{
			if (lap[j] > minmse)
			{
				minmse = lap[j];
				ind = j;
			}
		}
		file << "image: "<<num<<"---"<<ind  << endl;
			
	}
	file.close();
	tm.stop();
	cout << "count=" << tm.getCounter() << ",process time=" << tm.getTimeMilli() << endl;
有3个文件夹,每个文件夹下是对同一个物体拍摄的40组图,找到最清晰的,即达到自动对焦目的。

即:

cameraFocusing.h

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>

using namespace cv;
using namespace std;


class focusing{
public:
	focusing();
	int setimginfo(const Mat&);
	void doFocusing(string&);
	~focusing();
private:
	const float scale;
	const int imgs1time;
	int realPosition;
	Mat currentImg;
	static int timesCount;
	Mat times4img[40];
	float times4imgResult[40];
	Mat bestImg;
	Mat resizeImage(const Mat&);
	void laplaceWork();
	int judgeMaxLaplace();
	void saveBestImage(string&);
};
cameraFocusing.cpp

#include "cameraFocusing.h"  

int focusing::timesCount = 0;

focusing::focusing():scale(0.5),imgs1time(40)
{
	realPosition=0;
	memset(times4imgResult, 0, imgs1time*sizeof(float));
}

int focusing::setimginfo(const Mat &srcimg)
{
	if (!srcimg.data)
	{
		cout << "Error:No image sent to the class object!" << endl;
		return -1;
	}
	srcimg.copyTo(currentImg);
	timesCount += 1;
	realPosition = (timesCount - 1) % imgs1time;
	srcimg.copyTo(times4img[realPosition]);
	laplaceWork();
	return 0;
}

void focusing::doFocusing(string &folderName){
	if ((timesCount % imgs1time) == 0)
	{

		int bestLaplace = judgeMaxLaplace();
		times4img[bestLaplace].copyTo(bestImg);
		saveBestImage(folderName);
	}
}

Mat focusing::resizeImage(const Mat &src)
{
	cv::Size mysize;
	mysize.height = src.rows*scale;
	mysize.width = src.cols*scale;
	Mat dst(mysize, src.depth(), src.channels());
	resize(src, dst, mysize);
	return dst;
}

void focusing::laplaceWork()
{
	Mat srcimg = resizeImage(currentImg);
	Mat srcimggray;
	cvtColor(srcimg, srcimggray, CV_RGB2GRAY);
	Mat imageLaplace;
	Laplacian(srcimggray, imageLaplace, srcimggray.depth(), 1, 1);
	float meanValue = 0.0;
	meanValue = sum(imageLaplace)[0];
	times4imgResult[realPosition] = meanValue;
}

int focusing::judgeMaxLaplace(){
	float maxLaplace = times4imgResult[0];
	int ind = 0;
	for (int j = 1; j <= 39; j++)
	{
		if (times4imgResult[j] > maxLaplace)
		{
			maxLaplace = times4imgResult[j];
			ind = j;
		}
	}
	ind = ind + 2;
	return ind;
}

void focusing::saveBestImage(string &folderName)
{
	DIR *dir = NULL;
	dir = opendir(folderName.c_str());
	if (NULL == dir)
	{
		int fd = mkdir(folderName.c_str(), 0755);
		if (fd == -1)
		{
			perror("create folder for saving images failt\n");
		}
	}
	
	//int num = timesCount / imgs1time;
	//char str[30];
	//sprintf(str,"%d",num);
	//itoa(num, str, 10);
	//string folderPathName = folderName + "/" + str+".bmp";
	
	time_t timenow;
	struct tm *sTime;
	timenow=time(NULL);
	sTime=localtime(&timenow);
	ostringstream imgName;
	imgName<<sTime->tm_year+1900<<"-"<<sTime->tm_mon+1<<"-"<<sTime->tm_mday<<" "<<sTime->tm_hour<<":"<<sTime->tm_min<<":"<<sTime->tm_sec;
	string folderPathName = folderName + "/" + imgName.str()+".bmp";

	imwrite(folderPathName.c_str(), bestImg);
}


focusing::~focusing()
{
}
test.cpp

#include "cameraFocusing.h"

int main()
{
	TickMeter tm;
	tm.start();
	focusing theFocuser;
	char imgfile[100];
	string folderPosition="/home/jumper/Ecology_EDK/EcologyMathOfCameraFocusing/result";

	for(int num=1;num<=15;num++)
	{
		for(int i=0;i<=39;i++)
		{
			sprintf(imgfile,"focusing0710/%d/%d.bmp",num,i);
			Mat srcimg=imread(imgfile);
			if(!srcimg.data)
			{
				cout<<"this image does not exit!"<<endl;
				return -1;
			}
			int errorFlag=theFocuser.setimginfo(srcimg);
			theFocuser.doFocusing(folderPosition);
		}
	}
	tm.stop();
	cout<<"counter:"<<tm.getCounter()<<", process time: "<<tm.getTimeMilli()<<endl; // 0.7~0.8/group
	return 0;
}

不对,类文件中那样保存可能会造成因为耗时很短而覆盖,丢失结果图片,如果用注释中那样又会在每次启动工程时覆盖上次的结果!改成这样就不会重复了,

void focusing::saveBestImage(string &folderName)
{
	DIR *dir = NULL;
	dir = opendir(folderName.c_str());
	if (NULL == dir)
	{
		int fd = mkdir(folderName.c_str(), 0755);
		if (fd == -1)
		{
			perror("create folder for saving images failt\n");
		}
	}
	int num = timesCount / imgs1time;
	char str[30];
	sprintf(str,"%d",num);

	time_t timenow;
	struct tm *sTime;
	timenow=time(NULL);
	sTime=localtime(&timenow);
	ostringstream imgName;
	imgName<<sTime->tm_year+1900<<"-"<<sTime->tm_mon+1<<"-"<<sTime->tm_mday<<" "<<sTime->tm_hour<<":"<<sTime->tm_min<<":"<<sTime->tm_sec;
	string folderPathName = folderName + "/" + imgName.str()+" "+str+".bmp";
	imwrite(folderPathName.c_str(), bestImg);
}

本来还搞了一个梯度、psnr等做指标的:

int num = 35;
	float psnrArray[40];
	float gradient_mean_array[40];
	float gradient_std_array[40];
	float gradient_mse_array[40];
	//for gradient img!
	//ofstream txtfile("focusing7.txt", ios::out);
	for (int i = 0; i <= 39; i++)
	{
		sprintf(filename, "%d\\%d.bmp",num, i);
		sprintf(result, "camera-temp\\4\\%d.bmp", i);
		Mat srcimg=imread(filename);
		//IplImage* testimg = cvLoadImage(filename);

		cv::Mat grad_x, grad_y;
		cv::Mat abs_grad_x, abs_grad_y;
		cv::Mat kerl_x = (Mat_<float>(1, 3) << -1, 0, 1);
		cv::filter2D(srcimg, grad_x, srcimg.depth(), kerl_x, Point(-1, -1), 0, BORDER_DEFAULT);
		cv::convertScaleAbs(grad_x, abs_grad_x);

		cv::Mat kerl_y = (Mat_<float>(3, 1) << -1, 0, 1);
		cv::filter2D(srcimg, grad_y, srcimg.depth(), kerl_y, Point(-1, -1), 0, BORDER_DEFAULT);
		cv::convertScaleAbs(grad_y, abs_grad_y);
		Mat gradientimg;
		gradientimg.create(cv::Size(grad_x.cols, grad_y.rows), CV_8U);

		int sumGradient = 0;
		double gradient_mean = 0;
		uchar *totllGrad = gradientimg.ptr<uchar>(0);
		uchar *_x_grad = abs_grad_x.ptr<uchar>(0);
		uchar *_y_grad = abs_grad_y.ptr<uchar>(0);
		int numall = grad_x.rows*grad_x.cols;
		for (int i = 0; i < numall; i++)
		{
			totllGrad[i] = sqrt((double)_x_grad[i] * _x_grad[i] + (double)_y_grad[i] * _y_grad[i]);
			sumGradient += totllGrad[i];
		}
		gradient_mean = (double)sumGradient / numall;
		Mat meanimg, stdimg;
		double temp_mean = 0, temp_std = 0;
		meanStdDev(gradientimg, meanimg, stdimg);
		temp_mean = meanimg.at<double>(0, 0);
		temp_std = stdimg.at<double>(0, 0);

		float mse = 0;
		for (int i = 0; i < numall; i++)
		{
		mse += (totllGrad[i] - temp_mean)*(totllGrad[i] - temp_mean);
		}
		mse = (float)mse / numall;
		float psnr = 0;
		psnr = 10 * log10(255 * 255 / mse);
		gradient_mean_array[i] = gradient_mean;
		gradient_std_array[i] = temp_std;
		gradient_mse_array[i] = mse;
		psnrArray[i] = psnr;
		cout << "image " << i << " : gradient---" << gradient_mean << "  std---" << temp_std << "  mse---" << mse << "  psnr---" << psnr << endl;
		cout << "_______________________________________________________________________" << endl;
		//txtfile << "image " << i << " : gradient---" << gradient_mean << "  std---" << temp_std << "  mse---" << mse << "  psnr---" << psnr << endl;
		//txtfile << "_______________________________________________________________________" << endl;
		//imwrite(result, gradientimg);
	}
	//txtfile.close();


	float minpsnr = psnrArray[0];
	int ind = 0;
	for (int j = 1; j <= 39; j++)
	{
		if (psnrArray[j] < minpsnr)
		{
			minpsnr = psnrArray[j];
			ind = j;
		}
	}
	cout << ind << endl;
	sprintf(filename, "%d\\%d.bmp", num,ind);
	sprintf(result, "20170706\\psnr\\%d.bmp", num);
	Mat srcimg0 = imread(filename);
	imwrite(result, srcimg0);

	float minmean = gradient_mean_array[0];
	ind = 0;
	for (int j = 1; j <= 39; j++)
	{
		if (gradient_mean_array[j] > minmean)
		{
			minmean = gradient_mean_array[j];
			ind = j;
		}
	}
	cout << ind << endl;
	sprintf(filename, "%d\\%d.bmp", num,ind);
	sprintf(result, "20170706\\gradientMean\\%d.bmp", num);
	Mat srcimg1 = imread(filename);
	imwrite(result, srcimg1);


	float minstd = gradient_std_array[0];
	ind = 0;
	for (int j = 1; j <= 39; j++)
	{
		if (gradient_std_array[j] > minstd)
		{
			minstd = gradient_std_array[j];
			ind = j;
		}
	}
	cout << ind << endl;
	sprintf(filename, "%d\\%d.bmp", num,ind);
	sprintf(result, "20170706\\gradientStd\\%d.bmp", num);
	Mat srcimg2 = imread(filename);
	imwrite(result, srcimg2);


	float minmse = gradient_mse_array[0];
	ind = 0;
	for (int j = 1; j <= 39; j++)
	{
		if (gradient_mse_array[j] > minmse)
		{
			minmse = gradient_mse_array[j];
			ind = j;
		}
	}
	cout << ind << endl;
	sprintf(filename, "%d\\%d.bmp", num,ind);
	sprintf(result, "20170706\\mse\\%d.bmp", num);
	Mat srcimg3= imread(filename);
	imwrite(result, srcimg3);
	
但这个貌似不行。不能概括全部情况。




  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

元气少女缘结神

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

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

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

打赏作者

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

抵扣说明:

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

余额充值