extractOutlineFromImages.cpp
Go to the documentation of this file.
00001 
00033 #include <iostream>
00034 #include <opencv/cv.h>
00035 #include <opencv/highgui.h>
00036 #include <string>
00037 #include <vector>
00038 #include <fstream>
00039 
00040 #include "DUtils.h"
00041 #include "DUtilsCV.h"
00042 
00043 using namespace std;
00044 
00045 // ----------------------------------------------------------------------------
00046 
00047 void extractMask(const cv::Mat &image, cv::Mat &mask);
00048 void getSegmentedFilenames(const std::string &list_file, 
00049   std::vector<std::string> &normal_files,
00050   std::vector<std::string> &segmented_files,
00051   const std::string &segmented_model_dir);
00052 void generateMasks(const std::vector<std::string> &normal_files,
00053   const std::vector<std::string> &segmented_files,
00054   const std::string &out_dir);
00055 
00056 // ----------------------------------------------------------------------------
00057 
00058 int main(int argc, char *argv[])
00059 {
00060 
00061   if(argc < 4)
00062   {
00063     cout << "Usage: " << argv[0] << " <list.rd.out file> <out dir> <segmented dir>" << endl;
00064     return 1;
00065   }
00066 
00067   std::string list_file = argv[1];
00068   std::string out_dir = argv[2];
00069   std::string segmented_model_dir = argv[3];
00070   
00071   vector<string> segmented_files, normal_files;
00072   
00073   try
00074   {
00075     cout << "-- Getting filenames..." << endl;
00076     getSegmentedFilenames(list_file, normal_files, segmented_files, segmented_model_dir);
00077 
00078     cout << "-- Generating masks..." << endl;
00079     generateMasks(normal_files, segmented_files, out_dir);
00080   }
00081   catch(std::string ex)
00082   {
00083     cout << ex << endl;
00084   }
00085 
00086 }
00087 
00088 // ----------------------------------------------------------------------------
00089 
00090 void getSegmentedFilenames(const std::string &list_file, 
00091   std::vector<std::string> &normal_files,
00092   std::vector<std::string> &segmented_files,
00093   const std::string &segmented_model_dir)
00094 {
00095   // assumes segmented files are in a directory with the same
00096   // name as the original, but with the suffix "SinFondo"
00097   
00098   segmented_files.clear();
00099   normal_files.clear();
00100   
00101   fstream f(list_file.c_str(), ios::in);
00102   if(!f.is_open())
00103   {
00104     throw(string("Could not open file ") + list_file);
00105     return;
00106   }
00107   
00108   string line;
00109   while(!f.eof())
00110   {
00111     getline(f, line);
00112     if(!f.eof() && !line.empty())
00113     {
00114       string path, name, ext;
00115       DUtils::FileFunctions::FileParts(line, path, name, ext);
00116       
00117       normal_files.push_back(line);
00118 
00119       segmented_files.push_back(
00120         segmented_model_dir + "/" + name + "." + ext);
00121       
00122 //      segmented_files.push_back(
00123 //        path + "SinFondo/" + name + "." + ext);
00124     }
00125   }
00126   
00127   f.close();
00128 }
00129 
00130 // ----------------------------------------------------------------------------
00131 
00132 void generateMasks(const std::vector<std::string> &normal_files,
00133   const std::vector<std::string> &segmented_files,
00134   const std::string &out_dir)
00135 {
00136   vector<string>::const_iterator nit, sit;
00137   nit = normal_files.begin();
00138   sit = segmented_files.begin();
00139 
00140   for(; nit != normal_files.end(); ++nit, ++sit)
00141   {
00142     int idx = nit - normal_files.begin();
00143     
00144     //string path, filename, ext;
00145     //DUtils::FileFunctions::FileParts(*nit, path, filename, ext);
00146     
00147     cv::Mat im = cv::imread(*sit, 0);
00148     
00149     if(im.empty())
00150     {
00151       throw string("Could not open image " + *sit);
00152     }
00153     
00154     cv::Mat mask;
00155     extractMask(im, mask);
00156 
00157     char buffer[512];    
00158     sprintf(buffer, "%s/im%02d_mask.png", out_dir.c_str(), idx);
00159     cv::imwrite(buffer, mask);
00160   }
00161 
00162 }
00163 
00164 // ----------------------------------------------------------------------------
00165 
00166 struct xy { 
00167   int x, y; 
00168   xy(int _x, int _y): x(_x), y(_y) {} 
00169 };
00170 
00171 void extractMask(const cv::Mat &image, cv::Mat &mask)
00172 {
00173   mask.create(image.rows, image.cols, CV_8U);
00174   mask = 255;
00175   
00176   // set 1 if foreground pixels
00177   // assume pixel 0,0 is always background and that background is connected
00178   
00179   cv::Mat visited(image.rows, image.cols, CV_8U);
00180   visited = cv::Scalar(0);
00181   
00182   vector<xy> queue;
00183   queue.push_back(xy(0,0));
00184   visited.at<unsigned char>(0,0) = 1;
00185 
00186   // 4-connectivity
00187   const int N = 4;
00188   const int dx[N] = {-1, 0, +1, 0};
00189   const int dy[N] = {0, -1, 0, +1};
00190 
00191   while(!queue.empty())
00192   {
00193     xy p = queue.back();
00194     queue.pop_back();
00195 
00196     for(int i = 0; i < N; ++i)
00197     {
00198       int x = p.x + dx[i];
00199       int y = p.y + dy[i];
00200       
00201       if(x >= 0 && x < image.cols && y >= 0 && y < image.rows &&
00202         visited.at<unsigned char>(y,x) == 0)
00203       {
00204         visited.at<unsigned char>(y,x) = 1;
00205         
00206         // original images are jpg, so there are black pixels not so black
00207         if(image.at<unsigned char>(y,x) < 5)
00208         {
00209           queue.push_back(xy(x,y));
00210           mask.at<unsigned char>(y,x) = 0;
00211         }
00212       } // if not visited
00213     } // for each neighbor
00214   } // for each item in the queue
00215   
00216 }
00217 
00218 // ----------------------------------------------------------------------------
00219 


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:31:08