add logging engine
add options to control harris algorithum
This commit is contained in:
29
argpopt.h
29
argpopt.h
@ -27,10 +27,15 @@ struct Config
|
|||||||
std::string norm = "";
|
std::string norm = "";
|
||||||
std::string maps = "";
|
std::string maps = "";
|
||||||
std::string bg = "";
|
std::string bg = "";
|
||||||
|
int blockSize = 5;
|
||||||
|
int apature = 5;
|
||||||
|
float detectorParameter = 0.01;
|
||||||
|
float minSize = 7;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
|
bool quiet = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *argp_program_version = "0.1";
|
const char *argp_program_version = "0.2";
|
||||||
const char *argp_program_bug_address = "<carl@uvos.xyz>";
|
const char *argp_program_bug_address = "<carl@uvos.xyz>";
|
||||||
static char doc[] = "Program to determine the lubricant thikness on a curved surface";
|
static char doc[] = "Program to determine the lubricant thikness on a curved surface";
|
||||||
static char args_doc[] = "";
|
static char args_doc[] = "";
|
||||||
@ -38,9 +43,14 @@ static char args_doc[] = "";
|
|||||||
static struct argp_option options[] =
|
static struct argp_option options[] =
|
||||||
{
|
{
|
||||||
{"verbose", 'v', 0, 0, "Enable verbose logging" },
|
{"verbose", 'v', 0, 0, "Enable verbose logging" },
|
||||||
|
{"quiet", 'q', 0, 0, "Disable info messages" },
|
||||||
{"map", 'm', "File Name", 0, "remap maps file" },
|
{"map", 'm', "File Name", 0, "remap maps file" },
|
||||||
{"bg", 'b', "File Name", 0, "background image file" },
|
{"bg", 'b', "File Name", 0, "background image file" },
|
||||||
{"normalize", 'n', "File Name", 0, "image to use as a normalization source" },
|
{"normalize", 'n', "File Name", 0, "image to use as a normalization source" },
|
||||||
|
{"apature", 'a', "Value", 0, "Sobel size" },
|
||||||
|
{"block-size", 't', "Value", 0, "Harris neighborhood size " },
|
||||||
|
{"detector-arameter", 'd', "Value", 0, "Harris detector parameter" },
|
||||||
|
{"min-size", 's', "Value", 0, "Smallest feature accepted as a corner" },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,6 +63,9 @@ error_t parse_opt (int key, char *arg, struct argp_state *state)
|
|||||||
case 'v':
|
case 'v':
|
||||||
config->verbose = true;
|
config->verbose = true;
|
||||||
break;
|
break;
|
||||||
|
case 'q':
|
||||||
|
config->quiet = true;
|
||||||
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
config->maps.assign(arg);
|
config->maps.assign(arg);
|
||||||
break;
|
break;
|
||||||
@ -62,6 +75,20 @@ error_t parse_opt (int key, char *arg, struct argp_state *state)
|
|||||||
case 'n':
|
case 'n':
|
||||||
config->norm.assign(arg);
|
config->norm.assign(arg);
|
||||||
break;
|
break;
|
||||||
|
case 'a':
|
||||||
|
config->apature=atol(arg);
|
||||||
|
if(config->apature % 2 == 0) ++config->apature;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
config->blockSize=atol(arg);
|
||||||
|
if(config->blockSize % 2 == 0) ++config->blockSize;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
config->detectorParameter=atol(arg);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
config->minSize=atol(arg);
|
||||||
|
break;
|
||||||
case ARGP_KEY_NO_ARGS:
|
case ARGP_KEY_NO_ARGS:
|
||||||
argp_usage(state);
|
argp_usage(state);
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
|
@ -3,12 +3,13 @@
|
|||||||
#include <opencv2/highgui.hpp>
|
#include <opencv2/highgui.hpp>
|
||||||
#include <opencv2/imgproc.hpp>
|
#include <opencv2/imgproc.hpp>
|
||||||
#include <opencv2/bgsegm.hpp>
|
#include <opencv2/bgsegm.hpp>
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
bool createMask(const cv::Mat& in, cv::Mat& mask, const cv::Mat& bg)
|
bool createMask(const cv::Mat& in, cv::Mat& mask, const cv::Mat& bg)
|
||||||
{
|
{
|
||||||
if(in.size != bg.size || in.type() != bg.type())
|
if(in.size != bg.size || in.type() != bg.type())
|
||||||
{
|
{
|
||||||
std::cerr<<"input image and backgournd image size and type needs to be the same\n";
|
Log(Log::ERROR)<<"input image and backgournd image size and type needs to be the same";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
76
log.h
Normal file
76
log.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Log
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum Level
|
||||||
|
{
|
||||||
|
DEBUG,
|
||||||
|
INFO,
|
||||||
|
WARN,
|
||||||
|
ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool opened = false;
|
||||||
|
Level msglevel = DEBUG;
|
||||||
|
|
||||||
|
inline std::string getLabel(Level level)
|
||||||
|
{
|
||||||
|
std::string label;
|
||||||
|
switch(level)
|
||||||
|
{
|
||||||
|
case DEBUG:
|
||||||
|
label = "DEBUG";
|
||||||
|
break;
|
||||||
|
case INFO:
|
||||||
|
label = "INFO ";
|
||||||
|
break;
|
||||||
|
case WARN:
|
||||||
|
label = "WARN ";
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
label = "ERROR";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
inline static bool headers = false;
|
||||||
|
inline static Level level = WARN;
|
||||||
|
|
||||||
|
Log() {}
|
||||||
|
Log(Level type)
|
||||||
|
{
|
||||||
|
msglevel = type;
|
||||||
|
if(headers)
|
||||||
|
{
|
||||||
|
operator << ("["+getLabel(type)+"]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~Log()
|
||||||
|
{
|
||||||
|
if(opened)
|
||||||
|
{
|
||||||
|
std::cout<<'\n';
|
||||||
|
}
|
||||||
|
opened = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T> Log &operator<<(const T &msg)
|
||||||
|
{
|
||||||
|
if(msglevel >= level)
|
||||||
|
{
|
||||||
|
std::cout<<msg;
|
||||||
|
opened = true;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
19
main.cpp
19
main.cpp
@ -8,6 +8,7 @@
|
|||||||
#include "unwrap.h"
|
#include "unwrap.h"
|
||||||
#include "bgremoval.h"
|
#include "bgremoval.h"
|
||||||
#include "normalize.h"
|
#include "normalize.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
void cd_to_exe_dir( char *argv[] )
|
void cd_to_exe_dir( char *argv[] )
|
||||||
{
|
{
|
||||||
@ -42,11 +43,13 @@ int main(int argc, char* argv[])
|
|||||||
Config config;
|
Config config;
|
||||||
argp_parse(&argp, argc, argv, 0, 0, &config);
|
argp_parse(&argp, argc, argv, 0, 0, &config);
|
||||||
|
|
||||||
|
Log::level = config.quiet ? Log::WARN : config.verbose ? Log::DEBUG : Log::INFO;
|
||||||
|
|
||||||
std::vector<cv::Mat> inImages = loadImages(config.inFileNames);
|
std::vector<cv::Mat> inImages = loadImages(config.inFileNames);
|
||||||
|
|
||||||
if(inImages.empty())
|
if(inImages.empty())
|
||||||
{
|
{
|
||||||
std::cout<<"Input images must be provided!\n";
|
Log(Log::ERROR)<<"Input images must be provided!";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,16 +83,18 @@ int main(int argc, char* argv[])
|
|||||||
cv::waitKey(0);
|
cv::waitKey(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else std::cout<<"can not read background image from "<<config.bg<<'\n';
|
else Log(Log::WARN)<<"can not read background image from "<<config.bg;
|
||||||
}
|
}
|
||||||
createRemapMap(inImages[0], config.inFileNames[0], mask, config.verbose);
|
createRemapMap(inImages[0], config.inFileNames[0], mask,
|
||||||
|
config.blockSize, config.apature, config.detectorParameter,
|
||||||
|
config.minSize, config.verbose);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cv::FileStorage fs(config.maps, cv::FileStorage::READ);
|
cv::FileStorage fs(config.maps, cv::FileStorage::READ);
|
||||||
if (!fs.isOpened())
|
if (!fs.isOpened())
|
||||||
{
|
{
|
||||||
std::cerr<<"could not open maps file " <<config.maps<<'\n';
|
Log(Log::ERROR)<<"could not open maps file " <<config.maps;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
cv::Mat xMat;
|
cv::Mat xMat;
|
||||||
@ -103,9 +108,9 @@ int main(int argc, char* argv[])
|
|||||||
cv::Mat tmp = cv::imread(config.norm);
|
cv::Mat tmp = cv::imread(config.norm);
|
||||||
if(!tmp.data)
|
if(!tmp.data)
|
||||||
{
|
{
|
||||||
std::cerr<<"could not open normalize file " <<config.norm<<'\n';
|
Log(Log::WARN)<<"could not open normalize file " <<config.norm;
|
||||||
}
|
}
|
||||||
applyRemap(tmp, norm, xMat, yMat, cv::Size(900,1000));
|
applyRemap(tmp, norm, xMat, yMat, 500);
|
||||||
if(config.verbose)
|
if(config.verbose)
|
||||||
{
|
{
|
||||||
cv::imshow("Viewer", norm );
|
cv::imshow("Viewer", norm );
|
||||||
@ -121,7 +126,7 @@ int main(int argc, char* argv[])
|
|||||||
cv::waitKey(0);
|
cv::waitKey(0);
|
||||||
}
|
}
|
||||||
cv::Mat remaped;
|
cv::Mat remaped;
|
||||||
applyRemap(image, remaped, xMat, yMat, cv::Size(900,1000));
|
applyRemap(image, remaped, xMat, yMat, 500);
|
||||||
if(norm.data) normalize(remaped, norm);
|
if(norm.data) normalize(remaped, norm);
|
||||||
cv::imshow( "Viewer", remaped );
|
cv::imshow( "Viewer", remaped );
|
||||||
cv::waitKey(0);
|
cv::waitKey(0);
|
||||||
|
@ -22,7 +22,7 @@ inline bool normalize(cv::Mat& image, const cv::Mat& referance)
|
|||||||
std::vector<cv::Mat> labPlanes(3);
|
std::vector<cv::Mat> labPlanes(3);
|
||||||
cv::split(labImage, labPlanes);
|
cv::split(labImage, labPlanes);
|
||||||
|
|
||||||
cv::add(labPlanes[0], labPlanesRef[0], labPlanes[0], cv::noArray(), CV_8UC1);
|
cv::subtract(labPlanes[0], labPlanesRef[0], labPlanes[0], cv::noArray(), CV_8UC1);
|
||||||
cv::merge(labPlanes, labImage);
|
cv::merge(labPlanes, labImage);
|
||||||
cv::cvtColor(labImage, image, cv::COLOR_Lab2BGR);
|
cv::cvtColor(labImage, image, cv::COLOR_Lab2BGR);
|
||||||
return true;
|
return true;
|
||||||
|
91
unwrap.cpp
91
unwrap.cpp
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include "matutils.h"
|
#include "matutils.h"
|
||||||
#include "drawing.h"
|
#include "drawing.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
struct DisplacmentMap
|
struct DisplacmentMap
|
||||||
{
|
{
|
||||||
@ -26,8 +26,8 @@ static std::vector< std::vector<cv::Point2f > > sortPointsIntoRows(std::vector<c
|
|||||||
cv::Point2f topLeft(*getTopLeft(points));
|
cv::Point2f topLeft(*getTopLeft(points));
|
||||||
cv::Point2f bottomRight(*getBottomRight(points));
|
cv::Point2f bottomRight(*getBottomRight(points));
|
||||||
|
|
||||||
std::cout<<"topLeft "<<topLeft.x<<' '<<topLeft.y<<'\n';
|
Log(Log::DEBUG)<<"topLeft "<<topLeft.x<<' '<<topLeft.y;
|
||||||
std::cout<<"bottomRight "<<bottomRight.x<<' '<<bottomRight.y<<'\n';
|
Log(Log::DEBUG)<<"bottomRight "<<bottomRight.x<<' '<<bottomRight.y;
|
||||||
|
|
||||||
float fuzz = (bottomRight.x-topLeft.x)*0.01f;
|
float fuzz = (bottomRight.x-topLeft.x)*0.01f;
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ static float detimineXPitch(const std::vector<cv::Point2f>& row, float fuzz = 1.
|
|||||||
xRowDists.push_back(abs(row[i+1].x-row[i].x));
|
xRowDists.push_back(abs(row[i+1].x-row[i].x));
|
||||||
float xMinDist = *std::min(xRowDists.begin(), xRowDists.end());
|
float xMinDist = *std::min(xRowDists.begin(), xRowDists.end());
|
||||||
|
|
||||||
std::cout<<__func__<<": xMinDist "<<xMinDist<<'\n';
|
Log(Log::DEBUG)<<__func__<<": xMinDist "<<xMinDist;
|
||||||
|
|
||||||
float meanXDistAccum = 0;
|
float meanXDistAccum = 0;
|
||||||
size_t validCount = 0;
|
size_t validCount = 0;
|
||||||
@ -149,7 +149,7 @@ static void thompsonTauTest(const std::vector<float>& in, std::vector<size_t>& o
|
|||||||
{
|
{
|
||||||
if(abs((in[i]-mean)/sd) > rej)
|
if(abs((in[i]-mean)/sd) > rej)
|
||||||
{
|
{
|
||||||
std::cout<<__func__<<": "<<i<<" is outlier mean: "<<mean<<" sd: "<<sd<<" n: "<<n<<'\n';
|
Log(Log::DEBUG)<<__func__<<": "<<i<<" is outlier mean: "<<mean<<" sd: "<<sd<<" n: "<<n<<'\n';
|
||||||
outliers.push_back(i);
|
outliers.push_back(i);
|
||||||
removed = true;
|
removed = true;
|
||||||
}
|
}
|
||||||
@ -212,7 +212,7 @@ static DisplacmentMap calcDisplacementMap(const std::vector< std::vector<cv::Poi
|
|||||||
const std::vector<cv::RotatedRect>& elipses)
|
const std::vector<cv::RotatedRect>& elipses)
|
||||||
{
|
{
|
||||||
if(rows.size() < 2 || rows.size() != elipses.size()) {
|
if(rows.size() < 2 || rows.size() != elipses.size()) {
|
||||||
std::cerr<<__func__<<": rows < 2 or rows != elipses\n";
|
Log(Log::ERROR)<<__func__<<": rows < 2 or rows != elipses";
|
||||||
return DisplacmentMap();
|
return DisplacmentMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +235,7 @@ static DisplacmentMap calcDisplacementMap(const std::vector< std::vector<cv::Poi
|
|||||||
}
|
}
|
||||||
meanYdist = meanYdist/elipses.size();
|
meanYdist = meanYdist/elipses.size();
|
||||||
|
|
||||||
std::cout<<__func__<<": meanYdist "<<meanYdist<<'\n';
|
Log(Log::DEBUG)<<__func__<<": meanYdist "<<meanYdist;
|
||||||
|
|
||||||
for(size_t rowCnt = 0; rowCnt < rows.size(); ++rowCnt)
|
for(size_t rowCnt = 0; rowCnt < rows.size(); ++rowCnt)
|
||||||
{
|
{
|
||||||
@ -244,7 +244,7 @@ static DisplacmentMap calcDisplacementMap(const std::vector< std::vector<cv::Poi
|
|||||||
|
|
||||||
cv::Rect_<float> boundingRect = elipse.boundingRect2f();
|
cv::Rect_<float> boundingRect = elipse.boundingRect2f();
|
||||||
|
|
||||||
std::cout<<__func__<<": Proc row "<<rowCnt<<'\n';
|
Log(Log::DEBUG)<<__func__<<": Proc row "<<rowCnt;
|
||||||
|
|
||||||
for(size_t i = 0; i < row.size(); ++i)
|
for(size_t i = 0; i < row.size(); ++i)
|
||||||
{
|
{
|
||||||
@ -253,7 +253,7 @@ static DisplacmentMap calcDisplacementMap(const std::vector< std::vector<cv::Poi
|
|||||||
double normDist = ((row[i].x - boundingRect.x)/boundingRect.width-0.5)*2;
|
double normDist = ((row[i].x - boundingRect.x)/boundingRect.width-0.5)*2;
|
||||||
double tau = asin(normDist);
|
double tau = asin(normDist);
|
||||||
float xDest = (((2*tau)/M_PI)*500)+500;
|
float xDest = (((2*tau)/M_PI)*500)+500;
|
||||||
std::cout<<__func__<<": normDist "<<normDist<<" tau "<<tau<<" xDest "<<xDest<<'\n';
|
Log(Log::DEBUG)<<__func__<<": normDist "<<normDist<<" tau "<<tau<<" xDest "<<xDest;
|
||||||
displacmentmap.destination[rowCnt].push_back(cv::Point2f(xDest,yDest));
|
displacmentmap.destination[rowCnt].push_back(cv::Point2f(xDest,yDest));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -269,7 +269,7 @@ static void removeSparseCollums(cv::Mat& mat)
|
|||||||
if(mat.at<float>(y,0) >= 0) ++front;
|
if(mat.at<float>(y,0) >= 0) ++front;
|
||||||
if(mat.at<float>(y,mat.cols-1) >= 0) ++back;
|
if(mat.at<float>(y,mat.cols-1) >= 0) ++back;
|
||||||
}
|
}
|
||||||
std::cout<<__func__<<" front: "<<front<<" back "<<back<<'\n';
|
Log(Log::DEBUG)<<__func__<<" front: "<<front<<" back "<<back;
|
||||||
cv::Rect roi;
|
cv::Rect roi;
|
||||||
bool frontRej = (front < mat.rows/2);
|
bool frontRej = (front < mat.rows/2);
|
||||||
bool backRej = (back < mat.rows/2);
|
bool backRej = (back < mat.rows/2);
|
||||||
@ -286,7 +286,7 @@ static void generateRemapMaps(const DisplacmentMap& map, cv::Mat& xMat, cv::Mat&
|
|||||||
{
|
{
|
||||||
if(map.destination.size() < 2)
|
if(map.destination.size() < 2)
|
||||||
{
|
{
|
||||||
std::cerr<<__func__<<": at least 2 rows are needed"<<std::endl;
|
Log(Log::ERROR)<<__func__<<": at least 2 rows are needed";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +297,7 @@ static void generateRemapMaps(const DisplacmentMap& map, cv::Mat& xMat, cv::Mat&
|
|||||||
xMeanDist+=detimineXPitch(map.destination[i]);
|
xMeanDist+=detimineXPitch(map.destination[i]);
|
||||||
}
|
}
|
||||||
xMeanDist/=map.destination.size();
|
xMeanDist/=map.destination.size();
|
||||||
std::cout<<__func__<<": xMeanDist "<<xMeanDist<<'\n';
|
Log(Log::DEBUG)<<__func__<<": xMeanDist "<<xMeanDist;
|
||||||
|
|
||||||
float xMin = std::numeric_limits<float>::max();
|
float xMin = std::numeric_limits<float>::max();
|
||||||
float xMeanMin = 0;
|
float xMeanMin = 0;
|
||||||
@ -313,20 +313,15 @@ static void generateRemapMaps(const DisplacmentMap& map, cv::Mat& xMat, cv::Mat&
|
|||||||
}
|
}
|
||||||
xMeanMin = xMeanMin / map.destination.size();
|
xMeanMin = xMeanMin / map.destination.size();
|
||||||
|
|
||||||
std::cout<<__func__<<": Grid: xMin "<<xMin<<'\n';
|
Log(Log::DEBUG)<<__func__<<": Grid: xMin "<<xMin;
|
||||||
std::cout<<__func__<<": Grid: grid xMax "<<xMax<<'\n';
|
Log(Log::DEBUG)<<__func__<<": Grid: grid xMax "<<xMax;
|
||||||
std::cout<<__func__<<": Grid: grid xMeanMin "<<xMeanMin<<'\n';
|
Log(Log::DEBUG)<<__func__<<": Grid: grid xMeanMin "<<xMeanMin;
|
||||||
/*if(abs(xMeanMin-xMin) > (xMeanDist)/2)
|
|
||||||
{
|
|
||||||
std::cout<<__func__<<": Grid: xMin is outlier\n";
|
|
||||||
xMin = xMeanMin;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
size_t xGridSize = static_cast<size_t>(std::lround(abs((xMax-xMin)/xMeanDist))+1);
|
size_t xGridSize = static_cast<size_t>(std::lround(abs((xMax-xMin)/xMeanDist))+1);
|
||||||
xMat = cv::Mat::zeros(cv::Size(xGridSize, map.destination.size()), CV_32FC1);
|
xMat = cv::Mat::zeros(cv::Size(xGridSize, map.destination.size()), CV_32FC1);
|
||||||
yMat = cv::Mat::zeros(cv::Size(xGridSize, map.destination.size()), CV_32FC1);
|
yMat = cv::Mat::zeros(cv::Size(xGridSize, map.destination.size()), CV_32FC1);
|
||||||
|
|
||||||
std::cout<<"Grid: "<<xGridSize<<'x'<<map.destination.size()<<'\n';
|
Log(Log::DEBUG)<<"Grid: "<<xGridSize<<'x'<<map.destination.size();
|
||||||
|
|
||||||
for(int y = 0; y < xMat.rows; y++)
|
for(int y = 0; y < xMat.rows; y++)
|
||||||
{
|
{
|
||||||
@ -339,32 +334,34 @@ static void generateRemapMaps(const DisplacmentMap& map, cv::Mat& xMat, cv::Mat&
|
|||||||
bool found = findClosest(xIndex, yIndex,
|
bool found = findClosest(xIndex, yIndex,
|
||||||
cv::Point2f((x)*xMeanDist+xMin, (y)*yMeanDist),
|
cv::Point2f((x)*xMeanDist+xMin, (y)*yMeanDist),
|
||||||
map.destination, (2*xMeanDist)/5, (2*yMeanDist)/5);
|
map.destination, (2*xMeanDist)/5, (2*yMeanDist)/5);
|
||||||
std::cout<<__func__<<": found: "<<found<<' '<<xIndex<<'x'<<yIndex<<" at: "<<(x)*xMeanDist+xMin<<'x'<<(y)*yMeanDist<<'\n';
|
Log(Log::DEBUG)<<__func__<<": found: "<<found<<' '<<xIndex<<'x'<<yIndex<<" at: "<<(x)*xMeanDist+xMin<<'x'<<(y)*yMeanDist;
|
||||||
colx[x] = found ? map.source[yIndex][xIndex].x : -1;
|
colx[x] = found ? map.source[yIndex][xIndex].x : -1;
|
||||||
coly[x] = found ? map.source[yIndex][xIndex].y : -1;
|
coly[x] = found ? map.source[yIndex][xIndex].y : -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout<<__func__<<": xMat raw\n"<<xMat<<'\n';
|
Log(Log::DEBUG)<<__func__<<": xMat raw\n"<<xMat;
|
||||||
removeSparseCollums(xMat);
|
removeSparseCollums(xMat);
|
||||||
removeSparseCollums(yMat);
|
removeSparseCollums(yMat);
|
||||||
std::cout<<__func__<<": xMat rejcted\n"<<xMat<<'\n';
|
Log(Log::DEBUG)<<__func__<<": xMat rejcted\n"<<xMat;
|
||||||
fillMissing(xMat);
|
fillMissing(xMat);
|
||||||
std::cout<<__func__<<": xMat filled\n"<<xMat<<'\n';
|
Log(Log::DEBUG)<<__func__<<": xMat filled\n"<<xMat;
|
||||||
interpolateMissing(xMat);
|
interpolateMissing(xMat);
|
||||||
std::cout<<__func__<<": yMat raw \n"<<yMat<<'\n';
|
Log(Log::DEBUG)<<__func__<<": yMat raw \n"<<yMat;
|
||||||
interpolateMissing(yMat);
|
interpolateMissing(yMat);
|
||||||
std::cout<<__func__<<": xMat \n"<<xMat<<'\n';
|
Log(Log::INFO)<<__func__<<": xMat \n"<<xMat;
|
||||||
std::cout<<__func__<<": yMat \n"<<yMat<<'\n';
|
Log(Log::INFO)<<__func__<<": yMat \n"<<yMat;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<cv::Point2f> detectPoints(cv::Mat& image, const cv::Mat& mask, bool verbose = false)
|
static std::vector<cv::Point2f> detectPoints(cv::Mat& image, const cv::Mat& mask,
|
||||||
|
int blockSize = 5, int apature = 5, float detectorParameter = 0.01,
|
||||||
|
float minSize = 7, bool verbose = false)
|
||||||
{
|
{
|
||||||
cv::Mat gray;
|
cv::Mat gray;
|
||||||
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
|
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
|
||||||
|
|
||||||
//detect corners
|
//detect corners
|
||||||
cv::Mat corners;
|
cv::Mat corners;
|
||||||
cv::cornerHarris(gray, corners, 5, 5, 0.01);
|
cv::cornerHarris(gray, corners, blockSize, apature, detectorParameter);
|
||||||
cv::normalize(corners, corners, 0, 255, cv::NORM_MINMAX, CV_32FC1, cv::Mat());
|
cv::normalize(corners, corners, 0, 255, cv::NORM_MINMAX, CV_32FC1, cv::Mat());
|
||||||
cv::convertScaleAbs( corners, corners );
|
cv::convertScaleAbs( corners, corners );
|
||||||
cv::threshold(corners, corners, 50, 255, cv::THRESH_BINARY);
|
cv::threshold(corners, corners, 50, 255, cv::THRESH_BINARY);
|
||||||
@ -381,7 +378,7 @@ static std::vector<cv::Point2f> detectPoints(cv::Mat& image, const cv::Mat& mask
|
|||||||
//get middle of corners
|
//get middle of corners
|
||||||
cv::SimpleBlobDetector::Params blobParams;
|
cv::SimpleBlobDetector::Params blobParams;
|
||||||
blobParams.filterByArea = true;
|
blobParams.filterByArea = true;
|
||||||
blobParams.minArea = 7;
|
blobParams.minArea = minSize;
|
||||||
blobParams.maxArea = 500;
|
blobParams.maxArea = 500;
|
||||||
blobParams.filterByColor = false;
|
blobParams.filterByColor = false;
|
||||||
blobParams.blobColor = 255;
|
blobParams.blobColor = 255;
|
||||||
@ -397,13 +394,15 @@ static std::vector<cv::Point2f> detectPoints(cv::Mat& image, const cv::Mat& mask
|
|||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool createRemapMap(cv::Mat& image, const std::string& fileName, const cv::Mat& mask, bool verbose)
|
bool createRemapMap(cv::Mat& image, const std::string& fileName, const cv::Mat& mask,
|
||||||
|
int blockSize, int apature, float detectorParameter, float minSize,
|
||||||
|
bool verbose)
|
||||||
{
|
{
|
||||||
std::vector<cv::Point2f > points = detectPoints(image, mask, verbose);
|
std::vector<cv::Point2f > points = detectPoints(image, mask, blockSize, apature, detectorParameter, minSize, verbose);
|
||||||
if(verbose) std::cout<<"Found "<<points.size()<<" points\n";
|
if(verbose) std::cout<<"Found "<<points.size()<<" points\n";
|
||||||
if(points.size() < 8)
|
if(points.size() < 8)
|
||||||
{
|
{
|
||||||
std::cout<<"Error creating map, insufficant points detected\n";
|
Log(Log::ERROR)<<"Error creating map, insufficant points detected";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,15 +410,15 @@ bool createRemapMap(cv::Mat& image, const std::string& fileName, const cv::Mat&
|
|||||||
if(verbose) std::cout<<"Found "<<rows.size()<<" rows\n";
|
if(verbose) std::cout<<"Found "<<rows.size()<<" rows\n";
|
||||||
if(rows.size() < 2)
|
if(rows.size() < 2)
|
||||||
{
|
{
|
||||||
std::cout<<"Error creating map, insufficant rows detected\n";
|
Log(Log::ERROR)<<"Error creating map, insufficant rows detected";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector< cv::RotatedRect > ellipses = fitEllipses(rows);
|
std::vector< cv::RotatedRect > ellipses = fitEllipses(rows);
|
||||||
if(verbose) std::cout<<"Found "<<ellipses.size()<<" ellipses. rows reduced to "<<rows.size()<<'\n';
|
if(verbose) Log(Log::INFO)<<"Found "<<ellipses.size()<<" ellipses. rows reduced to "<<rows.size();
|
||||||
if(ellipses.size() < 3)
|
if(ellipses.size() < 3)
|
||||||
{
|
{
|
||||||
std::cout<<"Error creating map, insufficant ellipses detected\n";
|
Log(Log::ERROR)<<"Error creating map, insufficant ellipses detected";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,7 +445,7 @@ bool createRemapMap(cv::Mat& image, const std::string& fileName, const cv::Mat&
|
|||||||
DisplacmentMap dispMap = calcDisplacementMap(rows, ellipses);
|
DisplacmentMap dispMap = calcDisplacementMap(rows, ellipses);
|
||||||
if(dispMap.destination.size() < 2)
|
if(dispMap.destination.size() < 2)
|
||||||
{
|
{
|
||||||
std::cout<<"Error creating map, unable to calculate destination points";
|
Log(Log::ERROR)<<"Error creating map, unable to calculate destination points";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,14 +469,22 @@ bool createRemapMap(cv::Mat& image, const std::string& fileName, const cv::Mat&
|
|||||||
sanityCheckMap(xMat, 0, image.cols-1, 0, image.cols-1);
|
sanityCheckMap(xMat, 0, image.cols-1, 0, image.cols-1);
|
||||||
sanityCheckMap(yMat, 0, image.rows-1, 0, image.rows-1);
|
sanityCheckMap(yMat, 0, image.rows-1, 0, image.rows-1);
|
||||||
|
|
||||||
|
if(xMat.cols < 3 || xMat.rows < 3)
|
||||||
|
{
|
||||||
|
Log(Log::ERROR)<<"Error creating map, to few points with high confidence";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
cv::FileStorage matf(fileName+".mat", cv::FileStorage::WRITE );
|
cv::FileStorage matf(fileName+".mat", cv::FileStorage::WRITE );
|
||||||
matf<<"xmat"<<xMat<<"ymat"<<yMat;
|
matf<<"xmat"<<xMat<<"ymat"<<yMat;
|
||||||
matf.release();
|
matf.release();
|
||||||
|
|
||||||
|
Log(Log::INFO)<<"Unwrap maps saved to "<<fileName<<".mat";
|
||||||
|
|
||||||
if(verbose)
|
if(verbose)
|
||||||
{
|
{
|
||||||
cv::Mat remaped;
|
cv::Mat remaped;
|
||||||
applyRemap(image, remaped, xMat, yMat, cv::Size(900,1000));
|
applyRemap(image, remaped, xMat, yMat, 800);
|
||||||
cv::imshow( "Viewer", remaped );
|
cv::imshow( "Viewer", remaped );
|
||||||
cv::waitKey(0);
|
cv::waitKey(0);
|
||||||
}
|
}
|
||||||
@ -509,12 +516,12 @@ bool findDeadSpace(const cv::Mat& mat, cv::Rect& roi)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyRemap(cv::Mat& image, cv::Mat& out, const cv::Mat& xmap, const cv::Mat& ymap, cv::Size size)
|
void applyRemap(cv::Mat& image, cv::Mat& out, const cv::Mat& xmap, const cv::Mat& ymap, unsigned int outputSize)
|
||||||
{
|
{
|
||||||
cv::Mat xMapResized;
|
cv::Mat xMapResized;
|
||||||
cv::Mat yMapResized;
|
cv::Mat yMapResized;
|
||||||
cv::resize(xmap, xMapResized, cv::Size(800,900), cv::INTER_CUBIC);
|
cv::resize(xmap, xMapResized, cv::Size(outputSize,outputSize*(xmap.rows/(double)xmap.cols)), cv::INTER_CUBIC);
|
||||||
cv::resize(ymap, yMapResized, cv::Size(800,900), cv::INTER_CUBIC);
|
cv::resize(ymap, yMapResized, cv::Size(outputSize,outputSize*(xmap.rows/(double)xmap.cols)), cv::INTER_CUBIC);
|
||||||
cv::Rect roi;
|
cv::Rect roi;
|
||||||
cv::Mat xMapRed;
|
cv::Mat xMapRed;
|
||||||
cv::Mat yMapRed;
|
cv::Mat yMapRed;
|
||||||
|
6
unwrap.h
6
unwrap.h
@ -2,6 +2,8 @@
|
|||||||
#include <opencv2/core/ocl.hpp>
|
#include <opencv2/core/ocl.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
bool createRemapMap(cv::Mat& image, const std::string& fileName, const cv::Mat& mask, bool verbose = false);
|
bool createRemapMap(cv::Mat& image, const std::string& fileName, const cv::Mat& mask,
|
||||||
|
int blockSize = 5, int apature = 5, float detectorParameter = 0.01, float minSize = 7,
|
||||||
|
bool verbose = false);
|
||||||
|
|
||||||
void applyRemap(cv::Mat& image, cv::Mat& out, const cv::Mat& xmap, const cv::Mat& ymap, cv::Size size);
|
void applyRemap(cv::Mat& image, cv::Mat& out, const cv::Mat& xmap, const cv::Mat& ymap, unsigned int size);
|
||||||
|
Reference in New Issue
Block a user