PuzzleSolver/Source/functions/solve/puzzleExtension.cpp
Raphael Maenle 7920e73bfb removed calls to other layers to get into solver
problem with imread in preprocess when multiple layers make call. This was subv. by deactivating these layers.
2018-01-26 22:27:46 +01:00

252 lines
6.9 KiB
C++

#include "../../header/solve.h"
#include "../../header/input.h"
typedef std::vector<std::vector<Point>> Contour_t;
typedef std::vector<Vec4i> Hierarchy_t; //hierarchy object is needed for drawContours apparently
Mat crop2ContourInv(const Mat & img);
Contour_t getLongestContour(Mat bw);
int getLongestContourIndex(Contour_t contours);
void Puzzle::printPuzzle()
{
cout << "a1: " << endl;
a1.printConstraintMatrix();
}
void Puzzle::printBox()
{
int i=0;
for(auto it:myBox)
{
cout << "Part " << i++ << ":" << endl;
it.print(); cout << endl;
}
}
//puts a puzzlepiece back into its box
void Puzzle::putIntoBox()
{
Part tmpPart;
int id = 0;
for(int i=0;i<this->getSizeAsCoor().col;i++)
{
for(int j=0;j<this->getSizeAsCoor().row;j++)
{
tmpPart.m_a1=this->a1.m_constraintMatrix[i+1][j+1];
tmpPart.m_a3=this->a3.m_constraintMatrix[i][j];
tmpPart.m_a4=this->a4.m_constraintMatrix[i][j];
//sets part id
tmpPart.SetPartID(id++);
// adds all 4 rotations to Box
for(int rotations=0;rotations<4;rotations++)
{
tmpPart.m_a1.shift(1);
tmpPart.m_a3.shift(1);
//TODO! add all other layer with their rotaionvariance into "tmpPart"
//if it piece is roation invariant no need to do anything
myBox.emplace_back(tmpPart);
}
}
}
}
//shuffles the existing box in Puzzle
void Puzzle::shuffle()
{
random_shuffle(myBox.begin(),myBox.end());
}
//deletes all constraints from all abstractionlayers
void Puzzle::removeConstrains(coor removeCoordinates)
{
// this->a1.RemoveConstraintOnPosition(removeCoordinates);
// this->a3.RemoveConstraintOnPosition(removeCoordinates);
this->a4.RemoveConstraintOnPosition(removeCoordinates);
//TODO!! Add other layer remove here
}
void Puzzle::setConstraints(coor setConstraints, Part* constraintPiece)
{
//dp
// this->dp.m_constraintMatrix[setConstraints.col][setConstraints.row].DestructionArray.clear();
// for(auto it:this->tmp_destructionArray)
// this->dp.m_constraintMatrix[setConstraints.col][setConstraints.row].DestructionArray.emplace_back(it);
//a1
//this->a1.SetConstraintOnPosition(setConstraints,constraintPiece->m_a1);
//a3
//this->a3.SetConstraintOnPosition(setConstraints,constraintPiece->m_a3);
//a4
this->a4.SetConstraintOnPosition(setConstraints,constraintPiece->m_a4);
//TODO!! Add other layer remove here
}
int Puzzle::removeSimilar(qualityVector& qVector, Part& myPart)
{
//a1
uint8_t tmpConnections=myPart.m_a1.getConnections();
a1.RemoveSimilar(qVector,tmpConnections);
}
void Puzzle::createRandomPuzzle()
{
a1.CreateRandomPuzzle();
}
void Puzzle::createp_box()
{
for(int i=0;i<cols*rows*4;i++)
p_myBox.push_back(&myBox[i]);
}
//creates a box of puzzlepieces with nothing other than puzzle piece id and correct nr of pieces
void Puzzle::createBox(){
for(int i=0;i<cols*rows;i++)
{
Part temp;
temp.SetPartID(i);
for(uint8_t j=0;j<4;j++)
{
temp.SetNumOfRotations(j);
myBox.push_back(temp);
}
}
}
bool Puzzle::allSet() {
for(auto it:myBox)
if(!it.set)
return false;
return true;
}
void Puzzle::clearMat()
{
for(unsigned int i=0;i<cols;i++)
{
for(unsigned int j=0;j<rows;j++)
{
this->removeConstrains({i,j});
}
}
}
Mat Puzzle::readImage(int fileIndex, const char* inputDir){
char indexstr[12];
sprintf(indexstr,"%d.jpg",fileIndex);
char * inputstr = (char *) malloc(1 + strlen(inputDir)+ strlen(indexstr) );
strcpy(inputstr, inputDir);
strcat(inputstr,indexstr);
//cout<<inputstr<<endl;
Mat source = imread(inputstr,1);
return source;
}
Mat Puzzle::resultImage( vector<LogEntry>& log){
int Y_size = 1200; // chose this to fit your monitor!
int separator = 1;
int partHeight = 90;
int partWidth;
auto imageH = int(round(partHeight* cols));
if(imageH > Y_size){
imageH = Y_size;
}
partHeight = int(round(imageH / cols));
partWidth= partHeight;
int imageW = int(round( partWidth*rows));
int temp = imageW;
imageW = imageH;
imageH = temp;
Mat result(imageH,imageW,CV_8UC3);
char name[100];
for (auto it:log)
{
if (it.myCoor.col == 27 && it.myCoor.row == 5)
{
;
// imshow("result",result);
// waitKey(0);
}
//cout << it.PieceCollector[0].second->GetPartID() << endl;
int imageNumber = it.PieceCollector[0].second->GetPartID();
//cout<<"imageIndex: "<< imageNumber << endl;
sprintf(name, PATH, imageNumber);
Mat img = imread(name, 1);
copyMakeBorder(img,img,200,200,200,200,BORDER_CONSTANT,Scalar(255,255,255));
Mat invert = Mat::ones(img.size(), CV_8UC3); // invert for rotation to work correctly
bitwise_not ( img, invert );
if (it.myCoor.col == 35 && it.myCoor.row == 5)
{
//imshow("img",img);
//waitKey(0);
;
}
int angle = ((int)it.PieceCollector[0].second->GetNumOfRotations())*-90;
Point2f center;
center.x = img.cols/2;
center.y = img.rows/2;
Mat RotMatrix = getRotationMatrix2D(center,angle,1);
warpAffine(invert,invert,RotMatrix, invert.size());
bitwise_not(invert,img);
Mat cropped = crop2ContourInv(img);
auto ROI_X = int(round(it.myCoor.col*partWidth));
auto ROI_Y = int(round(it.myCoor.row*partHeight));
// cout<<"ROI X: "<< ROI_X<<endl;
// cout<<"ROI Y: "<< ROI_Y<<endl;
Rect ROI(ROI_X,ROI_Y , partWidth-separator, partHeight-separator); // j is the x coordinate not i!!
Mat temp(Scalar(255,255,255));
resize(cropped,temp, Size(ROI.width, ROI.height));
temp.copyTo(result(ROI));
}
imshow("result",result);
waitKey(0);
return result;
}
Mat crop2ContourInv(const Mat & img){ // for white background images
Mat grey;
cvtColor(img, grey,CV_BGR2GRAY);
Contour_t c; Hierarchy_t h;
threshold(grey,grey,200,255,THRESH_BINARY_INV);
findContours(grey,c,h,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);
int longest = getLongestContourIndex(c);
Rect croppingRect = boundingRect(c[longest]);
Mat cropped = img(croppingRect);
// imshow("cropped", cropped);
return cropped;
}
int getLongestContourIndex(Contour_t contours){
double area = 0;
double largestArea = 0;
size_t largestIndex = 0;
for (size_t i = 0; i < contours.size(); ++i)
{
area = contourArea(contours[i]);
if (area < 1e2 || 1e5 < area) continue; //
if (area > largestArea) {
largestArea = area;
largestIndex = i; // i is type size_t, should be converted to int.
}
}
return(largestIndex);
}