diff --git a/cpp_frep/frep.cpp b/cpp_frep/frep.cpp index 9d539fee851b4f208a93eb816d253f1d55057a5f..0a84ea10cc24624a70ea9ba01c5668867fecdb1c 100755 --- a/cpp_frep/frep.cpp +++ b/cpp_frep/frep.cpp @@ -1,6 +1,9 @@ #include <iostream> #include <math.h> #include <vector> +#include <sstream> // std::ostringstream + + namespace cpp_frep { using scalar=float; @@ -347,6 +350,19 @@ namespace cpp_frep { return (weight*shape1->eval()+(1-weight)*shape2->eval()); } + std::string to_string_with_precision(const scalar a_value, const int n = 3) + { + std::ostringstream out; + out.precision(n); + out << std::fixed << a_value; + return out.str(); + } + + std::string getPrintedName(){ + std::string frepName=name+"("+shape1->getPrintedName()+","+shape2->getPrintedName()+","+ to_string_with_precision(weight,2) +")" ; + return frepName; + } + }; //..................................................................// diff --git a/cpp_frep/frep_tree.cpp b/cpp_frep/frep_tree.cpp index cb5f50e8c5075423dde68b6f70f31aea9ee0d4a3..3f3d56fa6c6b6bb8adfcd5212d6c4a92dfc00f41 100644 --- a/cpp_frep/frep_tree.cpp +++ b/cpp_frep/frep_tree.cpp @@ -16,18 +16,23 @@ namespace cpp_frep { Y=0.0f; }; - Frep_tree(std::vector<std::vector<scalar>> genome_) { + Frep_tree(std::vector<std::vector<scalar>> genome_,bool smooth) { // inputs=inputs_; genome=genome_; X=0.0f; Y=0.0f; nodeLength; addPrimitives(); - parseTree(); + if(!smooth){ + parseTree(); + }else{ + parseTreeSmooth(); + } + }; - void updateGenome(std::vector<std::vector<scalar>> genome_){ + void updateGenome(std::vector<std::vector<scalar>> genome_,bool smooth_){ genome=genome_; counterAdd =0; @@ -44,8 +49,12 @@ namespace cpp_frep { counterRectangle =0; addPrimitives(); - parseTree(); - + smooth=smooth_; + if(!smooth){ + parseTree(); + }else{ + parseTreeSmooth(); + } } @@ -81,6 +90,15 @@ namespace cpp_frep { std::cout<<"\n"; } + void parseTreeSmooth(){ + printGenome(); + // parsedTree=getNode(0); + parsedTree=morphNodes(0); + std::cout<<"\n"; + parsedTree->printName(); + std::cout<<"\n"; + } + Frep* getNode(int index){ int nodeIndex=(int)(genome[index][0]*nodeLength); @@ -222,150 +240,153 @@ namespace cpp_frep { nodeIndex2=nodeIndex1==nodeLength-1?10.0:nodeIndex1+1; float weight=genome[index][0]*nodeLength-(float)nodeIndex1; - static Morph f1; + + int n=counterMorph; + ArrayMorph[n].weight=1.0f-weight; std::cout<<"Morph("; - f1.setShape1(getNodeSharp( index ,nodeIndex1)); + counterMorph++; + ArrayMorph[n].setShape1(getNodeSmooth( index ,nodeIndex1)); std::cout<<","; - f1.setShape2(getNodeSharp(index ,nodeIndex2)); - std::cout<<")"; - f1.weight=1.0f-weight; - return &f1; + ArrayMorph[n].setShape2(getNodeSmooth( index ,nodeIndex2)); + std::cout<<","<<1.0f-weight<<")"; + + return &ArrayMorph[n]; + } - Frep* getNodeSharp(int index, int nodeIndex){ + Frep* getNodeSmooth(int index, int nodeIndex){ int shape1Index,shape2Index,shapeIndex; + shape1Index=index+(int)ceilf(genome[index][1]* (maxLength-1-index)); + shape2Index=index+(int)ceilf(genome[index][2]* (maxLength-1-index)); + shapeIndex =index+(int)ceilf(genome[index][1]* (maxLength-1-index)); //0 add, 1 subtract, 2 intersect, 3 morph, 4 translate, 5 scale, 6 rotate, 7 linearArrayX, 8 linearArrayX, 9 polar array //TODO: Add parameters switch (nodeIndex) { case 0: { - static Add f; + // Add f; + int n=counterAdd; std::cout<<"Add("; - shape1Index=index+(int)ceilf(genome[index][1]* (maxLength-1-index)); - f.setShape1(morphNodes(genome[index][1])); + counterAdd++; + ArrayAdd[n].setShape1(morphNodes(shape1Index)); std::cout<<","; - shape2Index=index+(int)ceilf(genome[index][2]* (maxLength-1-index)); - f.setShape2(morphNodes(shape2Index)); + ArrayAdd[n].setShape2(morphNodes(shape2Index)); std::cout<<")"; - return &f; - break; + return &ArrayAdd[n]; } case 1: { - static Subtract f; + + // Subtract f; + int n=counterSubtract; std::cout<<"Subtract("; - shape1Index=index+(int)ceilf(genome[index][1]* (maxLength-1-index)); - f.setShape1(morphNodes(shape1Index)); + counterSubtract++; + ArraySubtract[n].setShape1(morphNodes(shape1Index)); std::cout<<","; - shape2Index=index+(int)ceilf(genome[index][2]* (maxLength-1-index)); - f.setShape2(morphNodes(shape2Index)); + ArraySubtract[n].setShape2(morphNodes(shape2Index)); std::cout<<")"; - return &f; - break; + return &ArraySubtract[n]; } case 2: { - static Intersect f; + // Intersect f; + int n=counterIntersect; std::cout<<"Intersect("; - shape1Index=index+(int)ceilf(genome[index][1]* (maxLength-1-index)); - f.setShape1(morphNodes(shape1Index)); + counterIntersect++; + ArrayIntersect[n].setShape1(morphNodes(shape1Index)); std::cout<<","; - shape2Index=index+(int)ceilf(genome[index][2]* (maxLength-1-index)); - f.setShape2(morphNodes(shape2Index)); + ArrayIntersect[n].setShape2(morphNodes(shape2Index)); std::cout<<")"; - return &f; - break; + return &ArrayIntersect[n]; } case 3: { - static Morph f; + // Morph f; + int n=counterMorph; std::cout<<"Morph("; - shape1Index=index+(int)ceilf(genome[index][1]* (maxLength-1-index)); - f.setShape1(morphNodes(shape1Index)); + counterMorph++; + ArrayMorph[n].setShape1(morphNodes(shape1Index)); std::cout<<","; - shape2Index=index+(int)ceilf(genome[index][2]* (maxLength-1-index)); - f.setShape2(morphNodes(shape2Index)); + ArrayMorph[n].setShape2(morphNodes(shape2Index)); std::cout<<")"; - return &f; - break; + ArrayMorph[n].weight=0.5; + return &ArrayMorph[n]; } case 4: { - static Translate f; + // Translate f; + int n=counterTranslate; std::cout<<"Translate("; - shapeIndex=index+(int)ceilf(genome[index][1]* (maxLength-1-index)); - f.setShape(morphNodes(shapeIndex)); + counterTranslate++; + ArrayTranslate[n].setShape(morphNodes(shapeIndex)); std::cout<<")"; - return &f; - break; + return &ArrayTranslate[n]; } case 5: { - static Scale f; + // Scale f; + int n=counterScale; std::cout<<"Scale("; - shapeIndex=index+(int)ceilf(genome[index][1]* (maxLength-1-index)); - f.setShape(morphNodes(shapeIndex)); + counterScale++; + ArrayScale[n].setShape(morphNodes(shapeIndex)); std::cout<<")"; - return &f; - break; + return &ArrayScale[n]; } case 6: { - static Rotate f; + //Rotate f; + int n=counterRotate; std::cout<<"Rotate("; - shapeIndex=index+(int)ceilf(genome[index][1]* (maxLength-1-index)); - f.setShape(morphNodes(shapeIndex)); + counterRotate++; + ArrayRotate[n].setShape(morphNodes(shapeIndex)); std::cout<<")"; - return &f; - break; + return &ArrayRotate[n]; } case 7: { - static LinearArrayX f; + // LinearArrayX f; + int n=counterLinearArrayX; std::cout<<"LinearArrayX("; - shapeIndex=index+(int)ceilf(genome[index][1]* (maxLength-1-index)); - f.setShape(morphNodes(shapeIndex)); + counterLinearArrayX++; + ArrayLinearArrayX[n].setShape(morphNodes(shapeIndex)); std::cout<<")"; - return &f; - break; + return &ArrayLinearArrayX[n]; } case 8: { - static LinearArrayY f; + // LinearArrayY f; + int n=counterLinearArrayY; std::cout<<"LinearArrayY("; - shapeIndex=index+(int)ceilf(genome[index][1]* (maxLength-1-index)); - f.setShape(morphNodes(shapeIndex)); + counterLinearArrayY++; + ArrayLinearArrayY[n].setShape(morphNodes(shapeIndex)); std::cout<<")"; - return &f; - break; + return &ArrayLinearArrayY[n]; } case 9: { - static PolarArray f; + // PolarArray f; + int n=counterPolarArray; std::cout<<"PolarArray("; - shapeIndex=index+(int)ceilf(genome[index][1]* (maxLength-1-index)); - f.setShape(morphNodes(shapeIndex)); + counterPolarArray++; + ArrayPolarArray[n].setShape(morphNodes(shapeIndex)); std::cout<<")"; - return &f; - break; + return &ArrayPolarArray[n]; } case 10: { - static Circle f(1.0f,0.0f,0.0f); + // Circle f(1.0f,0.0f,0.0f); + int n=counterCircle; + counterCircle++; std::cout<<"Circle"; - return &f; - break; + return &ArrayCircle[n]; } case 11: { - static Rectangle f(-1.0f,1.0f,-1.0f,1.0f); + // Rectangle f(-1.0f,1.0f,-1.0f,1.0f); + int n=counterRectangle; + counterRectangle++; std::cout<<"Rectangle"; - return &f; - break; + return &ArrayRectangle[n]; } default: { - static Rectangle f(-1.0f,1.0f,-1.0f,1.0f); - std::cout<<"rectangle1"; - std::cout<<nodeIndex; - return &f; - break; + int n=counterRectangle; + counterRectangle++; + std::cout<<"REECCC"; + return &ArrayRectangle[n]; } } - // static Rectangle f1(-1.0f,1.0f,-1.0f,1.0f); - // std::cout<<"rectangle2"; - // return &f1; } void setXY(scalar X_,scalar Y_){ @@ -406,13 +427,13 @@ namespace cpp_frep { Frep* parsedTree; scalar nodeLength=12.0f; - static const int storageSpace=5; + static const int storageSpace=20; Add ArrayAdd [storageSpace]; Subtract ArraySubtract [storageSpace]; Intersect ArrayIntersect [storageSpace]; Scale ArrayScale [storageSpace]; - Morph ArrayMorph [storageSpace]; + Morph ArrayMorph [storageSpace*20]; Translate ArrayTranslate [storageSpace]; Rotate ArrayRotate [storageSpace]; LinearArrayX ArrayLinearArrayX [storageSpace]; @@ -435,6 +456,8 @@ namespace cpp_frep { int counterRectangle =0; int numPrimitives=2; + + bool smooth=false; }; } \ No newline at end of file diff --git a/cpp_frep/main.cpp b/cpp_frep/main.cpp index 288b8f863ebfa8ae595c61542ac030eb15c3169d..0a0c364c3762f4da207a63f9f0afe7cd8b6213e0 100755 --- a/cpp_frep/main.cpp +++ b/cpp_frep/main.cpp @@ -11,6 +11,22 @@ using namespace cpp_frep; using scalar=float; //-------------------------------------------------------------------------------------------------- +std::vector<std::string> insert_newlines(const std::string &in, const size_t every_n){ + std::vector<std::string> outStrings; + // out.reserve(in.size() + in.size() / every_n); + int count=0; + outStrings.push_back(""); + for(std::string::size_type i = 0; i < in.size(); i++) { + if (!(i % every_n) && i) { + // out.push_back('\n'); + outStrings.push_back(""); + count++; + } + outStrings[count].push_back(in[i]); + } + return outStrings; +} + void drawFrep(Frep* frep,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar dx,scalar dy){ for(scalar i=minX;i<maxX;i+=dx){ for(scalar j=minY;j<maxY;j+=dy){ @@ -47,7 +63,7 @@ void drawFrep(Frep_tree frep,scalar minX,scalar maxX,scalar minY,scalar maxY,sca } -void drawFrep(Frep_tree frep,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar dx,scalar dy,std::string name){ +void drawFrep(Frep_tree frep,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar dx,scalar dy,std::string name,bool preview){ int height=(int)((maxX-minX)/dx); int width=(int)((maxY-minY)/dy); @@ -83,9 +99,80 @@ void drawFrep(Frep_tree frep,scalar minX,scalar maxX,scalar minY,scalar maxY,sca } // std::cout << '\n'; + cv::Mat image = cv::Mat(width, height, CV_8UC4, pix); + + auto strings=insert_newlines(frep.getPrintedGenome(),120); + float scale=0.3; + int y=20; + for (int i=0;i<strings.size();i++){ + cv::putText(image, + strings[i], + cv::Point(10,y), // Coordinates + cv::FONT_HERSHEY_SIMPLEX, // Font + scale, // Scale. 2.0 = 2x bigger + cv::Scalar(0,0,0), // BGR Color + 1); // Line Thickness (Optional) + y+=15; + + } + + // cv::putText(image, + // frep.getPrintedGenome(), + // cv::Point(10,10), // Coordinates + // cv::FONT_HERSHEY_SIMPLEX, // Font + // 0.25, // Scale. 2.0 = 2x bigger + // cv::Scalar(0,0,0), // BGR Color + // 1); // Line Thickness (Optional) + + std::string fileName=name+".jpg"; + cv::imwrite( fileName, image ); + if(preview){ + cv::namedWindow("Display Image", cv::WINDOW_AUTOSIZE ); + cv::imshow("Display Image", image); + cv::waitKey(0); + + } +} + +void drawFrep(Frep* frep,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar dx,scalar dy,std::string name,bool preview){ + + int height=(int)((maxX-minX)/dx); + int width=(int)((maxY-minY)/dy); + int size=height*width*4; + + + + int stride=0; + unsigned char pix[size]; + + + for(scalar i=minX;i<maxX-dx;i+=dx){ + for(scalar j=minY;j<maxY-dy;j+=dy){ + frep->setXY(i,j); + scalar val=frep->eval(); + if(val>0.0f){ + // std::cout << "+" ; + pix[stride+0]=0; + pix[stride+1]=0; + pix[stride+2]=0; + pix[stride+3]=0; + + }else{ + // std::cout << "o" ; + pix[stride+0]=255; + pix[stride+1]=255; + pix[stride+2]=255; + pix[stride+3]=255; + } + stride+=4; + } + // std::cout << '\n'; + } + // std::cout << '\n'; + cv::Mat image = cv::Mat(width, height, CV_8UC4, pix); cv::putText(image, - frep.getPrintedGenome(), + frep->getPrintedName(), cv::Point(10,10), // Coordinates cv::FONT_HERSHEY_SIMPLEX, // Font 0.25, // Scale. 2.0 = 2x bigger @@ -94,11 +181,12 @@ void drawFrep(Frep_tree frep,scalar minX,scalar maxX,scalar minY,scalar maxY,sca std::string fileName=name+".jpg"; cv::imwrite( fileName, image ); - cv::namedWindow("Display Image", cv::WINDOW_AUTOSIZE ); - cv::imshow("Display Image", image); - cv::waitKey(0); - + if(preview){ + cv::namedWindow("Display Image", cv::WINDOW_AUTOSIZE ); + cv::imshow("Display Image", image); + cv::waitKey(0); + } } float constraint(float num){ @@ -107,7 +195,7 @@ float constraint(float num){ return num; } -float compareL1(Vector v, Frep* frep,Frep_tree* frep_tree,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar dx,scalar dy,std::string name){ +float compareL1(Vector v, Frep* frep,Frep_tree* frep_tree,scalar minX,scalar maxX,scalar minY,scalar maxY,scalar dx,scalar dy,std::string name,bool smooth){ int height=(int)((maxX-minX)/dx); int width=(int)((maxY-minY)/dy); @@ -136,10 +224,10 @@ float compareL1(Vector v, Frep* frep,Frep_tree* frep_tree,scalar minX,scalar max // frep_tree->genome[0][0]=constraint(v.at(0)); // frep_tree->genome[0][1]=constraint(v.at(1)); // frep_tree->genome[0][2]=constraint(v.at(2)); - // frep_tree->updateGenome(frep_tree->genome); + // frep_tree->updateGenome(frep_tree->genome,false); - frep_tree->updateGenome(g); + frep_tree->updateGenome(g,smooth); for(scalar i=minX;i<maxX-dx;i+=dx){ @@ -178,13 +266,21 @@ float compareL1(Vector v, Frep* frep,Frep_tree* frep_tree,scalar minX,scalar max std::cout<<result <<"\n"; cv::Mat image = cv::Mat(width, height, CV_8UC4, pix); - cv::putText(image, - frep_tree->getPrintedGenome(), - cv::Point(10,20), // Coordinates + auto strings=insert_newlines(frep_tree->getPrintedGenome(),120); + float scale=0.3; + int y=20; + for (int i=0;i<strings.size();i++){ + cv::putText(image, + strings[i], + cv::Point(10,y), // Coordinates cv::FONT_HERSHEY_SIMPLEX, // Font - 0.5, // Scale. 2.0 = 2x bigger + scale, // Scale. 2.0 = 2x bigger cv::Scalar(0,0,0), // BGR Color 1); // Line Thickness (Optional) + y+=15; + + } + cv::imwrite( fileName, image ); return result; @@ -212,20 +308,21 @@ int main(int const, char const**) { scalar maxY=3.0f; scalar dx=0.01f; scalar dy=0.01f; + bool smooth=false; std::vector<std::vector<scalar>> genome; std::vector<scalar> node1; - node1.push_back(0.848148); - node1.push_back(0.855556); - node1.push_back(0.244); + node1.push_back(0.34); + node1.push_back(0.1); + node1.push_back(0.95); genome.push_back(node1); std::vector<scalar> node2; - node2.push_back(0.205); - node2.push_back(0.4524); - node2.push_back(0.94); + node2.push_back(0.48); + node2.push_back(0.3); + node2.push_back(0.9); genome.push_back(node2); std::vector<scalar> node3; @@ -234,14 +331,14 @@ int main(int const, char const**) { node3.push_back(0.727); genome.push_back(node3); - Frep_tree tree(genome); + Frep_tree tree(genome,smooth); // genome[0][0]=0.1; - // tree.updateGenome(genome); - // drawFrep(tree,minX, maxX, minY, maxY, dx, dy,"image"); + // tree.updateGenome(genome,false); + // drawFrep(tree,minX, maxX, minY, maxY, dx, dy,"image22",true); - float precision = 0.01; + float precision = 0.001; int dimension = 3; NelderMeadOptimizer o(dimension, precision); @@ -263,7 +360,7 @@ int main(int const, char const**) { Rectangle r(-1.0f,1.0f,-1.0f,1.0f); Subtract s(&r,&c); PolarArray pa(&r,0.0f, 0.0f, 45.0f,-1.0f); - // drawFrep(&s,minX, maxX, minY, maxY, dx, dy); + drawFrep(&s,minX, maxX, minY, maxY, dx, dy,"target",false); int count=0; @@ -272,7 +369,7 @@ int main(int const, char const**) { float score=0.0f; while ( !o.done(score)) { - if(count>50){ + if(count>50||o.done()){ count=0; std::cout<<"Counld't find solution, reset with random values!\n"; o.reset(); @@ -284,7 +381,7 @@ int main(int const, char const**) { std::string name1 = "i"; std::string name=name1+std::to_string(count); - score=compareL1( v, &s, &tree, minX, maxX, minY, maxY, dx, dy, name); + score=compareL1( v, &s, &tree, minX, maxX, minY, maxY, dx, dy, name,smooth); v = o.step(v,score ); count++; }