这个需求很简单。本来用了很多别的方法,比如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);
但这个貌似不行。不能概括全部情况。