2018-01-25 22:14:00 +01:00
# include "AbstractionLayer_SURFFeatures.h"
2018-01-26 14:58:51 +01:00
// Parameters for algorithm:
// maxCorners – The maximum number of corners to return. If there are more corners than that will be found, the strongest of them will be returned
// qualityLevel – Characterizes the minimal accepted quality of image corners;
// minDistance – The minimum possible Euclidean distance between the returned corners
// mask – The optional region of interest. It will specify the region in which the corners are detected
// blockSize – Size of the averaging block for computing derivative covariation
// useHarrisDetector – Indicates, whether to use operator or cornerMinEigenVal()
// k – Free parameter of Harris detector
# include <iostream>
2018-01-26 22:26:19 +01:00
# include "opencv2/highgui/highgui.hpp"
# include "opencv2/imgproc/imgproc.hpp"
2018-01-26 14:58:51 +01:00
using namespace cv ;
using namespace std ;
2018-01-25 22:14:00 +01:00
bool AbstractionLayer_SURFFeatures : : PreProcessing ( coor mySize , const vector < Part * > * partArray )
{
2018-01-26 22:26:19 +01:00
cout < < " Abstraction 4 (Features) Preprocessing... " < < flush ;
2018-01-26 14:13:14 +01:00
InitialiseConstraintMatrixSize ( mySize . col , mySize . row ) ;
2018-01-26 19:59:12 +01:00
if ( ! PreProcessingFullImg ( mySize ) ) return false ;
if ( ! PreProcessingPieces ( mySize , partArray ) ) return false ;
2018-01-27 12:35:14 +01:00
cout < < " Done! " < < endl ;
2018-01-26 19:59:12 +01:00
return true ;
}
2018-01-26 14:58:51 +01:00
2018-01-26 19:59:12 +01:00
bool AbstractionLayer_SURFFeatures : : EvaluateQuality ( coor constraintCoordinate , qualityVector & qVector )
{
2018-01-26 20:30:17 +01:00
// Calculate absolute difference between constraints and each piece and safe it
for ( int i = 0 ; i < qVector . size ( ) ; i + + )
{
2018-01-26 23:01:21 +01:00
float diff = abs ( m_constraintMatrix [ constraintCoordinate . col ] [ constraintCoordinate . row ] . m_numberOfFeaturesDetected - qVector [ i ] . second - > m_a4 . m_numberOfFeaturesDetected ) ;
2018-01-26 20:30:17 +01:00
qVector [ i ] . first = 1 - diff ;
2018-01-27 12:35:14 +01:00
// cout << i << " " << fixed << qVector[i].first << endl;
2018-01-26 20:30:17 +01:00
}
2018-01-27 12:35:14 +01:00
// cout << " Matrix: " << m_constraintMatrix[constraintCoordinate.col][constraintCoordinate.row].m_numberOfFeaturesDetected << endl;
2018-01-26 20:30:17 +01:00
return true ;
2018-01-26 19:59:12 +01:00
}
2018-01-26 20:30:17 +01:00
bool AbstractionLayer_SURFFeatures : : SetConstraintOnPosition ( const coor constraintCoordinate , const AbstractionLayer_SURFFeatures_Properties constraint )
2018-01-26 19:59:12 +01:00
{
//TODO: Benötigen wir nicht unbedint.
//TODO: Hier erhalten wir vom Dispatcher welches Teil an welche Position gesetzt wird und wir könnten hier die Features des Bilds in die m_constraintMatrix speichern
2018-01-26 22:26:19 +01:00
return true ;
2018-01-26 19:59:12 +01:00
}
bool AbstractionLayer_SURFFeatures : : RemoveConstraintOnPosition ( const coor constraintCoordinate )
{
//TODO: Wie auch beim SetConstraint sollte uns das hier nicht wirklich interessieren.
//TODO: Außer wir setzen etwas in die Contraintmatrix.
//TODO: Dann ruft uns der Dispatcher beim Backtrack hier auf und wir müssten das jeweilige PuzzlePart hier wieder rauslöschen.
2018-01-26 22:26:19 +01:00
return true ;
2018-01-26 19:59:12 +01:00
}
bool AbstractionLayer_SURFFeatures : : PreProcessingFullImg ( coor mySize )
{
std : : vector < cv : : Point2f > corners ; // Variable to store corner-positions at
2018-01-26 18:47:41 +01:00
2018-01-26 14:58:51 +01:00
// Load and resize image, so that number of parts in row and col fit in
2018-01-26 22:26:19 +01:00
Mat image = imread ( PATH_FULL_PUZZLE , IMREAD_GRAYSCALE ) ;
2018-01-26 19:59:12 +01:00
if ( ! image . data ) {
cerr < < " Problem loading image of complete puzzle! " < < endl ;
return false ;
}
2018-01-26 14:58:51 +01:00
//cout << "PRE: " << image.cols << " x " << image.rows << endl;
2018-01-26 22:26:19 +01:00
resize ( image , image , Size ( int ( ceil ( double ( image . cols ) / mySize . col ) * mySize . col ) , int ( ceil ( double ( image . rows ) / mySize . row ) * mySize . row ) ) ) ;
2018-01-26 14:58:51 +01:00
//cout << "POST: " << image.cols << " x " << image.rows << endl;
// PARAMETERS (for description see top of file)
2018-01-27 12:35:14 +01:00
int maxCorners = 12000 ;
2018-01-26 14:58:51 +01:00
double qualityLevel = 0.01 ;
double minDistance = .5 ;
2018-01-26 22:26:19 +01:00
Mat mask ;
2018-01-26 14:58:51 +01:00
int blockSize = 3 ;
bool useHarrisDetector = false ;
double k = 0.04 ;
// Detect features - this is where the magic happens
2018-01-26 22:26:19 +01:00
goodFeaturesToTrack ( image , corners , maxCorners , qualityLevel , minDistance , mask , blockSize , useHarrisDetector , k ) ;
2018-01-26 14:58:51 +01:00
2018-01-26 17:35:21 +01:00
// Empty the matrix
2018-01-27 12:35:14 +01:00
for ( int j = 0 ; j < mySize . row ; j + + )
{ for ( int i = 0 ; i < mySize . col ; i + + )
2018-01-26 17:35:21 +01:00
{
2018-01-27 12:35:14 +01:00
m_constraintMatrix [ i ] [ j ] . m_numberOfFeaturesDetected = 0 ;
//cout << m_constraintMatrix[i][j].m_numberOfFeaturesDetected << " ";
2018-01-26 17:35:21 +01:00
}
2018-01-27 12:35:14 +01:00
//cout << endl;
2018-01-26 17:35:21 +01:00
}
2018-01-26 14:58:51 +01:00
int pieceColSize = image . cols / mySize . col ;
int pieceRowSize = image . rows / mySize . row ;
// Calculate number of features for each piece-position
for ( int i = 0 ; i < corners . size ( ) ; i + + ) // For all found features
{
// Increment number of found pieces
2018-01-26 23:01:21 +01:00
m_constraintMatrix [ int ( corners [ i ] . x / pieceColSize ) ] [ int ( corners [ i ] . y / pieceRowSize ) ] . m_numberOfFeaturesDetected + + ;
2018-01-26 14:58:51 +01:00
}
// Get minimal and maximal number of features -> TODO: Do in first loop to safe time?
int minFeatures = int ( m_constraintMatrix [ 0 ] [ 0 ] . m_numberOfFeaturesDetected ) ;
int maxFeatures = int ( m_constraintMatrix [ 0 ] [ 0 ] . m_numberOfFeaturesDetected ) ;
2018-01-27 12:35:14 +01:00
for ( int j = 0 ; j < mySize . row ; j + + )
2018-01-26 14:58:51 +01:00
{
2018-01-27 12:35:14 +01:00
for ( int i = 0 ; i < mySize . col ; i + + )
2018-01-26 14:58:51 +01:00
{
2018-01-27 12:35:14 +01:00
if ( m_constraintMatrix [ i ] [ j ] . m_numberOfFeaturesDetected < minFeatures ) minFeatures = int ( m_constraintMatrix [ i ] [ j ] . m_numberOfFeaturesDetected ) ;
if ( m_constraintMatrix [ i ] [ j ] . m_numberOfFeaturesDetected > maxFeatures ) maxFeatures = int ( m_constraintMatrix [ i ] [ j ] . m_numberOfFeaturesDetected ) ;
//cout << fixed << m_constraintMatrix[i][j].m_numberOfFeaturesDetected << " ";
2018-01-26 14:58:51 +01:00
}
2018-01-27 12:35:14 +01:00
//cout << endl;
2018-01-26 14:58:51 +01:00
}
2018-01-26 18:47:41 +01:00
// Calculate percentage from 0 to 100% (normalized 0-1) with numberOfFeatures and safe it
2018-01-27 12:35:14 +01:00
for ( int j = 0 ; j < mySize . row ; j + + )
2018-01-26 14:58:51 +01:00
{
2018-01-27 12:35:14 +01:00
for ( int i = 0 ; i < mySize . col ; i + + )
2018-01-26 14:58:51 +01:00
{
2018-01-27 12:35:14 +01:00
m_constraintMatrix [ i ] [ j ] . m_numberOfFeaturesDetected = ( m_constraintMatrix [ i ] [ j ] . m_numberOfFeaturesDetected - minFeatures ) / ( maxFeatures - minFeatures ) ;
2018-01-26 14:58:51 +01:00
//cout << fixed << m_constraintMatrix[i][j].m_numberOfFeaturesDetected << " ";
}
//cout << endl;
}
2018-01-26 14:12:16 +01:00
2018-01-26 14:58:51 +01:00
// DEBUG - Display image
/*for( size_t i = 0; i < corners.size(); i++ )
{
cv : : circle ( image , corners [ i ] , 2 , cv : : Scalar ( 255. ) , - 1 ) ;
}
cv : : namedWindow ( " Output " , CV_WINDOW_AUTOSIZE ) ;
cv : : imshow ( " Output " , image ) ;
2018-01-25 22:14:00 +01:00
2018-01-26 14:58:51 +01:00
cv : : waitKey ( 0 ) ; */
2018-01-26 14:12:16 +01:00
2018-01-26 19:59:12 +01:00
return true ;
}
2018-01-26 18:47:41 +01:00
2018-01-26 19:59:12 +01:00
bool AbstractionLayer_SURFFeatures : : PreProcessingPieces ( coor mySize , const vector < Part * > * partArray )
{
std : : vector < cv : : Point2f > corners ; // Variable to store corner-positions at
2018-01-26 18:47:41 +01:00
// PARAMETERS (for description see top of file)
2018-01-26 19:59:12 +01:00
int maxCorners = 500 ;
double qualityLevel = 0.05 ;
double minDistance = .5 ;
2018-01-26 22:26:19 +01:00
Mat mask ;
2018-01-26 19:59:12 +01:00
int blockSize = 3 ;
bool useHarrisDetector = false ;
double k = 0.04 ;
2018-01-26 18:47:41 +01:00
2018-01-26 19:59:12 +01:00
int minFeatures = maxCorners ;
int maxFeatures = 0 ;
char name [ 100 ] ;
2018-01-26 18:47:41 +01:00
2018-01-26 19:59:12 +01:00
for ( unsigned imgID = 0 ; imgID < mySize . col * mySize . row ; imgID + + ) {
2018-01-26 22:26:19 +01:00
sprintf ( name , PATH1 , imgID ) ;
Mat src = imread ( name , IMREAD_GRAYSCALE ) ;
2018-01-26 18:47:41 +01:00
if ( ! src . data ) {
2018-01-26 19:59:12 +01:00
cerr < < " Problem loading image of puzzle piece! " < < endl ;
2018-01-26 18:47:41 +01:00
return false ;
} else {
2018-01-26 22:26:19 +01:00
goodFeaturesToTrack ( src , corners , maxCorners , qualityLevel , minDistance , mask , blockSize ,
2018-01-26 19:59:12 +01:00
useHarrisDetector , k ) ;
if ( corners . size ( ) < minFeatures ) minFeatures = corners . size ( ) ;
if ( corners . size ( ) > maxFeatures ) maxFeatures = corners . size ( ) ;
2018-01-27 12:35:14 +01:00
for ( int rotate = 0 ; rotate < 4 ; rotate + + )
partArray - > at ( imgID * 4 + rotate ) - > m_a4 . m_numberOfFeaturesDetected = corners . size ( ) ;
//cout << imgID << ":" << partArray->at(imgID*4)->m_a4.m_numberOfFeaturesDetected << endl;
//cout << imgID << " " << corners.size() << endl;
2018-01-26 18:47:41 +01:00
/*for( size_t i = 0; i < corners.size(); i++ ) {
cv : : circle ( src , corners [ i ] , 2 , cv : : Scalar ( 255. ) , - 1 ) ;
}
cv : : namedWindow ( " Output " , CV_WINDOW_AUTOSIZE ) ;
cv : : imshow ( " Output " , src ) ;
cv : : waitKey ( 0 ) ; */
}
}
// Calculate percentage from 0 to 100% (normalized 0-1) with numberOfFeatures and safe it
2018-01-27 12:35:14 +01:00
for ( unsigned i = 0 ; i < partArray - > size ( ) ; i + + )
2018-01-26 18:47:41 +01:00
{
partArray - > at ( i ) - > m_a4 . m_numberOfFeaturesDetected = ( partArray - > at ( i ) - > m_a4 . m_numberOfFeaturesDetected - minFeatures ) / ( maxFeatures - minFeatures ) ;
2018-01-26 22:26:19 +01:00
//cout << fixed << partArray->at(i)->m_a4.m_numberOfFeaturesDetected << endl;
2018-01-26 18:47:41 +01:00
}
2018-01-26 22:26:19 +01:00
//cout << endl;
2018-01-26 18:47:41 +01:00
return true ;
2018-01-25 22:14:00 +01:00
}