Commit 5267ce8b authored by Tomáš Oberhuber's avatar Tomáš Oberhuber
Browse files

Implementing image converter.

parent 5bd35eeb
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@

#include <core/tnlString.h>
#include <core/io/tnlImage.h>
#include <core/io/tnlRegionOfInterest.h>

template< typename Index = int >
class tnlPGMImage : public tnlImage< Index >
@@ -30,13 +31,30 @@ class tnlPGMImage : public tnlImage< Index >
      
      tnlPGMImage();
       
      bool open( const tnlString& fileName );
      bool openForRead( const tnlString& fileName );
      
      template< typename Real,
                typename Device,
                typename Vector >
      bool read( const tnlRegionOfInterest< Index > roi,
                 const tnlGrid< 2, Real, Device, Index >& grid,
                 Vector& vector );
      
      void close();
      
      ~tnlPGMImage();
      
      protected:
         
         bool readHeader( FILE* file );
         
         bool binary;
         
         IndexType maxColors;
         
         FILE* file;
         
         bool fileOpen;
};

#include <core/io/tnlPGMImage_impl.h>
+65 −9
Original line number Diff line number Diff line
@@ -24,22 +24,15 @@
template< typename Index >
tnlPGMImage< Index >::
tnlPGMImage() : 
   binary( false ), maxColors( 0 )
   binary( false ), maxColors( 0 ), fileOpen( false )
{
}

template< typename Index >
bool
tnlPGMImage< Index >::
open( const tnlString& fileName )
readHeader( FILE* file )
{
   FILE* file = fopen( fileName.getString(), "r" );
   if( ! file )
   {
      cerr << "Unable to open the file " << fileName << endl;
      return false;
   }

   char magicNumber[ 3 ];
   magicNumber[ 2 ] = 0;
   if( fread( magicNumber, sizeof( char ), 2, file ) != 2 )
@@ -69,6 +62,69 @@ open( const tnlString& fileName )
   return true;   
}

template< typename Index >
bool
tnlPGMImage< Index >::
openForRead( const tnlString& fileName )
{
   this->file = fopen( fileName.getString(), "r" );
   if( ! this->file )
   {
      cerr << "Unable to open the file " << fileName << endl;
      return false;
   }
   this->fileOpen = true;
   if( ! readHeader( this->file ) )
      return false;
   return true;
}

template< typename Index >
   template< typename Real,
             typename Device,
             typename Vector >
bool
tnlPGMImage< Index >::
read( const tnlRegionOfInterest< Index > roi,
      const tnlGrid< 2, Real, Device, Index >& grid,
      Vector& vector )
{
   typedef tnlGrid< 2, Real, Device, Index > GridType;
   typedef typename GridType::CoordinatesType CoordinatesType;
   
   Index i, j;
   for( i = 0; i < this->height; i ++ )
      for( j = 0; j < this->width; j ++ )
      {
         int col;
         if( this->binary ) col = getc( this->file );
         else fscanf( this->file, "%d", &col );
         if( roi.isIn( i, j ) )
         {
            Index cellIndex = grid.getCellIndex( CoordinatesType( j - roi.getLeft(),
                                                                  roi.getBottom() - 1 - i ) );
            vector.setElement( cellIndex, ( Real ) col / ( Real ) this->maxColors );
         }
      }
   return true;
}

template< typename Index >
void
tnlPGMImage< Index >::
close()
{
   if( this->fileOpen )
      fclose( file );
   this->fileOpen = false;
}

template< typename Index >
tnlPGMImage< Index >::
~tnlPGMImage()
{
   close();
}

