From 913bcd567fc7bbad92680bb8abd137d2a70141ce Mon Sep 17 00:00:00 2001 From: Pavol Debnar Date: Sun, 16 Oct 2022 18:09:09 +0200 Subject: [PATCH] updated pointbase, now with actual stitching stitching functionality added to pointbase, bug prevails where stitcher will not deem some images worthy for stitching (usually about half of adj. images are stitched) --- src/pointbase.cpp | 225 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 221 insertions(+), 4 deletions(-) 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