2015-03-11 6 views
0

Я попытался дать некоторые эффекты эскиза для изображения, для которого я использовал гауссовскую технику моделирования в opencv, но я столкнулся с проблемой, которая требует больше времени для выполнения. Время уменьшается, когда размер изображения мал, если размер большой, требуется больше времени. Пожалуйста, любой один рассказать, как сократить время выполнения без изменения фактического размера изображения для следующего кодаКак сократить время выполнения для следующего кода?

#include "opencv2/opencv.hpp" 
 
#include <iostream> 
 
#include <vector> 
 
#include "opencv2/ml/ml.hpp" 
 
#include <list> 
 
#include <iostream> 
 
using namespace cv; 
 
using namespace std; 
 

 
void clustrize_colors(Mat& src,Mat& dst) 
 
{ 
 
\t // Number of clusters 
 
\t int NrGMMComponents = 96; 
 

 
\t cv::GaussianBlur(src,src,Size(3,3),1); 
 

 
\t int srcHeight = src.rows; 
 
\t int srcWidth = src.cols; 
 

 
\t // Get datapoints 
 
\t vector<Vec3d> ListSamplePoints; 
 

 
\t for (int y=0; y<srcHeight; y++) 
 
\t { 
 
\t \t for (int x=0; x<srcWidth; x++) 
 
\t \t { 
 
\t \t \t // Collecting points from image 
 
\t \t \t Vec3b bgrPixel = src.at<Vec3b>(y, x); 
 

 
\t \t \t uchar b = bgrPixel.val[0]; 
 
\t \t \t uchar g = bgrPixel.val[1]; 
 
\t \t \t uchar r = bgrPixel.val[2]; 
 
\t \t \t if(rand()%25==0) // peek every 25-th 
 
\t \t \t { 
 
\t \t \t \t ListSamplePoints.push_back(Vec3d(b,g,r)); 
 
\t \t \t } 
 
\t \t } // for (x) 
 
\t } // for (y) 
 

 

 
\t // Form training matrix 
 
\t int NrSamples = ListSamplePoints.size();  
 
\t Mat samples(NrSamples, 3, CV_64FC1); 
 

 
\t for (int s=0; s<NrSamples; s++) 
 
\t { 
 
\t \t Vec3d v = ListSamplePoints.at(s); 
 
\t \t samples.at<double>(s,0) = (float) v[0]; 
 
\t \t samples.at<double>(s,1) = (float) v[1]; 
 
\t \t samples.at<double>(s,2) = (float) v[2]; 
 
\t }  
 
\t // 
 
\t cout << "Learning to represent the sample distributions with " << NrGMMComponents << " gaussians." << endl; 
 
\t cout << "Started GMM training" << endl; 
 

 
\t Ptr<cv::ml::EM> em_model; 
 
\t cv::ml::EM::Params params(NrGMMComponents,cv::ml::EM::COV_MAT_GENERIC); 
 

 
\t Mat labels(NrSamples,1,CV_32SC1); 
 
\t Mat logLikelihoods(NrSamples, 1, CV_64FC1); 
 

 
\t // Train classifier 
 
\t em_model=cv::ml::EM::train(samples,logLikelihoods,labels,noArray(),params); 
 
\t cout << "Finished GMM training" << endl; 
 

 
\t // result image 
 
\t Mat img = Mat::zeros(Size(srcWidth, srcHeight), CV_8UC3); 
 

 
\t // predict cluster 
 
\t Mat sample(1, 3, CV_64FC1); 
 

 
\t Mat means=em_model->getMeans(); 
 

 
\t for(int i = 0; i < img.rows; i++) 
 
\t { 
 
\t \t for(int j = 0; j < img.cols; j++) 
 
\t \t { 
 
\t \t \t Vec3b v=src.at<Vec3b>(i,j); 
 
\t \t \t sample.at<double>(0,0) = (float) v[0]; 
 
\t \t \t sample.at<double>(0,1) = (float) v[1]; 
 
\t \t \t sample.at<double>(0,2) = (float) v[2]; 
 
\t \t \t int response = cvRound(em_model->predict(sample)); 
 
\t \t \t img.at<Vec3b>(i,j)[0]=means.at<double>(response,0); 
 
\t \t \t img.at<Vec3b>(i,j)[1]=means.at<double>(response,1); 
 
\t \t \t img.at<Vec3b>(i,j)[2]=means.at<double>(response,2); 
 
\t \t } 
 
\t } 
 

 
\t img.convertTo(img,CV_8UC3); 
 
     namedWindow("result",WINDOW_AUTOSIZE); 
 
\t imshow("result",img); 
 
     imwrite("D:\\nfr.jpg",img); 
 
\t waitKey(); 
 
\t dst=img; 
 
} 
 

 
void processLayer(Mat& src,Mat& dst) 
 
