www.pudn.com > reacTIVision-1.3.rar > ragbuilder.cpp


/***************************************************************************
                          ragfactory.cpp  -  description
                             -------------------
    begin                : Wed Nov 26 2003
    copyright            : (C) 2003 by Enrico Costanza
    email                : e.costanza@ieee.org
 ***************************************************************************/


/***************************************************************************
 *                                                                         *
 *	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.                                    *
 *                                                                         *
 *  This program 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 General Public License for more details.                           *
 *                                                                         *
 *  You should have received a copy of the GNU General Public License      *
 *  along with this program; if not, write to the Free Software            *
 *  Foundation, Inc., 59 Temple Place, Suite 330                           *
 *  Boston, MA  02111-1307  USA                                            *
 *                                                                         *
 ***************************************************************************/


/*  Changes

	Code optimization by Jorge M Santiago

*/

//
#include "ragbuilder.h"

using std::cout;
using std::endl;	
   
RAGBuilder::RAGBuilder( unsigned char *in_image, int in_width, int in_height,
	unsigned char *in_threshold, RegionAdjacencyGraph *in_rag, bool *in_stored )
	: _image(in_image), _width(in_width), _height(in_height),
		_threshold(in_threshold), _rag(in_rag), _stored(in_stored){
	// do nothing?

	//_stored = new bool[_width*_height];
	memset(_stored,0,_width*_height*sizeof(bool));
}

RAGBuilder::~RAGBuilder(){
	//delete [] _stored;
}

