Mill3dScanner/main.cpp
2025-07-23 18:09:20 +02:00

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