diff --git a/src/pointbase.cpp b/src/pointbase.cpp index f056a7a..da57a94 100644 --- a/src/pointbase.cpp +++ b/src/pointbase.cpp @@ -1,8 +1,13 @@ #include "opencv2/highgui.hpp" #include "opencv2/core.hpp" #include "opencv2/imgproc.hpp" +#include "opencv2/imgcodecs.hpp" +#include "opencv2/highgui.hpp" +#include "opencv2/stitching.hpp" +#include #include #include +#include #include #include #include @@ -31,9 +36,10 @@ struct ComparePoints class PointBase { public: - vector points; - vector doneVector; - std::map pathMap; + vector points; //all points - points are being removed as adjacencies are found + vector doneVector; //points that have been successfully searched for adjacencies + vector toDoVector; //points yet to be searched for adjacent points + std::map pathMap; //map for file paths - get the path of a file via pathMap[Point2d(x,y)] @@ -43,7 +49,7 @@ class PointBase { //std::string path = "../data/"; for (const auto & entry : fs::directory_iterator(path)) { - string filePath = entry.path(); + string filePath = fs::canonical(entry.path()); // absolute path without .. //cout << filePath.find(".json") << std::endl; if (filePath.find(".json") != string::npos) { @@ -72,6 +78,12 @@ class PointBase { } } + + + + + + void printPoints(int which=0) { if (which==1) // prints current points vector @@ -97,6 +109,12 @@ class PointBase { } + + + + + + string getPath(double x, double y) { string path = pathMap[Point2d(x,y)]; @@ -104,6 +122,13 @@ class PointBase { } + + + + + + + //shows the location of loaded points on an images //useful for debugging void showPointImg() @@ -116,4 +141,196 @@ class PointBase { imshow("Location of Images", img);//Showing the circle// waitKey(0);//Waiting for Keystroke// } + + + /*DESTRUCTIVE!! - removes found adj. points from points vector, adds them to the toBeDone vector + Searches for adjacent points to a given point + Returns either empty vector, or a vector with the found adjacent points + */ + vector getAdjacents(Point2d inputPoint) + { + vector resultVector; + for (int i = 0; i < points.size(); i++) + { + + double yDifference = inputPoint.y-points[i].y; + double xDifference = inputPoint.x - points[i].x; + + + + if(abs(yDifference)<15 && (xDifference<45) && (xDifference>0)) + { + resultVector.push_back(points[i]); + toDoVector.push_back(points[i]); + points.erase(points.begin()+i); + + } + + + + if(abs(yDifference)<15 && (xDifference> -45) && (xDifference<0)) + { + resultVector.push_back(points[i]); + toDoVector.push_back(points[i]); + points.erase(points.begin()+i); + } + + + + if(abs(xDifference)<15 && (yDifference<45) && (yDifference>0)) + { + resultVector.push_back(points[i]); + toDoVector.push_back(points[i]); + points.erase(points.begin()+i); + + } + + + + if(abs(xDifference)<15 && (yDifference> -45) && (yDifference<0)) + { + resultVector.push_back(points[i]); + toDoVector.push_back(points[i]); + points.erase(points.begin()+i); + + } + } + return resultVector; + + } + + + + + + + + /* + stitches images + points have to be loaded in the pointBase first + uses public toDoVector, points + BUG: not all adjacent images are used for stitching - OpenCV evaluates them as not appropriate for stitching + */ + void stitchImgs() + { + int imgIdx = 0; + //main loop + while (!points.empty()) + { + //take the first point from the left and find adjts. to it + Point2d p = points[0]; + vector stitchQueue; + stitchQueue.push_back(p); + points.erase(points.begin()); + + vector temp = getAdjacents(p); //find adj. of first point - inits toDo vector + + + if (toDoVector.empty()) //if first point has no adjts. - log him as singleton + { + ofstream singletonsFile("singletons.log", ios_base::app); + if(!singletonsFile) + { + singletonsFile << "x: " << p.x << std::endl; + singletonsFile << "y: " << p.y << std::endl; + singletonsFile << pathMap[Point2d(p.x,p.y) ] << std::endl; + singletonsFile.close(); + } + else + { + ofstream sing; + sing.open("singletons.log",ios_base::app); + sing << "x: " << p.x << std::endl; + sing << "y: " << p.y << std::endl; + sing << pathMap[Point2d(p.x,p.y) ] << std::endl; + sing.close(); + } + stitchQueue.pop_back(); + continue; + } + + //finds adjacencies to every point + while(!toDoVector.empty()) + { + Point2d p2 = toDoVector[0]; + stitchQueue.push_back(p2); + temp = getAdjacents(p2); + toDoVector.erase(toDoVector.begin()); + } + + //stitching + // Define object to store the stitched image + Mat pano; + + // Create a Stitcher class object with mode scans + Ptr stitcher = Stitcher::create(Stitcher::SCANS); + vector imgs; + + //open stream for logging + string logFileName = to_string(imgIdx) + ".log"; + ofstream logFile(logFileName); + for (Point2d coords: stitchQueue) + { + //log which images are in which result file + logFile << "x: " << coords.x << std::endl; + logFile << "y: " << coords.y << std::endl; + logFile << pathMap[Point2d(coords.x,coords.y) ] << std::endl; + + //log to stdout + cout << "x: " << coords.x << std::endl; + cout << "y: " << coords.y << std::endl; + + + string jsonPath = pathMap[coords]; + string pngPath = jsonPath.erase(jsonPath.length()-4); + pngPath = pngPath + "png"; + cout << "file: " << pngPath << std::endl; + + Mat img = imread(pngPath,IMREAD_COLOR); + //imshow("Location of Images", img);//Showing the circle// + + if (!img.empty()) + { + imgs.push_back(img); //store loaded image in vector of images + } + else + { + cout << "Error: Cannot read image"<< std::endl; + } + + } + logFile.close(); + + + //stitching + cout << "Stitching" << std::endl; + Stitcher::Status status = stitcher->stitch(imgs, pano); + if (status != Stitcher::OK) + { + // Check if images could not be stitched + // status is OK if images are stitched successfully + cout << "Can't stitch images\n"; + } + else + { + + string resultName = "result" + to_string(imgIdx) +".jpg"; + + // Store a new image stitched from the given + //set of images as "result.jpg" + imwrite(resultName, pano); + + // Show the result + imshow(resultName, pano); + imgIdx++; + + waitKey(0); + } + + + } + + } + + }; \ No newline at end of file