197 lines
5 KiB
C++
197 lines
5 KiB
C++
#include <iostream>
|
|
#include <opencv2/highgui.hpp>
|
|
#include <opencv2/imgproc.hpp>
|
|
#include <unistd.h>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
|
|
class Config
|
|
{
|
|
public:
|
|
std::vector<std::string> inputImages;
|
|
std::string maskFileName = "";
|
|
std::string outputFileName = "out.xyz";
|
|
float scaleX = 0.01;
|
|
float scaleY = 0.01;
|
|
float scaleZ = 0.3;
|
|
};
|
|
|
|
void cd_to_exe_dir( char *argv[] )
|
|
{
|
|
std::string path = argv[0];
|
|
int ii = path.length();
|
|
while ( !( path[ii] == '/' || path[ii] == '\\' ) && ii > 0 )
|
|
{
|
|
ii--;
|
|
}
|
|
path.erase( ii, 100 );
|
|
chdir( path.c_str() );
|
|
}
|
|
|
|
static void printUsage()
|
|
{
|
|
std::cout<<"scannassembler --output outImage inImage\n";
|
|
}
|
|
|
|
static int parseCmdArgs(int argc, char** argv, Config *config)
|
|
{
|
|
if (argc == 1)
|
|
{
|
|
printUsage();
|
|
return -1;
|
|
}
|
|
for (int i = 1; i < argc; i++)
|
|
{
|
|
if (std::string(argv[i]) == "--help" || std::string(argv[i]) == "-h")
|
|
{
|
|
printUsage();
|
|
return -1;
|
|
}
|
|
else if (std::string(argv[i]) == "--output" || std::string(argv[i]) == "-o")
|
|
{
|
|
i++;
|
|
if(argc > i) config->outputFileName = argv[i];
|
|
else return -1;
|
|
}
|
|
else if (std::string(argv[i]) == "--mask" || std::string(argv[i]) == "-m")
|
|
{
|
|
i++;
|
|
if(argc > i) config->maskFileName = argv[i];
|
|
else return -1;
|
|
}
|
|
else if (std::string(argv[i]) == "--scale" || std::string(argv[i]) == "-s")
|
|
{
|
|
if(argc > i+3)
|
|
{
|
|
config->scaleX = atof(argv[i+1]);
|
|
config->scaleY = atof(argv[i+2]);
|
|
config->scaleZ = atof(argv[i+3]);
|
|
i+=3;
|
|
}
|
|
else return -1;
|
|
}
|
|
else if (std::string(argv[i]) == "--mask" || std::string(argv[i]) == "-m")
|
|
{
|
|
i++;
|
|
if(argc > i) config->maskFileName = argv[i];
|
|
else return -1;
|
|
}
|
|
else config->inputImages.push_back(argv[i]);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void showImages(std::vector<cv::Mat> images)
|
|
{
|
|
cv::namedWindow( "Viewer", cv::WINDOW_AUTOSIZE );
|
|
for(uint i = 0; i< images.size(); i++)
|
|
{
|
|
cv::imshow( "Viewer", images[i] );
|
|
cv::waitKey(0);
|
|
}
|
|
cv::destroyWindow("Viewer");
|
|
}
|
|
|
|
void showImages(std::vector<cv::UMat> images)
|
|
{
|
|
cv::namedWindow( "Viewer", cv::WINDOW_AUTOSIZE );
|
|
for(uint i = 0; i< images.size(); i++)
|
|
{
|
|
cv::imshow( "Viewer", images[i] );
|
|
cv::waitKey(0);
|
|
}
|
|
cv::destroyWindow("Viewer");
|
|
}
|
|
|
|
void showImages(cv::Mat image)
|
|
{
|
|
cv::namedWindow( "Viewer", cv::WINDOW_AUTOSIZE );
|
|
cv::imshow( "Viewer", image );
|
|
cv::waitKey(0);
|
|
cv::destroyWindow("Viewer");
|
|
}
|
|
|
|
|
|
|
|
std::vector<cv::Mat> loadImages(std::vector<std::string> fileNames)
|
|
{
|
|
std::vector<cv::Mat> images;
|
|
for(uint i = 0; i < fileNames.size(); i++)
|
|
{
|
|
cv::Mat tmpImage = cv::imread(fileNames[i]);
|
|
if(tmpImage.data)images.push_back(tmpImage);
|
|
else
|
|
{
|
|
std::cout<<"can not read image "<<i<<" from "<<fileNames[i]<<'\n';
|
|
}
|
|
}
|
|
return images;
|
|
}
|
|
|
|
|
|
void processImageToCordinates( cv::Mat in, std::ostream& outputFile, float scaleX, float scaleY, float postitionZ )
|
|
{
|
|
for(unsigned int y = 0; y < in.cols; y++)
|
|
for(unsigned int x = 0; x < in.rows; x++)
|
|
{
|
|
if(in.at<uchar>(x,y)) outputFile<<x*scaleX<<' '<<y*scaleY<<' '<<postitionZ<<" \n";
|
|
}
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
std::cout<<"UVOS scann sticher v1\n";
|
|
cd_to_exe_dir( argv );
|
|
|
|
Config config;
|
|
|
|
int parseReturn = parseCmdArgs(argc, argv, &config);
|
|
if(parseReturn != 0) return parseReturn;
|
|
|
|
cv::Mat mask;
|
|
if(config.maskFileName != "")
|
|
{
|
|
mask = cv::imread(config.maskFileName);
|
|
if(!mask.data)
|
|
{
|
|
std::cout<<"could not read mask.\n";
|
|
return 1;
|
|
}
|
|
cv::cvtColor(mask, mask, CV_BGR2GRAY);
|
|
}
|
|
|
|
std::ofstream outputFile( config.outputFileName );
|
|
|
|
for(unsigned int i = 0; i < config.inputImages.size(); i++)
|
|
{
|
|
cv::Mat currentImage = cv::imread(config.inputImages[i]);
|
|
if(!currentImage.data)
|
|
{
|
|
std::cout<<"can not read image "<<i<<" from "<<config.inputImages[i]<<'\n';
|
|
}
|
|
|
|
cv::cvtColor(currentImage, currentImage, CV_BGR2GRAY);
|
|
cv::threshold( currentImage, currentImage, 128,255, cv::THRESH_BINARY );
|
|
cv::Mat maskedImage;
|
|
currentImage.copyTo(maskedImage, mask);
|
|
|
|
cv::GaussianBlur(maskedImage,maskedImage,cv::Size(0,0),10,10);
|
|
cv::threshold( maskedImage, maskedImage, 128,255, cv::THRESH_BINARY);
|
|
|
|
cv::Mat eadgesImage;
|
|
Canny( maskedImage, eadgesImage, 100, 200, 3 );
|
|
|
|
std::stringstream ss;
|
|
ss<<i<<".png";
|
|
|
|
cv::imwrite( ss.str(), eadgesImage );
|
|
|
|
processImageToCordinates( eadgesImage, outputFile, config.scaleX, config.scaleY, 0-config.scaleZ*i );
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|