int RAGBuilder::buildRAG( const int &maxRegions ){
	// first pixel
	_rag->appendToRegion( DTPoint(0,0), 0 );
	if( *_image > *_threshold ){
		_rag->_region[0]->_white = true;
	}else{ 
		_rag->_region[0]->_white = false; 
	}
	*(_rag->_labelsMap) = _rag->getNewLabel();
	_rag->_region[0]->appendToLabelPtrList( *(_rag->_labelsMap) );
  
	int x;
	int y;

	unsigned char *current;
	unsigned char *above;
	unsigned char *left;
	unsigned char *aboveLeft;

	unsigned char *currentThreshold;
	unsigned char *aboveThreshold;
	unsigned char *leftThreshold;
	unsigned char *aboveLeftThreshold;

	int **currentLabel;
	int **aboveLabel;
	int **leftLabel;
	int **aboveLeftLabel;

	//first row
	{
		y=0;
		current = _image + 1;
		left = _image;
		currentThreshold = _threshold + 1;
		leftThreshold = _threshold;
		currentLabel = (_rag->_labelsMap)+1;
		leftLabel = _rag->_labelsMap;
		for(x=1;x<_width;x++){
			if( (*current >= *currentThreshold) == (*left >= *leftThreshold) ){
				// current is the same colour as left
				// set the label of the current pel to be the same as left
				//*currentLabel = *leftLabel;
				(_rag->_labelsMap)[x+y*_width] = (_rag->_labelsMap)[x+y*_width-1];
				//*currentLabel = (_rag->_labelsMap)[x+y*_width+1];
				// add current to the region of left
				_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
			}else{
				// current is of a different colour from left
				// create a new label
				//*currentLabel = _rag->_used++;
				*currentLabel = _rag->getNewLabel();
				_rag->_region[**currentLabel]->appendToLabelPtrList( *currentLabel );
				// set the colour of the new region
				if( (*current >= *currentThreshold) ){
					_rag->_region[**currentLabel]->_white = true;
				}else{ _rag->_region[**currentLabel]->_white = false; }
				// add current to the new region
				_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
				// link the new region to the one on the left
				_rag->link(**currentLabel,**leftLabel);
			}
			current++;
			left++;
			currentThreshold++;
			leftThreshold++;
			currentLabel++;
			leftLabel++;

			//std::cout << "(x,y): (" << x << "," << y << ")";
			//std::cout << " l: " << *leftLabel << " " ;
			//std::cout << ((*left>*leftThreshold)?("w"):("b")) << std::endl;
		}
	}

	for(y=1;y<_height;y++){
	// deal with the first pixel of the row
		x=0;
		current = _image+y*_width;
		above = _image+(y-1)*_width;
		currentThreshold = _threshold+y*_width;
		aboveThreshold = _threshold+(y-1)*_width;
		currentLabel = (_rag->_labelsMap)+y*_width;
		aboveLabel = (_rag->_labelsMap)+(y-1)*_width;
		if( (*current >= *currentThreshold) == (*above >= *aboveThreshold) ){
			// current is the same colour as above
			// set the label of the current pel to be the same as above
			*currentLabel = *aboveLabel;
			//(_rag->_labelsMap)[x+y*_width] = (_rag->_labelsMap)[x+(y-1)*_width];
			//if( (_rag->_labelsMap)[x+y*_width] != (_rag->_labelsMap)[x+(y-1)*_width] ){
			//	cout << "label copy failed!!!" << endl;
			//}
			// add current to the region of above
			_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
		}else{
			// current is of a different colour from above
			// create a new label
			*currentLabel = _rag->getNewLabel();
			_rag->_region[**currentLabel]->appendToLabelPtrList( *currentLabel );
			// set the colour of the new region
			if( (*current >= *currentThreshold) ){
				_rag->_region[**currentLabel]->_white = true;
			}else{ _rag->_region[0]->_white = true; }
			// add current to the new region
			_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
			// link the new region to the one above
			_rag->link(**currentLabel,**aboveLabel);
		}

		current = _image+y*_width+1;
		above = _image+(y-1)*_width+1;
		left = _image+y*_width;
		aboveLeft = _image+(y-1)*_width;

		currentThreshold = _threshold+y*_width+1;
		aboveThreshold = _threshold+(y-1)*_width+1;
		leftThreshold = _threshold+y*_width;
		aboveLeftThreshold = _threshold+(y-1)*_width;

		currentLabel = (_rag->_labelsMap)+y*_width+1;
		aboveLabel = (_rag->_labelsMap)+(y-1)*_width+1;
		leftLabel = (_rag->_labelsMap)+y*_width;
		aboveLeftLabel = (_rag->_labelsMap)+(y-1)*_width;

		for(x=1;x<_width;x++){
			//if( (_rag->_region[*aboveLabel]->isEmpty()) || (_rag->_region[*leftLabel]->isEmpty()) ){
			//	std::cout << "Empty regions here!" << std::endl;
			//}

			bool currentEqualsLeft = (*current >= *currentThreshold) == (*left >= *leftThreshold);
			bool currentEqualsAbove = (*current >= *currentThreshold) == (*above >= *aboveThreshold);
			if( currentEqualsAbove && !currentEqualsLeft ){
				// set the label of the current pel to be the same as the one above
				*currentLabel = *aboveLabel;
				// add current to the region of the one above
				_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
				// link the region containing current and the region containing the left neighbour
				// in the RAG if they are not already linked
				//if( !_rag->check(**currentLabel,**leftLabel) ){
					_rag->link(**currentLabel,**leftLabel);
				//}
			}else if( !currentEqualsAbove && currentEqualsLeft ){
				// set the label of the current pel to be the same as the one on the left
				*currentLabel = *leftLabel;
				// add current to the region of the pel on the left
				_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
				// link the region containing current and the region containing the neighbour above
				// in the RAG if they are not already linked
				//if( !_rag->check(**currentLabel,**aboveLabel) ){
					_rag->link(**currentLabel,**aboveLabel);
				//}
			}else if( !currentEqualsAbove && !currentEqualsLeft ){
				// in this case current is different from both "direct" neighbours
				// if current is black, the neighbour above left needs to be checked
				if( *current < *currentThreshold ){
					// if the left above pel is black as well..
					if( *aboveLeft < *aboveLeftThreshold ){
						// .. the two are part of the same region
						// set the label of the current pel to be the same as the one above left
						*currentLabel = *aboveLeftLabel;
						// add current to the region of the pel above left
						_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
					}else{
						// in this case current is black and the 3 neighbours are white
						// create a new label for current
						*currentLabel = _rag->getNewLabel();
						_rag->_region[**currentLabel]->appendToLabelPtrList( *currentLabel );
						// no need to set the colour of the new region
						// it is black, which is the default
						_rag->_region[**currentLabel]->_white = false;
						// add current to the new region
						_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
						// link the new region to the one above (just need to link current to any of the neighbours)
						_rag->link(**currentLabel,**aboveLabel);
					}// end if..else (*aboveLeft < *aboveLeftThreshold)
				}else{ // current is white and the two "direct" neighbours are black
					// create a new white region for current
					*currentLabel = _rag->getNewLabel();
					_rag->_region[**currentLabel]->appendToLabelPtrList( *currentLabel );
					_rag->_region[**currentLabel]->_white = true;
					_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
					// if the left and above neighbours are not in the same regions
					if( **leftLabel != **aboveLabel ){
						// merge the two regions
						_rag->merge(**aboveLabel,**leftLabel);
					}
					// link the new region to one of the two
					_rag->link(**currentLabel,**aboveLabel);
				}
			}else{ // current is the same colour as left and above
				if( **leftLabel != **aboveLabel ){
					// the pels left and above are in fact in the same region
					// merge the two regions
					/*mk int r =*/ _rag->merge(**aboveLabel,**leftLabel);
					//if( r == 1 ){
						*currentLabel = *aboveLabel;
					//}else{
					//	*currentLabel = *leftLabel;
					//}
				}else{
					// set the label of the current pel to be the same as the one above
					*currentLabel = *leftLabel;
				}
				// add current to the region containing the neighbours
				_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
			}

			++current;
			++above;
			++left;
			++aboveLeft;

			++currentThreshold;
			++aboveThreshold;
			++leftThreshold;
			++aboveLeftThreshold;

			++currentLabel;
			++aboveLabel;
			++leftLabel;
			++aboveLeftLabel;

			// check the graph size
			// if it's above a threshold
			// abort the construction 
			if( !(_rag->_used < maxRegions) ){
				return -1;
				// clean up?
			}
		}
		//std::cout << "(x,y): (" << "x" << "," << y << ")" << std::endl;
	}

	return 0;
}

