@ -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 ) ;
}
}
}
} ;
} ;