#endif	/* TNLPGMIMAGE_IMPL_H */
+60 −0
Original line number Diff line number Diff line
/***************************************************************************
                          tnlRegionOfInterest.h  -  description
                             -------------------
    begin                : Jul 22, 2015
    copyright            : (C) 2015 by Tomas Oberhuber
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef TNLREGIONOFINTEREST_H
#define	TNLREGIONOFINTEREST_H

#include <config/tnlParameterContainer.h>
#include <mesh/tnlGrid.h>
#include <core/io/tnlImage.h>


template< typename Index = int >
class tnlRegionOfInterest
{
   public:
      
      tnlRegionOfInterest();
      
      bool setup( const tnlParameterContainer& parameters,
                  const tnlImage< Index >* image );
      
      bool check( const tnlImage< Index >* image ) const;
      
      Index getTop() const;
      
      Index getBottom() const;
      
      Index getLeft() const;
      
      Index getRight() const;
      
      Index getWidth() const;
      
      Index getHeight() const;
      
      bool isIn( const Index row, const Index column ) const;
      
   protected:
      
      Index top, bottom, left, right;
};

#include <core/io/tnlRegionOfInterest_impl.h>

#endif	/* TNLREGIONOFINTEREST_H */
+176 −0
Original line number Diff line number Diff line
/***************************************************************************
                          tnlRegionOfInterest.h  -  description
                             -------------------
    begin                : Jul 22, 2015
    copyright            : (C) 2015 by Tomas Oberhuber
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef TNLREGIONOFINTEREST_IMPL_H
#define	TNLREGIONOFINTEREST_IMPL_H

#include "tnlImage.h"


template< typename Index >
tnlRegionOfInterest< Index >::
tnlRegionOfInterest()
: top( -1 ), bottom( -1 ), left( -1 ), right( -1 )
{   
}
      
template< typename Index >
bool
tnlRegionOfInterest< Index >::
setup( const tnlParameterContainer& parameters,
       const tnlImage< Index >* image )
{
   const int roiTop    = parameters.getParameter< int >( "roi-top" );
   const int roiBottom = parameters.getParameter< int >( "roi-bottom" );
   const int roiRight  = parameters.getParameter< int >( "roi-right" );
   const int roiLeft   = parameters.getParameter< int >( "roi-left" );
    
   if( roiBottom < roiTop )
   {
      cerr << "Error: roi-bottom (" << roiBottom << ") is smaller than roi-top (" << roiTop << ")." << endl;
      return false;
   }
   if( roiRight < roiLeft )
   {
      cerr << "Error: roi-right (" << roiRight << ") is smaller than roi-left (" << roiLeft << ")." << endl;
      return false;
   }

   if( roiLeft == -1 )
        this->left = 0;
   else
   {
      if( roiLeft >= image->getWidth() )
      {
         cerr << "ROI left column is larger than image width ( " << image->getWidth() << ")." << cerr;
         return false;
      }
      this->left = roiLeft;
   }
    
   if( roiRight == -1 )
      this->right = image->getWidth();
   else
   {
      if( roiRight >= image->getWidth() )
      {
         cerr << "ROI right column is larger than image width ( " << image->getWidth() << ")." << cerr;
         return false;
      }
      this->right = roiRight;
   }
    
   if( roiTop == -1 )
      this->top = 0;
   else
   {
      if( roiTop >= image->getHeight() )
      {
         cerr << "ROI top line is larger than image height ( " << image->getHeight() << ")." << cerr;
         return false;
      }
      this->top = roiTop;
   }
    
   if( roiBottom == -1 )
      this->bottom = image->getHeight();
   else
   {
      if( roiBottom >= image->getHeight() )
      {
         cerr << "ROI bottom line is larger than image height ( " << image->getHeight() << ")." << cerr;
         return false;
      }
      this->bottom = roiBottom;
   }
   return true;
}

template< typename Index >
bool
tnlRegionOfInterest< Index >::
check( const tnlImage< Index >* image ) const
{
   if( top >= image->getHeight() ||
       bottom >= image->getHeight() ||
       left >= image->getWidth() ||
       right >= image->getWidth() )
      return false;
   return true;
}

template< typename Index >
Index
tnlRegionOfInterest< Index >::
getTop() const
{
   return this->top;
}

template< typename Index >
Index
tnlRegionOfInterest< Index >::
getBottom() const
{
   return this->bottom;
}

template< typename Index >
Index
tnlRegionOfInterest< Index >::
getLeft() const
{
   return this->left;
}

template< typename Index >
Index
tnlRegionOfInterest< Index >::
getRight() const
{
   return this->right;
}

template< typename Index >
Index
tnlRegionOfInterest< Index >::
getWidth() const
{
   return this->right - this->left;
}

template< typename Index >
Index
tnlRegionOfInterest< Index >::
getHeight() const
{
   return this->bottom - this->top;
}

template< typename Index >
bool
tnlRegionOfInterest< Index >::
isIn( const Index row, const Index column ) const
{
   if( row >= top && row < bottom &&
       column >= left && column < right )
      return true;
   return false;
}

#endif	/* TNLREGIONOFINTEREST_IMPL_H */
+26 −91
Original line number Diff line number Diff line
@@ -20,11 +20,13 @@
#include <core/mfilename.h>
#include <mesh/tnlGrid.h>
#include <core/io/tnlPGMImage.h>
#include <core/io/tnlRegionOfInterest.h>

