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)
main
Pavol Debnar 2 years ago
parent 0c7f6aea3d
commit 913bcd567f

@ -1,8 +1,13 @@
#include "opencv2/highgui.hpp" #include "opencv2/highgui.hpp"
#include "opencv2/core.hpp" #include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp" #include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/stitching.hpp"
#include <fstream>
#include <iostream> #include <iostream>
#include <json/json.h> #include <json/json.h>
#include <cmath>
#include <fstream> #include <fstream>
#include <algorithm> #include <algorithm>
#include <map> #include <map>
@ -31,9 +36,10 @@ struct ComparePoints
class PointBase { class PointBase {
public: public:
vector <Point2d> points; vector <Point2d> points; //all points - points are being removed as adjacencies are found
vector <Point2d> doneVector; vector <Point2d> doneVector; //points that have been successfully searched for adjacencies
std::map<Point2d, string, ComparePoints> pathMap; vector <Point2d> toDoVector; //points yet to be searched for adjacent points
std::map<Point2d, string, ComparePoints> 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/"; //std::string path = "../data/";
for (const auto & entry : fs::directory_iterator(path)) 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; //cout << filePath.find(".json") << std::endl;
if (filePath.find(".json") != string::npos) if (filePath.find(".json") != string::npos)
{ {
@ -72,6 +78,12 @@ class PointBase {
} }
} }
void printPoints(int which=0) void printPoints(int which=0)
{ {
if (which==1) // prints current points vector if (which==1) // prints current points vector
@ -97,6 +109,12 @@ class PointBase {
} }
string getPath(double x, double y) string getPath(double x, double y)
{ {
string path = pathMap[Point2d(x,y)]; string path = pathMap[Point2d(x,y)];
@ -104,6 +122,13 @@ class PointBase {
} }
//shows the location of loaded points on an images //shows the location of loaded points on an images
//useful for debugging //useful for debugging
void showPointImg() void showPointImg()
@ -116,4 +141,196 @@ class PointBase {
imshow("Location of Images", img);//Showing the circle// imshow("Location of Images", img);//Showing the circle//
waitKey(0);//Waiting for Keystroke// 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<Point2d> getAdjacents(Point2d inputPoint)
{
vector<Point2d> 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<Point2d> stitchQueue;
stitchQueue.push_back(p);
points.erase(points.begin());
vector<Point2d> 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 = Stitcher::create(Stitcher::SCANS);
vector<Mat> 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);
}
}
}
}; };
Loading…
Cancel
Save