{ 
 
\t Mat tmp=src.clone(); 
 
\t Mat gx,gy,mag,blurred; 
 
\t Sobel(src, gx, -1, 1, 0, 3); 
 
\t Sobel(src, gy, -1, 0, 1, 3); 
 
\t magnitude(gx,gy,mag); 
 
\t //GaussianBlur(mag,blurred,Size(3,3),2); 
 
\t //mag+=blurred; 
 
\t normalize(mag,mag,0,1,cv::NORM_MINMAX); 
 
\t //sqrt(mag,dst); 
 
\t dst=mag.clone(); 
 
\t normalize(dst,dst,0,1,cv::NORM_MINMAX); 
 
} 
 

 
int main(int ac, char** av) 
 
{ 
 
\t Mat clusterized; 
 
\t Mat frame=imread("image path"); ////load an image////// 
 
     //resize(frame,frame,Size(256,256),0,0,INTER_LINEAR); 
 
\t clustrize_colors(frame,clusterized); 
 
\t clusterized.convertTo(clusterized,CV_32FC3,1.0/255.0); 
 
\t frame.convertTo(frame,CV_32FC3,1.0/255.0); 
 
\t Mat result1; 
 
\t vector<Mat> ch; 
 
\t split(frame, ch); 
 

 
\t processLayer(ch[0],ch[0]); 
 
\t processLayer(ch[1],ch[1]); 
 
\t processLayer(ch[2],ch[2]); 
 

 
\t merge(ch,result1); 
 

 
\t result1=(0.5*frame-0.9*result1+0.3*clusterized)*2.0; 
 
     namedWindow("result1",WINDOW_AUTOSIZE); 
 
\t imshow("result1",result1); 
 
     //cout<<result1; 
 
     imwrite("D:\\finalresult.jpg",result1); 
 
\t waitKey(0); 
 
\t //destroyAllWindows(); 
 
\t return 0; 
 
}

+0

Все выглядит медленно. Но в первом цикле самая жесткая часть должна быть rand(), затем% 25, ​​которые являются как дорогостоящими операциями. Может быть, может сгенерировать карту выборки? В третьем цикле встраивание em_model-> pred может помочь, и выглядит глупо, чтобы преобразовать байты в float, а затем удвоить, а затем вернуться к байту .... – user3528438

+0

Спасибо, пытаясь исправить его. –

+1

Возможно, вы захотите вставить некоторые временные инструменты чтобы определить, какие части медленны. – Arunas

ответ

0

По всей вероятности, узким местом является резюме OpenCV в :: мл :: EM :: метод поезда. Обучение классификатору - непростая задача. Проблема классификации не решена окончательно. Вот почему существуют большие компромиссы и различия между алгоритмами, не говоря уже о разных проблемных пространствах.

Что касается производительности, если вы настаиваете на использовании EM, проверьте EM class documentation и, возможно, его родительских классов для изменения:

  • Максимальное количество итераций для обучения и/или
  • критериев Term остановить обучение.

Из-за использования сторонней библиотеки, вы не можете много сделать, что увеличит скорость, но не принесет жертву точность. С другой стороны, библиотека является открытым исходным кодом, и она, вероятно, хорошо оптимизирована. Я не рекомендую пытаться оптимизировать фактический код библиотеки.

Смежные вопросы