Commit d28ad199 authored by aschwarzkopf's avatar aschwarzkopf
Browse files

[ADD #309] Added feature to save elevation images as bmp files

 * This is a first important intermediate step for making sure having a
 * consistent data structure that has an elevation image which has an
 * important role in building detection.
parent 31df550c
......@@ -41,17 +41,18 @@
#include "core/kernel/WModuleInputData.h"
#include "WMBuildingsDetection.xpm"
#include "WMBuildingsDetection.h"
#include "structure/WOTree.h"
#include "structure/WOctree.h"
// This line is needed by the module loader to actually find your module.
//W_LOADABLE_MODULE( WMBuildingsDetection )
W_LOADABLE_MODULE( WMBuildingsDetection )
//TODO(aschwarzkopf): Reenable above after solving the toolbox problem
WMBuildingsDetection::WMBuildingsDetection():
WModule(),
m_propCondition( new WCondition() )
{
m_tree = new WOTree( 0 );
m_tree = new WOctree( 0 );
m_elevationImage = new WQuadTree( 0 );
}
WMBuildingsDetection::~WMBuildingsDetection()
......@@ -91,6 +92,15 @@ void WMBuildingsDetection::connectors()
void WMBuildingsDetection::properties()
{
m_nbPoints = m_infoProperties->addProperty( "Points: ", "Input points count.", 0 );
m_xMin = m_infoProperties->addProperty( "X min.: ", "Minimal x coordinate of all input points.", 0.0 );
m_xMax = m_infoProperties->addProperty( "X max.: ", "Maximal x coordinate of all input points.", 0.0 );
m_yMin = m_infoProperties->addProperty( "Y min.: ", "Minimal y coordinate of all input points.", 0.0 );
m_yMax = m_infoProperties->addProperty( "Y max.: ", "Maximal y coordinate of all input points.", 0.0 );
m_zMin = m_infoProperties->addProperty( "Z min.: ", "Minimal z coordinate of all input points.", 0.0 );
m_zMax = m_infoProperties->addProperty( "Z max.: ", "Maximal z coordinate of all input points.", 0.0 );
// ---> Put the code for your properties here. See "src/modules/template/" for an extensively documented example.
m_stubSize = m_properties->addProperty( "Stub size: ",
"Size of tetraeders that are used to depict points.", 0.6, m_propCondition );
......@@ -111,6 +121,20 @@ void WMBuildingsDetection::properties()
"Enabling this option you must have 32GB RAM depicting a 400MB"
"las file.", false, m_propCondition );
boost::shared_ptr< WItemSelection > imageModes( boost::shared_ptr< WItemSelection >( new WItemSelection() ) );
imageModes->addItem( "Minimals", "Minimal elevation values." );
imageModes->addItem( "Maximals", "Maximal elevation values." );
imageModes->addItem( "Point count", "Store point count to each pixel." );
m_elevImageMode = m_properties->addProperty( "Color mode", "Choose one of the available colorings.", imageModes->getSelectorFirst(),
m_propCondition );
WPropertyHelper::PC_SELECTONLYONE::addTo( m_elevImageMode );
m_elevationImageExportablePath = m_properties->addProperty( "Elev. image:",
"Target file path of the exportable elevation image *.bmp file",
WPathHelper::getAppPath() );
m_exportTriggerProp = m_properties->addProperty( "Do read", "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
WModule::properties();
}
......@@ -141,9 +165,11 @@ void WMBuildingsDetection::moduleMain()
boost::shared_ptr< WDataSetPoints > points = m_input->getData();
std::cout << "Execute cycle\r\n";
WItemSelector elevImageModeSelector = m_elevImageMode->get( true );
if ( points )
{
m_tree = new WOTree( m_detailDepthLabel->get( true ) );
m_tree = new WOctree( m_detailDepthLabel->get( true ) );
m_elevationImage = new WQuadTree( m_detailDepthLabel->get( true ) );
WDataSetPoints::VertexArray verts = points->getVertices();
WDataSetPoints::ColorArray colors = points->getColors();
size_t count = verts->size()/3;
......@@ -180,9 +206,21 @@ void WMBuildingsDetection::moduleMain()
}
m_progressStatus->increment( 1 );
m_tree->registerPoint( x, y, z );
m_elevationImage->registerPoint( x, y, z );
}
m_output->updateData( m_showTrianglesInsteadOfOctreeCubes->get( true )
?tmpMesh :m_tree->getOutline( ) );
m_nbPoints->set( count );
m_xMin->set( m_elevationImage->getRootNode()->getXMin() );
m_xMax->set( m_elevationImage->getRootNode()->getXMax() );
m_yMin->set( m_elevationImage->getRootNode()->getYMin() );
m_yMax->set( m_elevationImage->getRootNode()->getYMax() );
m_zMin->set( m_elevationImage->getRootNode()->getElevationMin() );
m_zMax->set( m_elevationImage->getRootNode()->getElevationMax() );
if( m_exportTriggerProp->get( true ) )
m_elevationImage->exportElevationImage( m_elevationImageExportablePath->get().c_str(),
elevImageModeSelector.getItemIndexOfSelected( 0 ) );
m_exportTriggerProp->set( WPVBaseTypes::PV_TRIGGER_READY, true );
m_progressStatus->finish();
}
......
......@@ -42,7 +42,8 @@
#include <osg/ShapeDrawable>
#include <osg/Geode>
#include "core/dataHandler/WDataSetPoints.h"
#include "structure/WOTree.h"
#include "structure/WOctree.h"
#include "structure/WQuadTree.h"
......@@ -168,9 +169,38 @@ private:
*/
WGEShader::RefPtr m_shader;
/**
* Info tab property: Input points count.
*/
WPropInt m_nbPoints;
/**
* Info tab property: Minimal x value of input x coordunates.
*/
WPropDouble m_xMin;
/**
* Info tab property: Maximal x value of input x coordunates.
*/
WPropDouble m_xMax;
/**
* Info tab property: Minimal y value of input x coordunates.
*/
WPropDouble m_yMin;
/**
* Info tab property: Maximal y value of input x coordunates.
*/
WPropDouble m_yMax;
/**
* Info tab property: Minimal z value of input x coordunates.
*/
WPropDouble m_zMin;
/**
* Info tab property: Maximal z value of input x coordunates.
*/
WPropDouble m_zMax;
/**
* Voxel count that is cut off and kept regarding the ISO value.
*/
WPropDouble m_stubSize;
/**
......@@ -191,6 +221,19 @@ private:
*/
WPropBool m_showTrianglesInsteadOfOctreeCubes;
/**
* Mode of the elevation image to display
* 0: Minimal Z value of each X/Y bin coordinate.
* 1: Maximal Z value of each X/Y bin coordinate.
* 2: Point count of each X/Y bin coordinate.
*/
WPropSelection m_elevImageMode;
/**
* Path of the exportable elevation image *.bmp file.
*/
WPropFilename m_elevationImageExportablePath; //!< The mesh will be read from this file.
WPropTrigger m_exportTriggerProp; //!< This property triggers the actual reading,
/**
* Instance for applying drawable geoms.
*/
......@@ -203,7 +246,12 @@ private:
/**
* Octree node used for the data set points analysis.
*/
WOTree* m_tree;
WOctree* m_tree;
/**
* This is the elevation image of the whole data set.
* It depicts some statistical Z coordinate information of each X/Y-coordinate.
*/
WQuadTree* m_elevationImage;
};
#endif // WMBUILDINGSDETECTION_H
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2013 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <stdio.h>
#include <iostream>
#include <fstream>
#include "WBmpImage.h"
WBmpImage::WBmpImage( size_t sizeX, size_t sizeY )
{
resizeImage( sizeX, sizeY );
}
WBmpImage::~WBmpImage()
{
resizeImage( 0, 0 );
}
size_t WBmpImage::getSizeX()
{
return m_sizeX;
}
size_t WBmpImage::getSizeY()
{
return m_sizeY;
}
void WBmpImage::resizeImage( size_t sizeX, size_t sizeY )
{
m_sizeX = sizeX;
m_sizeY = sizeY;
size_t size = sizeX * sizeY;
m_dataR.reserve( size );
m_dataG.reserve( size );
m_dataB.reserve( size );
m_dataR.resize( size );
m_dataG.resize( size );
m_dataB.resize( size );
for( size_t index = 0; index < size; index++ )
{
m_dataB[index] = 0;
m_dataG[index] = 0;
m_dataB[index] = 0;
}
}
size_t WBmpImage::getR( size_t x, size_t y )
{
if( x >= m_sizeX || y >= m_sizeY ) return 0;
return m_dataR[getIndex( x, y )];
}
size_t WBmpImage::getG( size_t x, size_t y )
{
if( x >= m_sizeX || y >= m_sizeY ) return 0;
return m_dataG[getIndex( x, y )];
}
size_t WBmpImage::getB( size_t x, size_t y )
{
if( x >= m_sizeX || y >= m_sizeY ) return 0;
return m_dataB[getIndex( x, y )];
}
size_t WBmpImage::getA( size_t x, size_t y )
{
if( x >= m_sizeX || y >= m_sizeY ) return 0;
return 255;
}
void WBmpImage::setPixel( size_t x, size_t y, size_t intensity )
{
setPixel( x, y, intensity, intensity, intensity );
}
void WBmpImage::setPixel( size_t x, size_t y, size_t r, size_t g, size_t b )
{
if( x >= m_sizeX || y >= m_sizeY ) return;
size_t index = getIndex( x, y );
m_dataR[index] = r < 256 ?r :255;
m_dataG[index] = g < 256 ?g :255;
m_dataB[index] = b < 256 ?b :255;
}
size_t WBmpImage::getIndex( size_t x, size_t y )
{
return x + m_sizeX * y;
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2013 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WBMPIMAGE_H
#define WBMPIMAGE_H
#include <vector>
/**
* Image object. Currently it's used for saving bmp files.
*/
class WBmpImage
{
public:
/**
* Image constructor that also defines the main parameters.
* \param sizeX Image width.
* \param sizeY Image height.
*/
WBmpImage( size_t sizeX, size_t sizeY );
/**
* Image container destructor.
*/
virtual ~WBmpImage();
/**
* Returns the image width.
* \return The image width.
*/
size_t getSizeX();
/**
* Returns the image height.
* \return The image height.
*/
size_t getSizeY();
/**
* Resizes and clears the image.
* \param sizeX Image width.
* \param sizeY Image height.
*/
void resizeImage( size_t sizeX, size_t sizeY );
/**
* Returns the red color value of a pixel.
* \param x Pixel index on X axis (0 to width-1).
* \param y Pixel index on Y axis (0 to height-1).
* \return The red color value (0 to 255).
*/
size_t getR( size_t x, size_t y );
/**
* Returns the green color value of a pixel.
* \param x Pixel index on X axis (0 to width-1).
* \param y Pixel index on Y axis (0 to height-1).
* \return The green color value (0 to 255).
*/
size_t getG( size_t x, size_t y );
/**
* Returns the blue color value of a pixel.
* \param x Pixel index on X axis (0 to width-1).
* \param y Pixel index on Y axis (0 to height-1).
* \return The blue color value (0 to 255).
*/
size_t getB( size_t x, size_t y );
/**
* Returns the opacity value of a pixel.
* \param x Pixel index on X axis (0 to width-1).
* \param y Pixel index on Y axis (0 to height-1).
* \return The opacity value (0 to 255).
*/
size_t getA( size_t x, size_t y );
/**
* Sets a color within a pixel using just an intensity.
* \param x Pixel index on X axis (0 to width-1).
* \param y Pixel index on Y axis (0 to height-1).
* \param intensity Value that will be put to all color values equally (0 to 255).
*/
void setPixel( size_t x, size_t y, size_t intensity );
/**
* Sets a color within a pixel.
* \param x Pixel index on X axis (0 to width-1).
* \param y Pixel index on Y axis (0 to height-1).
* \param r The red color intensity (0 to 255).
* \param g The green color intensity (0 to 255).
* \param b The blue color intensity (0 to 255).
*/
void setPixel( size_t x, size_t y, size_t r, size_t g, size_t b );
private:
/**
* Returns the color data vector index using X and Y coordinates.
* \param x X coordinate of the image.
* \param y Y coordinate of the image.
* \return The suuitable color data vector index (e. g. for m_dataG).
*/
size_t getIndex( size_t x, size_t y );
/**
* Image width.
*/
size_t m_sizeX;
/**
* Image height.
*/
size_t m_sizeY;
/**
* Image red color intensity data. The order corresponds the following pixel traversing.
* It traverses linewise starting at Y=0 from first to last X value.
*/
std::vector<size_t> m_dataR;
/**
* Image green color intensity data. The order corresponds the following pixel traversing.
* It traverses linewise starting at Y=0 from first to last X value.
*/
std::vector<size_t> m_dataG;
/**
* Image blue color intensity data. The order corresponds the following pixel traversing.
* It traverses linewise starting at Y=0 from first to last X value.
*/
std::vector<size_t> m_dataB;
};
#endif // WBMPIMAGE_H
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2013 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
//Source code source: http://stackoverflow.com/questions/2654480/writing-bmp-image-in-pure-c-c-without-other-libraries
#include <stdio.h>
#include <iostream>
#include <fstream>
#include "WBmpSaver.h"
WBmpSaver::WBmpSaver()
{
}
WBmpSaver::~WBmpSaver()
{
}
void WBmpSaver::saveImage( WBmpImage* image, const char* path )
{
std::ofstream stream;
stream.open( path );
std::cout << "!!! this is Savefile !!!" << std::endl;
// mimeType = "image/bmp";
unsigned char file[14] = {
'B', 'M', // magic
0, 0, 0, 0, // size in bytes
0, 0, // app data
0, 0, // app data
40+14, 0, 0, 0 // start of data offset
};
unsigned char info[40] = {
40, 0, 0, 0, // info hd size
0, 0, 0, 0, // width
0, 0, 0, 0, // heigth
1, 0, // number color planes
24, 0, // bits per pixel
0, 0, 0, 0, // compression is none
0, 0, 0, 0, // image bits size
0x13, 0x0B, 0, 0, // horz resoluition in pixel / m
0x13, 0x0B, 0, 0, // vert resolutions (0x03C3 = 96 dpi, 0x0B13 = 72 dpi)
0, 0, 0, 0, // #colors in pallete
0, 0, 0, 0, // #important colors
};
int w = image->getSizeX();
int h = image->getSizeY();
int padSize = w%4; //Fixed bug in original code. Earlier assign = (4-w%4)%4
int sizeData = w*h*3 + h*padSize;
int sizeAll = sizeData + sizeof( file ) + sizeof( info );
file[2] = (unsigned char)( sizeAll );
file[3] = (unsigned char)( sizeAll>> 8 );
file[4] = (unsigned char)( sizeAll>>16 );
file[5] = (unsigned char)( sizeAll>>24 );
info[4] = (unsigned char)( w );
info[5] = (unsigned char)( w>> 8);
info[6] = (unsigned char)( w>>16);
info[7] = (unsigned char)( w>>24);
info[8] = (unsigned char)( h );
info[9] = (unsigned char)( h>>8 );
info[10] = (unsigned char)( h>>16 );
info[11] = (unsigned char)( h>>24 );
info[24] = (unsigned char)( sizeData );
info[25] = (unsigned char)( sizeData>>8 );
info[26] = (unsigned char)( sizeData>>16 );
info[27] = (unsigned char)( sizeData>>24 );
stream.write( ( char* )file, sizeof( file ) );
stream.write( ( char* )info, sizeof( info ) );
unsigned char pad[3] = {0, 0, 0};
for( int y = 0; y < h; y++ )
{
for( int x = 0; x < w; x++ )
{
unsigned char pixel[3];
pixel[0] = image->getB( x, y );
pixel[1] = image->getG( x, y );
pixel[2] = image->getR( x, y );
stream.write( ( char* )pixel, 3 );
}
stream.write( ( char* )( pad ), padSize );
}
stream.close();
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2013 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WBMPSAVER_H
#define WBMPSAVER_H
#include <stdio.h>
#include <iostream>
#include <fstream>
#include "WBmpImage.h"
/**
* Class that saves an image to a bmp file
*/
class WBmpSaver
{
public:
/**
* Bmp saver constructor
*/
WBmpSaver();
/**
* Bmp saver destructor
*/
virtual ~WBmpSaver();
/**
* Static method to save an image as a bmp file.
* \param image The image to store
* \param path Target image file path.
*/
static void saveImage( WBmpImage*</