//

int RAGBuilder::buildRAGBorder( const int &maxRegions ){
	// first pixel
	_rag->appendToRegion( DTPoint(0,0), 0 );
	if( *_image > *_threshold ){
		_rag->_region[0]->_white = true;
	}else{ _rag->_region[0]->_white = false; }
	*(_rag->_labelsMap) = _rag->getNewLabel();
	_rag->_region[0]->appendToLabelPtrList( *(_rag->_labelsMap) );

	int x;
	int y;

	unsigned char *current;
	unsigned char *above;
	unsigned char *left;
	unsigned char *aboveLeft;

	unsigned char *currentThreshold;
	unsigned char *aboveThreshold;
	unsigned char *leftThreshold;
	unsigned char *aboveLeftThreshold;

	int **currentLabel;
	int **aboveLabel;
	int **leftLabel;
	int **aboveLeftLabel;

	//first row
	{
		y=0;
		current = _image + 1;
		left = _image;
		currentThreshold = _threshold + 1;
		leftThreshold = _threshold;
		currentLabel = (_rag->_labelsMap)+1;
		leftLabel = _rag->_labelsMap;
		for(x=1;x<_width;x++){
			if( (*current >= *currentThreshold) == (*left >= *leftThreshold) ){
				// current is the same colour as left
				// set the label of the current pel to be the same as left
				//*currentLabel = *leftLabel;
				(_rag->_labelsMap)[x+y*_width] = (_rag->_labelsMap)[x+y*_width-1];
				//*currentLabel = (_rag->_labelsMap)[x+y*_width+1];
				// add current to the region of left
				_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
			}else{
				// current is of a different colour from left
				// create a new label
				//*currentLabel = _rag->_used++;
				*currentLabel = _rag->getNewLabel();
				_rag->_region[**currentLabel]->appendToLabelPtrList( *currentLabel );
				// set the colour of the new region
				if( (*current >= *currentThreshold) ){
					_rag->_region[**currentLabel]->_white = true;
				}else{ _rag->_region[**currentLabel]->_white = false; }
				// add current to the new region
				_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
				// link the new region to the one on the left
				_rag->link(**currentLabel,**leftLabel);
			}
			current++;
			left++;
			currentThreshold++;
			leftThreshold++;
			currentLabel++;
			leftLabel++;

			//std::cout << "(x,y): (" << x << "," << y << ")";
			//std::cout << " l: " << *leftLabel << " " ;
			//std::cout << ((*left>*leftThreshold)?("w"):("b")) << std::endl;
		}
	}

	for(y=1;y<_height;y++){
	// deal with the first pixel of the row
		x=0;
		current = _image+y*_width;
		above = _image+(y-1)*_width;
		currentThreshold = _threshold+y*_width;
		aboveThreshold = _threshold+(y-1)*_width;
		currentLabel = (_rag->_labelsMap)+y*_width;
		aboveLabel = (_rag->_labelsMap)+(y-1)*_width;
		if( (*current >= *currentThreshold) == (*above >= *aboveThreshold) ){
			// current is the same colour as above
			// set the label of the current pel to be the same as above
			*currentLabel = *aboveLabel;
			//(_rag->_labelsMap)[x+y*_width] = (_rag->_labelsMap)[x+(y-1)*_width];
			//if( (_rag->_labelsMap)[x+y*_width] != (_rag->_labelsMap)[x+(y-1)*_width] ){
			//	cout << "label copy failed!!!" << endl;
			//}
			// add current to the region of above
			_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
		}else{
			// current is of a different colour from above
			// create a new label
			*currentLabel = _rag->getNewLabel();
			_rag->_region[**currentLabel]->appendToLabelPtrList( *currentLabel );
			// set the colour of the new region
			if( (*current >= *currentThreshold) ){
				_rag->_region[**currentLabel]->_white = true;
			}else{ _rag->_region[0]->_white = true; }
			// add current to the new region
			_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
			// link the new region to the one above
			_rag->link(**currentLabel,**aboveLabel);
		}

		current = _image+y*_width+1;
		above = _image+(y-1)*_width+1;
		left = _image+y*_width;
		aboveLeft = _image+(y-1)*_width;

		currentThreshold = _threshold+y*_width+1;
		aboveThreshold = _threshold+(y-1)*_width+1;
		leftThreshold = _threshold+y*_width;
		aboveLeftThreshold = _threshold+(y-1)*_width;

		currentLabel = (_rag->_labelsMap)+y*_width+1;
		aboveLabel = (_rag->_labelsMap)+(y-1)*_width+1;
		leftLabel = (_rag->_labelsMap)+y*_width;
		aboveLeftLabel = (_rag->_labelsMap)+(y-1)*_width;

		for(x=1;x<_width;x++){
			//if( (_rag->_region[*aboveLabel]->isEmpty()) || (_rag->_region[*leftLabel]->isEmpty()) ){
			//	std::cout << "Empty regions here!" << std::endl;
			//}

			bool currentEqualsLeft = (*current >= *currentThreshold) == (*left >= *leftThreshold);
			bool currentEqualsAbove = (*current >= *currentThreshold) == (*above >= *aboveThreshold);
			if( currentEqualsAbove && !currentEqualsLeft ){
				// set the label of the current pel to be the same as the one above
				*currentLabel = *aboveLabel;
				// add current to the region of the one above
				_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
				// link the region containing current and the region 
				// containing the left neighbour in the RAG 
				_rag->link(**currentLabel,**leftLabel);
			}else if( !currentEqualsAbove && currentEqualsLeft ){
				// set the label of the current pel to be the same as the one on the left
				*currentLabel = *leftLabel;
				// add current to the region of the pel on the left
				_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
				// link the region containing current and the region 
				// containing the neighbour above in the RAG 
				_rag->link(**currentLabel,**aboveLabel);
			}else if( !currentEqualsAbove && !currentEqualsLeft ){
				// in this case current is different from both "direct" neighbours
				// if current is black, the neighbour above left needs to be checked
				if( *current < *currentThreshold ){
					// if the left above pel is black as well..
					if( *aboveLeft < *aboveLeftThreshold ){
						// .. the two are part of the same region
						// set the label of the current pel to be the same as the one above left
						*currentLabel = *aboveLeftLabel;
						// add current to the region of the pel above left
						_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
					}else{
						// in this case current is black and the 3 neighbours are white
						// create a new label for current
						*currentLabel = _rag->getNewLabel();
						_rag->_region[**currentLabel]->appendToLabelPtrList( *currentLabel );
						// no need to set the colour of the new region
						// it is black, which is the default
						_rag->_region[**currentLabel]->_white = false;
						// add current to the new region
						_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
						// link the new region to the one above (just need to link current to any of the neighbours)
						_rag->link(**currentLabel,**aboveLabel);
					}// end if..else (*aboveLeft < *aboveLeftThreshold)
				}else{ // current is white and the two "direct" neighbours are black
					// create a new white region for current
					*currentLabel = _rag->getNewLabel();
					_rag->_region[**currentLabel]->appendToLabelPtrList( *currentLabel );
					_rag->_region[**currentLabel]->_white = true;
					_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
					// if the left and above neighbours are not in the same regions
					if( **leftLabel != **aboveLabel ){
						// merge the two regions
						_rag->merge(**aboveLabel,**leftLabel);
					}
					// link the new region to one of the two
					_rag->link(**currentLabel,**aboveLabel);
				}
			}else{ // current is the same colour as left and above
				if( **leftLabel != **aboveLabel ){
					// the pels left and above are in fact in the same region
					// merge the two regions
					/*mk int r =*/ _rag->merge(**aboveLabel,**leftLabel);
					*currentLabel = *aboveLabel;
				}else{
					// set the label of the current pel to be the same as the one above
					*currentLabel = *leftLabel;
				}
				// add current to the region containing the neighbours
				//_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
			}

			++current;
			++above;
			++left;
			++aboveLeft;

			++currentThreshold;
			++aboveThreshold;
			++leftThreshold;
			++aboveLeftThreshold;

			++currentLabel;
			++aboveLabel;
			++leftLabel;
			++aboveLeftLabel;

			// check the graph size
			// if it's above a threshold
			// abort the construction
			if( !(_rag->_used < maxRegions) ){
				return -1;
			}
		}
		//std::cout << "(x,y): (" << "x" << "," << y << ")" << std::endl;

	}

  return 0;
}