void configSetup( tnlConfigDescription& config )
{
   config.addDelimiter( "General parameters" );
   config.addRequiredList < tnlString >( "input-files",   "Input files with images." );
   config.addRequiredList < tnlString >( "input-images",  "Input files with images." );
   config.addEntry        < tnlString >( "mesh-file",     "Mesh file.", "mesh.tnl" );
   config.addEntry        < bool >     ( "one-mesh-file", "Generate only one mesh file. All the images dimensions must be the same.", true );
   config.addEntry        < int >      ( "roi-top",       "Top (smaller number) line of the region of interest.", -1 );
   config.addEntry        < int >      ( "roi-bottom",    "Bottom (larger number) line of the region of interest.", -1 );
@@ -41,73 +43,15 @@ bool resolveRoi( const tnlParameterContainer& parameters,
                 int& right,
                 int& left )
{
    const int roiTop    = parameters.getParameter< int >( "roi-top" );
    const int roiBottom = parameters.getParameter< int >( "roi-bottom" );
    const int roiRight  = parameters.getParameter< int >( "roi-right" );
    const int roiLeft   = parameters.getParameter< int >( "roi-left" );
    
    if( roiLeft == -1 )
        left = 0;
    else
    {
        if( roiLeft >= image->getWidth() )
        {
            cerr << "ROI left column is larger than image width ( " << image->getWidth() << ")." << cerr;
            return false;
        }
        left = roiLeft;
    }
    
    if( roiRight == -1 )
        right = image->getWidth();
    else
    {
        if( roiRight >= image->getWidth() )
        {
            cerr << "ROI right column is larger than image width ( " << image->getWidth() << ")." << cerr;
            return false;
        }
        right = roiRight;
    }
    
    if( roiTop == -1 )
        top = 0;
    else
    {
        if( roiTop >= image->getHeight() )
        {
            cerr << "ROI top line is larger than image height ( " << image->getHeight() << ")." << cerr;
            return false;
        }
        top = roiTop;
    }
    
    if( roiBottom == -1 )
        bottom = image->getHeight();
    else
    {
        if( roiBottom >= image->getHeight() )
        {
            cerr << "ROI bottom line is larger than image height ( " << image->getHeight() << ")." << cerr;
            return false;
        }
        bottom = roiBottom;
    }
    return true;
}

template< typename Index,
          typename Grid >
bool setGrid( const tnlParameterContainer& parameters,
              const tnlImage< Index >* image,
bool setGrid( const tnlRegionOfInterest< Index >& roi,
              Grid& grid,
              bool verbose = false )
{
    int top, bottom, right, left;
    if( ! resolveRoi( parameters, image, top, bottom, right, left ) )
        return false;
    
    grid.setDimensions( right - left, bottom - top );
    grid.setDimensions( roi.getWidth(), roi.getHeight() );
    typename Grid::VertexType origin, proportions;
    origin.x() = 0.0;
    origin.y() = 0.0;
@@ -122,26 +66,6 @@ bool setGrid( const tnlParameterContainer& parameters,
    return true;
}

template< typename Index,
          typename Grid >
bool checkGrid( const tnlParameterContainer& parameters,
                const tnlImage< Index >* image,
                Grid& grid )
{
    int top, bottom, right, left;
    if( ! resolveRoi( parameters, image, top, bottom, right, left ) )
        return false;
    
    const int width = right - left;
    const int height = bottom - top;
    if( grid.getDimensions().x() == width &&
        grid.getDimensions().y() == height )
        return true;
    else
        return false;
}


template< typename Image,
          typename Grid,
          typename Vector >
@@ -154,30 +78,41 @@ bool readImage( const Image& image,

bool processImages( const tnlParameterContainer& parameters )
{
    const tnlList< tnlString >& inputFiles = parameters.getParameter< tnlList< tnlString > >( "input-files" );
    const tnlList< tnlString >& inputImages = parameters.getParameter< tnlList< tnlString > >( "input-images" );
    tnlString meshFile = parameters.getParameter< tnlString >( "mesh-file" );
    
    bool verbose = parameters.getParameter< bool >( "verbose" );
    
    tnlGrid< 2, double, tnlHost, int > grid;
    tnlVector< double, tnlHost, int > vector;
    for( int i = 0; i < inputFiles.getSize(); i++ )
    tnlRegionOfInterest< int > roi;
    for( int i = 0; i < inputImages.getSize(); i++ )
    {
        const tnlString& fileName = inputFiles[ i ];
        const tnlString& fileName = inputImages[ i ];
        cout << "Processing image file " << fileName << "... ";
        tnlPGMImage< int > pgmImage;
        if( pgmImage.open( fileName ) )
        if( pgmImage.openForRead( fileName ) )
        {
            cout << "PGM format detected ...";
            if( i == 0 )
                if( ! setGrid( parameters, &pgmImage, grid, verbose ) )
            {
                if( ! roi.setup( parameters, &pgmImage ) )
                    return false;
                else
                setGrid( roi, grid, verbose );
                vector.setSize( grid.getNumberOfCells() );
                cout << "Writing grid to file " << meshFile << endl;
                grid.save( meshFile );
            }
            else 
                if( ! checkGrid( parameters, &pgmImage, grid ) )
                if( ! roi.check( &pgmImage ) )
                    return false;
            if( ! pgmImage.read( vector ) )
            if( ! pgmImage.read( roi, grid, vector ) )
                return false;
            tnlString outputFileName( fileName );
            RemoveFileExtension( outputFileName );
            outputFileName += ".tnl";
            cout << "Writing image data to " << outputFileName << endl;
            vector.save( outputFileName );
        }
    }
}