相机自动对焦(草稿)

xiaoxiao2021-02-28  128

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

转载请注明原文地址: https://www.6miu.com/read-22083.html

最新回复(0)