int RAGBuilder::buildRAGFullBorder( const int &maxRegions ){
	// first pixel
	_rag->appendToRegion( DTPoint(0,0), 0 );
	if( *_image > *_threshold ){
		_rag->_region[0]->_white = true;
	}else{ _rag->_region[0]->_white = false; }
	*(_rag->_labelsMap) = _rag->getNewLabel();
	// store the pointer to the current label in the current region
	// so that it can be changed if the region will be merged
	_rag->_region[0]->appendToLabelPtrList( *(_rag->_labelsMap) );

	//bool *storedPtr = _stored;
	//int limit = _height*_width;
	//for(int i=0;i_labelsMap)+1;
		leftLabel = _rag->_labelsMap;

		currentStored = _stored + 1;
		leftStored = _stored;
    
		for(x=1;x<_width;x++){







			if( (*current >= *currentThreshold) == (*left >= *leftThreshold) ){
				// current is the same colour as left
				// set the label of the current pel to be the same as left
				//*currentLabel = *leftLabel;
				(_rag->_labelsMap)[x+y*_width] = (_rag->_labelsMap)[x+y*_width-1];
				//*currentLabel = (_rag->_labelsMap)[x+y*_width+1];
				// add current to the region of left
				_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
			}else{
				// current is of a different colour from left
				// create a new label
				//*currentLabel = _rag->_used++;
				*currentLabel = _rag->getNewLabel();
				// store the pointer to the current label in the current region
				// so that it can be changed if the region will be merged
				_rag->_region[**currentLabel]->appendToLabelPtrList( *currentLabel );
				// set the colour of the new region
				if( (*current >= *currentThreshold) ){
					_rag->_region[**currentLabel]->_white = true;
				}else{ _rag->_region[**currentLabel]->_white = false; }
				// add current to the new region
				_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
				// link the new region to the one on the left
				_rag->link(**currentLabel,**leftLabel);
			}
			current++;
			left++;
			currentThreshold++;
			leftThreshold++;
			currentLabel++;
			leftLabel++;

			*currentStored++ = true;
      
			//std::cout << "(x,y): (" << x << "," << y << ")";
			//std::cout << " l: " << *leftLabel << " " ;
			//std::cout << ((*left>*leftThreshold)?("w"):("b")) << std::endl;
		}
	}

	for(y=1;y<_height;y++){
	// deal with the first pixel of the row
		x=0;

		int yOffset = y*_width;

		current = _image+yOffset;
		above = _image+yOffset-_width;

		currentThreshold = _threshold+yOffset;
		aboveThreshold = _threshold+yOffset-_width;

		currentLabel = (_rag->_labelsMap)+yOffset;
		aboveLabel = (_rag->_labelsMap)+yOffset-_width;

		*(_stored+yOffset) = true;

		if( (*current >= *currentThreshold) == (*above >= *aboveThreshold) ){
			// current is the same colour as above
			// set the label of the current pel to be the same as above
			*currentLabel = *aboveLabel;
			//(_rag->_labelsMap)[x+yOffset] = (_rag->_labelsMap)[x+yOffset-_width];
			//if( (_rag->_labelsMap)[x+yOffset] != (_rag->_labelsMap)[x+yOffset-_width] ){
			//	cout << "label copy failed!!!" << endl;
			//}
			// add current to the region of above
			_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
		}else{
			// current is of a different colour from above
			// create a new label
			*currentLabel = _rag->getNewLabel();
			// store the pointer to the current label in the current region
			// so that it can be changed if the region will be merged
			_rag->_region[**currentLabel]->appendToLabelPtrList( *currentLabel );
			// set the colour of the new region
			if( (*current >= *currentThreshold) ){
				_rag->_region[**currentLabel]->_white = true;
			}else{ _rag->_region[0]->_white = true; }
			// add current to the new region
			_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
			// link the new region to the one above
			_rag->link(**currentLabel,**aboveLabel);
		}

		current = _image+yOffset+1;
		above = _image+yOffset-_width+1;
		left = _image+yOffset;
		aboveLeft = _image+yOffset-_width;

		currentThreshold = _threshold+yOffset+1;
		aboveThreshold = _threshold+yOffset-_width+1;
		leftThreshold = _threshold+yOffset;
		aboveLeftThreshold = _threshold+yOffset-_width;

		currentLabel = (_rag->_labelsMap)+yOffset+1;
		aboveLabel = (_rag->_labelsMap)+yOffset-_width+1;
		leftLabel = (_rag->_labelsMap)+yOffset;
		aboveLeftLabel = (_rag->_labelsMap)+yOffset-_width;

		currentStored = _stored+yOffset+1;
		aboveStored = _stored+yOffset-_width+1;
		leftStored = _stored+yOffset;

		for(x=1;x<_width;x++){
			bool currentEqualsLeft = (*current >= *currentThreshold) == (*left >= *leftThreshold);
			bool currentEqualsAbove = (*current >= *currentThreshold) == (*above >= *aboveThreshold);
			if( currentEqualsAbove && !currentEqualsLeft ){
				// set the label of the current pel to be the same as the one above
				*currentLabel = *aboveLabel;
				// add current to the region of the one above
				_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
				// mark the current pixel as stored
				*currentStored = true;
				// link the region containing current and the region
				// containing the left neighbour in the RAG
				_rag->link(**currentLabel,**leftLabel);

				if( !(*leftStored) ){
  					// add the left pixel to the border of the region to the left
  					_rag->_region[**leftLabel]->appendFromPool(DTPoint(x-1,y));
					// mark the left pixel as stored
					*leftStored = true;
				}
			}else if( !currentEqualsAbove && currentEqualsLeft ){
				// set the label of the current pel to be the same as the one on the left
				*currentLabel = *leftLabel;
				// add current to the region of the pel on the left
				_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
				// mark the current pixel as stored
				*currentStored = true;
				// link the region containing current and the region
				// containing the neighbour above in the RAG
				_rag->link(**currentLabel,**aboveLabel);

				if( !(*aboveStored) ){
					// add the pixel above to the border of the region above
					_rag->_region[**aboveLabel]->appendFromPool(DTPoint(x,y-1));
					// mark the pixel above as stored
					*aboveStored = true;
				}
			}else if( !currentEqualsAbove && !currentEqualsLeft ){
				// in this case current is different from both "direct" neighbours
				// if current is black, the neighbour above left needs to be checked
				if( *current < *currentThreshold ){
					// if the left above pel is black as well..
					if( *aboveLeft < *aboveLeftThreshold ){
						// .. the two are part of the same region
						// set the label of the current pel to be the same as the one above left
						*currentLabel = *aboveLeftLabel;
						// add current to the region of the pel above left
						_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
						// mark the current pixel as stored
						*currentStored = true;

						if( !(*leftStored) ){
							// add the pixel to the left to the border of the left region
							_rag->_region[**leftLabel]->appendFromPool(DTPoint(x-1,y));
							// mark the left pixel as stored
							*leftStored = true;
						}
						if( !(*aboveStored) ){
    						// add the pixel above to the border of the left above
    						_rag->_region[**aboveLabel]->appendFromPool(DTPoint(x,y-1));
							// mark the pixel above as stored
							*aboveStored = true;
						}
					}else{
						// in this case current is black and the 3 neighbours are white
						// create a new label for current
						*currentLabel = _rag->getNewLabel();
						// store the pointer to the current label in the current region
						// so that it can be changed if the region will be merged
						_rag->_region[**currentLabel]->appendToLabelPtrList( *currentLabel );
						// no need to set the colour of the new region
						// it is black, which is the default
						_rag->_region[**currentLabel]->_white = false;
						// add current to the new region
						_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
						// mark the current pixel as stored
						*currentStored = true;
						// link the new region to the one above (just need to link current to any of the neighbours)
						_rag->link(**currentLabel,**aboveLabel);

						if( !(*leftStored) ){
    						// add the pixel to the left to the border of the left region
    						_rag->_region[**leftLabel]->appendFromPool(DTPoint(x-1,y));
							// mark the left pixel as stored
							*leftStored = true;
						}
						if( !(*aboveStored) ){
    						// add the pixel above to the border of the left above
    						_rag->_region[**aboveLabel]->appendFromPool(DTPoint(x,y-1));
							// mark the pixel above as stored
							*aboveStored = true;
						}
					}// end if..else (*aboveLeft < *aboveLeftThreshold)
				}else{ // current is white and the two "direct" neighbours are black
					// create a new white region for current
					*currentLabel = _rag->getNewLabel();
					// store the pointer to the current label in the current region
					// so that it can be changed if the region will be merged
					_rag->_region[**currentLabel]->appendToLabelPtrList( *currentLabel );
					// set the colour of the new region
					_rag->_region[**currentLabel]->_white = true;
					// append the current pixel to the new region
					_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
					// mark the current pixel as stored
					*currentStored = true;
					// if the left and above neighbours are not in the same regions
					if( **leftLabel != **aboveLabel ){
						// merge the two regions
						_rag->merge(**aboveLabel,**leftLabel);
					}
					// link the new region to one of the two
					_rag->link(**currentLabel,**aboveLabel);

					if( !(*leftStored) ){
  						// add the pixel to the left to the border of the left region
  						_rag->_region[**leftLabel]->appendFromPool(DTPoint(x-1,y));
						// mark the left pixel as stored
						*leftStored = true;
					}
					if( !(*aboveStored) ){
  						// add the pixel above to the border of the left above
  						_rag->_region[**aboveLabel]->appendFromPool(DTPoint(x,y-1));
						// mark the pixel above as stored
						*aboveStored = true;
					}
				}
			}else{ // current is the same colour as left and above
				if( **leftLabel != **aboveLabel ){
					// the pels left and above are in fact in the same region
					// merge the two regions
					/*mk int r =*/ _rag->merge(**aboveLabel,**leftLabel);
					*currentLabel = *aboveLabel;
				}else{
					// set the label of the current pel to be the same as the one above
					*currentLabel = *leftLabel;
				}
				// add current to the region containing the neighbours
				//_rag->_region[**currentLabel]->appendFromPool(DTPoint(x,y));
			}

			++current;
			++above;
			++left;
			++aboveLeft;

			++currentThreshold;
			++aboveThreshold;
			++leftThreshold;
			++aboveLeftThreshold;

			++currentLabel;
			++aboveLabel;
			++leftLabel;
			++aboveLeftLabel;

			++currentStored;
			++aboveStored;
			++leftStored;

			// check the graph size
			// if it's above a threshold
			// abort the construction
			if( !(_rag->_used < maxRegions) ){
				return -1;
			}
		}
		//std::cout << "(x,y): (" << "x" << "," << y << ")" << std::endl;
	}

	return 0;
}