int main(int argc, const char** argv) {
    
    boost::program_options::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ("input", boost::program_options::value<std::string>(), "the folder to process")
        ("lambda", boost::program_options::value<double>()->default_value(0.5), "lambda")
        ("sigma", boost::program_options::value<double>()->default_value(5.0), "sigma")
        ("four-connected", "use 4-connected")
        ("superpixels", boost::program_options::value<int>()->default_value(400), "number of superpixels")
        ("time", boost::program_options::value<std::string>(), "time the algorithm and save results to the given directory")
        ("process", "show additional information while processing")
        ("csv", "save segmentation as CSV file")
        ("contour", "save contour image of segmentation")
        ("mean", "save mean colored image of segmentation")
        ("output", boost::program_options::value<std::string>()->default_value("output"), "specify the output directory (default is ./output)");

    boost::program_options::positional_options_description positionals;
    positionals.add("input", 1);
    
    boost::program_options::variables_map parameters;
    boost::program_options::store(boost::program_options::command_line_parser(argc, argv).options(desc).positional(positionals).run(), parameters);
    boost::program_options::notify(parameters);

    if (parameters.find("help") != parameters.end()) {
        std::cout << desc << std::endl;
        return 1;
    }
    
    boost::filesystem::path outputDir(parameters["output"].as<std::string>());
    if (!boost::filesystem::is_directory(outputDir)) {
        boost::filesystem::create_directory(outputDir);
    }
    
    boost::filesystem::path inputDir(parameters["input"].as<std::string>());
    if (!boost::filesystem::is_directory(inputDir)) {
        std::cout << "Image directory not found ..." << std::endl;
        return 1;
    }
    
    bool process = false;
    if (parameters.find("process") != parameters.end()) {
        process = true;
    }
    
    std::vector<boost::filesystem::path> pathVector;
    std::vector<boost::filesystem::path> images;
    
    std::copy(boost::filesystem::directory_iterator(inputDir), boost::filesystem::directory_iterator(), std::back_inserter(pathVector));

    std::sort(pathVector.begin(), pathVector.end());
    
    std::string extension;
    int count = 0;
    
    for (std::vector<boost::filesystem::path>::const_iterator iterator (pathVector.begin()); iterator != pathVector.end(); ++iterator) {
        if (boost::filesystem::is_regular_file(*iterator)) {
            
            // Check supported file extensions.
            extension = iterator->extension().string();
            std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
            
            if (extension == ".png" || extension == ".jpg" || extension == ".jpeg") {
                images.push_back(*iterator);
                
                if (process == true) {
                    std::cout << "Found " << iterator->string() << " ..." << std::endl;
                }
                
                ++count;
            }
        }
    }
    
    std::cout << count << " images total ..." << std::endl;
    
    boost::timer timer;
    double totalTime = 0;
    
    int eightConnected = 1;
    if (parameters.find("four-connected") != parameters.end()) {
        eightConnected = 0;
    }
    
    int superpixels = parameters["superpixels"].as<int>();
    int kernel = 0;
    double lambda = parameters["lambda"].as<double>();
    double sigma = parameters["sigma"].as<double>();
    MERCLazyGreedy merc;
    
    cv::Mat time(images.size(), 2, cv::DataType<double>::type);
    for(std::vector<boost::filesystem::path>::iterator iterator = images.begin(); iterator != images.end(); ++iterator) {
        cv::Mat mat = cv::imread(iterator->string());
        
        Image<RGBMap> inputImage;
        MERCInputImage<RGBMap> input;

        inputImage.Resize(mat.cols, mat.rows, false);

        for (int i = 0; i < mat.rows; ++i) {
            for (int j = 0; j < mat.cols; ++j) {
                RGBMap color((int) mat.at<cv::Vec3b>(i, j)[2], (int) mat.at<cv::Vec3b>(i, j)[1], (int) mat.at<cv::Vec3b>(i, j)[0]);
                inputImage.Access(j, i) = color;
            }
        }

        input.ReadImage(&inputImage, eightConnected);
		
        timer.restart();
        int index = std::distance(images.begin(), iterator);
        
        merc.ClusteringTreeIF(input.nNodes_, input, kernel, sigma*mat.channels(), lambda*1.0*superpixels, superpixels);
        
        time.at<double>(index, 1) = timer.elapsed();
        time.at<double>(index, 0) = index + 1;
        totalTime += time.at<double>(index, 1);
        
	vector<int> label = MERCOutputImage::DisjointSetToLabel(merc.disjointSet_);
        
        int** labels = new int*[mat.rows];
        for (int i = 0; i < mat.rows; ++i) {
            labels[i] = new int[mat.cols];
            
            for (int j = 0; j < mat.cols; ++j) {
                labels[i][j] = label[j + i*mat.cols];
            }
        }
        
        Integrity::relabel(labels, mat.rows, mat.cols);
        
        boost::filesystem::path extension = iterator->filename().extension();
        int position = iterator->filename().string().find(extension.string());
        
        if (parameters.find("contour") != parameters.end()) {
            
            std::string store = outputDir.string() + DIRECTORY_SEPARATOR + iterator->filename().string().substr(0, position) + "_contours.png";
            
            int bgr[] = {0, 0, 204};
            cv::Mat contourImage = Draw::contourImage(labels, mat, bgr);
            cv::imwrite(store, contourImage);
            
            if (process == true) {
                std::cout << "Image " << iterator->string() << " with contours saved to " << store << " ..." << std::endl;
            }
        }

        if (parameters.find("mean") != parameters.end()) {
            
            std::string store = outputDir.string() + DIRECTORY_SEPARATOR + iterator->filename().string().substr(0, position) + "_mean.png";

            cv::Mat meanImage = Draw::meanImage(labels, mat);
            cv::imwrite(store, meanImage);

            if (process == true) {
                std::cout << "Image " << iterator->string() << " with mean colors saved to " << store << " ..." << std::endl;
            }
        }

        if (parameters.find("csv") != parameters.end()) {
            
            boost::filesystem::path csvFile(outputDir.string() + DIRECTORY_SEPARATOR + iterator->filename().string().substr(0, position) + ".csv");
            Export::CSV(labels, mat.rows, mat.cols, csvFile);

            if (process == true) {
                std::cout << "Labels for image " << iterator->string() << " saved in " << csvFile.string() << " ..." << std::endl;
            }
        }
        
        for (int i = 0; i < mat.rows; ++i) {
            delete[] labels[i];
        }
        
        delete[] labels;
    }
    
    if (parameters.find("time") != parameters.end()) {
        
        boost::filesystem::path timeDir(parameters["time"].as<std::string>());
        if (!boost::filesystem::is_directory(timeDir)) {
            boost::filesystem::create_directories(timeDir);
        }
        
        boost::filesystem::path timeImgFile(timeDir.string() + DIRECTORY_SEPARATOR + "eval_time_img.txt");
        boost::filesystem::path timeFile(timeDir.string() + DIRECTORY_SEPARATOR + "eval_time.txt");
        
        Export::BSDEvaluationFile<double>(time, 4, timeImgFile);
        
        cv::Mat avgTime(1, 1, cv::DataType<double>::type);
        avgTime.at<double>(0, 0) = totalTime/((double) images.size());
        Export::BSDEvaluationFile<double>(avgTime, 6, timeFile);
    }
    
    std::cout << "On average, " << totalTime/images.size() << " seconds needed ..." << std::endl;
    
    return 0;
}
Beispiel #2
0
void mexFunction(int nlhs, mxArray *plhs[ ],int nrhs, const mxArray *prhs[ ]) 
{
	double lambda,sigma;
	int nC,kernel = 0;
	int row,col;
	int conn8;
	double *pLambda,*pSigma,*pNC;	
	double *data;
	double *out;
	double *pConn8;
	//size_t width,height;
	MERCLazyGreedy merc;	
	
	mexPrintf("Entropy Rate Superpixel Segmentation Version 0.2!!!\n");
	
	if(!(nrhs==2||nrhs==4||nrhs==5))
	{
		mexPrintf("Syntax Error!!!\n");
		mexPrintf("[labels] = mex_ers(image,nC)\n");
		mexPrintf("[labels] = mex_ers(image,nC,lambda,sigma)\n");
		mexErrMsgTxt("[labels] = mex_ers(image,nC,lambda,sigma,conn8)\n");
	}
	
    //if(nlhs > 1)
	//{
	//	mexErrMsgTxt("Too many output arguments.");
    //}
	
    /* Check data type of input argument  */
    if (!(mxIsDouble(prhs[0])))
	{
		mexErrMsgTxt("Input argument must be of type double.");
    }		

	//width  = mxGetN(prhs[0]);
	//height = mxGetM(prhs[0]);
	data   = mxGetPr(prhs[0]);

	if(nrhs==2)
	{
		pNC     = mxGetPr(prhs[1]);	
		lambda  = 0.5;
		sigma   = 5.0;
		conn8   = 1;
	}
	
	if(nrhs==4)
	{
		pNC     = mxGetPr(prhs[1]);	
		pLambda = mxGetPr(prhs[2]);
		pSigma  = mxGetPr(prhs[3]);
		lambda  = *pLambda;
		sigma   = *pSigma;
		conn8   = 1;
	}
	
	if(nrhs==5)
	{
		pNC     = mxGetPr(prhs[1]);	
		pLambda = mxGetPr(prhs[2]);
		pSigma  = mxGetPr(prhs[3]);
		pConn8  = mxGetPr(prhs[4]);
		lambda  = *pLambda;
		sigma   = *pSigma;
		conn8   = (int)(*pConn8);
	}
		
	nC = (int)(*pNC);
	
	
	int nDims = (int)mxGetNumberOfDimensions(prhs[0]);
	if(nDims == 3)
	{
		int width = mxGetN(prhs[0])/nDims;
		int height = mxGetM(prhs[0]);		
		//mexPrintf("Size = ( %d , %d ); Dimension = %d\n",width,height,nDims);
		Image<RGBMap> inputImage;
		MERCInputImage<RGBMap> input;
		// Create Iamge
		inputImage.Resize(width,height,false);
		// Read the image from MATLAB
		for (col=0; col < width; col++)
		{
			for (row=0; row < height; row++)
			{
				RGBMap color(
				(int)mxGetPr(prhs[0])[row+col*height+0*width*height],
				(int)mxGetPr(prhs[0])[row+col*height+1*width*height],
				(int)mxGetPr(prhs[0])[row+col*height+2*width*height]);
				inputImage.Access(col,row) = color;
				
			}
		}
		// Read the image for segmentation
		input.ReadImage(&inputImage,conn8);
		
		// Entropy rate superpixel segmentation
		merc.ClusteringTreeIF(input.nNodes_,input,kernel,sigma*nDims,lambda*1.0*nC,nC);
		vector<int> label = MERCOutputImage::DisjointSetToLabel(merc.disjointSet_);
		// Allocate memory for the labeled image.
		plhs[0] = mxCreateDoubleMatrix(height, width, mxREAL);
		out =  mxGetPr(plhs[0]);	
		// Fill in the labeled image
		for (col=0; col < width; col++)
			for (row=0; row < height; row++)
				out[row+col*height] = (double)label[col+row*width];		
	}
	else
	{
		int width = mxGetN(prhs[0]);
		int height = mxGetM(prhs[0]);			
		Image<uchar> inputImage;
		MERCInputImage<uchar> input;		
		// Create Iamge
		inputImage.Resize(width,height,false);
		// Read the image from MATLAB
		for (col=0; col < mxGetN(prhs[0]); col++)
			for (row=0; row < mxGetM(prhs[0]); row++)
				inputImage.Access(col,row) = (uchar)mxGetPr(prhs[0])[row+col*mxGetM(prhs[0])];
		// Read the image for segmentation
		input.ReadImage(&inputImage,conn8);
		
		// Entropy rate superpixel segmentation
		merc.ClusteringTreeIF(input.nNodes_,input,kernel,sigma,lambda*1.0*nC,nC);
		vector<int> label = MERCOutputImage::DisjointSetToLabel(merc.disjointSet_);
					
		// Allocate memory for the labeled image.
		plhs[0] = mxCreateDoubleMatrix(height, width, mxREAL);
		out =  mxGetPr(plhs[0]);	
		// Fill in the labeled image
		for (col=0; col < width; col++)
			for (row=0; row < height; row++)
				out[row+col*height] = (double)label[col+row*width];		
	}
	
    return;
}