Compare commits

..

No commits in common. "0f5ae63b7550dadecf198228b5fda3957fb595f9" and "8b643b03d3e43d0111a155e3e9119aaa36b9b098" have entirely different histories.

8 changed files with 101 additions and 246 deletions

View file

@ -35,13 +35,12 @@ struct Config
bool quiet = false; bool quiet = false;
bool interactive = false; bool interactive = false;
bool simpleStich = false; bool simpleStich = false;
float kFactor = 0;
}; };
const char *argp_program_version = "0.2"; 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.\n\ static char doc[] = "Program to determine the lubricant thikness on a curved surface.\n\
Possible operations: apply create curve mkcurve mkboard show"; Possible operations: apply create curve mkcurve mkboard";
static char args_doc[] = "[OPERATION] IMAGE1 IMAGE2 ..."; static char args_doc[] = "[OPERATION] IMAGE1 IMAGE2 ...";
static struct argp_option options[] = static struct argp_option options[] =
@ -57,7 +56,6 @@ static struct argp_option options[] =
{"interactive", 'i', 0, 0, "interactivly process multiple commands" }, {"interactive", 'i', 0, 0, "interactivly process multiple commands" },
{"simpe-stich", 'a', 0, 0, "Use non blending sticher" }, {"simpe-stich", 'a', 0, 0, "Use non blending sticher" },
{"curve", 'c', "File Name", 0, "curve file name" }, {"curve", 'c', "File Name", 0, "curve file name" },
{"kfactor", 'k', "Value", 0, "set the kfactor" },
{ 0 } { 0 }
}; };
@ -80,7 +78,7 @@ error_t parse_opt (int key, char *arg, struct argp_state *state)
config->norm.assign(arg); config->norm.assign(arg);
break; break;
case 's': case 's':
config->minSize=strtod(arg, nullptr); config->minSize=atol(arg);
break; break;
case 'r': case 'r':
config->harris = true; config->harris = true;
@ -100,9 +98,6 @@ error_t parse_opt (int key, char *arg, struct argp_state *state)
case 'c': case 'c':
config->curve.assign(arg); config->curve.assign(arg);
break; break;
case 'k':
config->kFactor=strtod(arg, nullptr);
break;
case ARGP_KEY_ARG: case ARGP_KEY_ARG:
config->commandsFiles = &state->argv[state->next-1]; config->commandsFiles = &state->argv[state->next-1];
state->next = state->argc; state->next = state->argc;

View file

@ -20,7 +20,10 @@
#include "uvosunwrap/charuco.h" #include "uvosunwrap/charuco.h"
#include <opencv2/aruco/charuco.hpp> #include <opencv2/aruco/charuco.hpp>
#include <opencv2/highgui.hpp> #include <opencv2/highgui.hpp>
#include "uvosunwrap/log.h"
static constexpr unsigned int X_BOARD_SIZE = 18;
static constexpr unsigned int Y_BOARD_SIZE = 10;
void createCharucoBoard(unsigned int size, const std::string& fileName) void createCharucoBoard(unsigned int size, const std::string& fileName)
{ {
@ -28,68 +31,8 @@ void createCharucoBoard(unsigned int size, const std::string& fileName)
cv::aruco::CharucoBoard::create(X_BOARD_SIZE, Y_BOARD_SIZE, 0.03f, 0.02f, cv::aruco::CharucoBoard::create(X_BOARD_SIZE, Y_BOARD_SIZE, 0.03f, 0.02f,
cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_250 )); cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_250 ));
cv::Mat charucoImage; cv::Mat charucoImage;
double cellSize = size/(double)Y_BOARD_SIZE; board->draw(cv::Size((size*18)/10, size), charucoImage, 0, 1);
board->draw(cv::Size((size*X_BOARD_SIZE)/Y_BOARD_SIZE, size), charucoImage, 0, 1); cv::imwrite(fileName, charucoImage);
cv::Mat charucoImageWithBorder =
cv::Mat::zeros(cv::Size(cellSize*(X_BOARD_SIZE+1), cellSize*(Y_BOARD_SIZE+2)), CV_8UC1);
cv::Rect roi(cellSize, cellSize, charucoImage.cols, charucoImage.rows);
charucoImage.copyTo(charucoImageWithBorder(roi));
cv::imwrite(fileName, charucoImageWithBorder);
}
static void seamAjust(std::vector<DetectedPoint>& detections)
{
int xMin = std::numeric_limits<int>::max();
int xMax = std::numeric_limits<int>::min();
for(auto& point : detections)
{
if(point.coordinate.x > xMax)
xMax = point.coordinate.x;
else if(point.coordinate.x < xMin)
xMin = point.coordinate.x;
}
if(xMax - xMin < static_cast<int>(X_BOARD_SIZE/2))
return;
Log(Log::DEBUG)<<"Image contains seam";
int rightMostPoint = 0;
bool extantCol[X_BOARD_SIZE] = {0};
for(auto& point : detections)
{
if(!extantCol[point.coordinate.x])
extantCol[point.coordinate.x] = true;
if(point.coordinate.x > rightMostPoint)
rightMostPoint = point.coordinate.x;
}
int leftCoordinate = 0;
int maxDeadrange = 0;
int deadRange = 0;
for(unsigned int i = 0; i < X_BOARD_SIZE-1; ++i)
{
if(!extantCol[i])
{
++deadRange;
if(extantCol[i+1] && maxDeadrange < deadRange)
{
leftCoordinate = i+1;
maxDeadrange = deadRange;
deadRange = 0;
}
}
}
Log(Log::DEBUG)<<"Left coordinate before seam "<<leftCoordinate
<<" right most "<<rightMostPoint;
for(auto& point : detections)
{
if(point.coordinate.x < leftCoordinate)
point.coordinate.x = point.coordinate.x + rightMostPoint + 1;
}
} }
std::vector<DetectedPoint> detectCharucoPoints(cv::Mat image, bool verbose) std::vector<DetectedPoint> detectCharucoPoints(cv::Mat image, bool verbose)
@ -143,8 +86,6 @@ std::vector<DetectedPoint> detectCharucoPoints(cv::Mat image, bool verbose)
detections.push_back(DetectedPoint(charucoCorners[i], coordiante)); detections.push_back(DetectedPoint(charucoCorners[i], coordiante));
} }
seamAjust(detections);
return detections; return detections;
} }
return std::vector<DetectedPoint>(); return std::vector<DetectedPoint>();

View file

@ -42,7 +42,6 @@ enum {
APPLY_MAP, APPLY_MAP,
APPLY_CURVE, APPLY_CURVE,
CREATE_CURVE, CREATE_CURVE,
SHOW_IMAGE,
EXIT EXIT
}; };
@ -60,8 +59,6 @@ int selectOperation(char** opt)
return CREATE_CURVE; return CREATE_CURVE;
else if(strcmp(opt[0], "mkboard" ) == 0) else if(strcmp(opt[0], "mkboard" ) == 0)
return CREATE_CHARUCO; return CREATE_CHARUCO;
else if(strcmp(opt[0], "show" ) == 0)
return SHOW_IMAGE;
else if(strcmp(opt[0], "exit" ) == 0) else if(strcmp(opt[0], "exit" ) == 0)
return EXIT; return EXIT;
return -1; return -1;
@ -95,7 +92,7 @@ cv::Mat openImageYml(char* fileName)
cv::FileStorage matf(fileName, cv::FileStorage::READ); cv::FileStorage matf(fileName, cv::FileStorage::READ);
matf["image"]>>image; matf["image"]>>image;
if(matf.isOpened() && !image.data) if(matf.isOpened() && (!image.data || image.type() != CV_32FC1))
{ {
Log(Log::WARN)<<fileName<<" dose not contain a valid image"; Log(Log::WARN)<<fileName<<" dose not contain a valid image";
matf.release(); matf.release();
@ -118,19 +115,13 @@ std::vector<cv::Mat> loadImages(char** fileNames)
cv::Mat tmpImage; cv::Mat tmpImage;
const std::string str(fileNames[i]); const std::string str(fileNames[i]);
if(str.find(".mat") != std::string::npos) if(str.find(".mat") != std::string::npos)
{ openImageYml(fileNames[i]);
Log(Log::DEBUG)<<__func__<<": "<<fileNames[i]<<" as YAML image";
tmpImage = openImageYml(fileNames[i]);
}
else else
{
Log(Log::DEBUG)<<__func__<<": "<<fileNames[i]<<" as png image";
tmpImage = openImageImg(fileNames[i]); tmpImage = openImageImg(fileNames[i]);
}
if(tmpImage.data) if(tmpImage.data)
images.push_back(tmpImage); images.push_back(tmpImage);
else else
Log(Log::WARN)<<"can not read image "<<i<<" from "<<fileNames[i]; Log(Log::WARN)<<"can not read image "<<i<<" from "<<fileNames[i]<<'\n';
} }
return images; return images;
} }
@ -138,7 +129,7 @@ std::vector<cv::Mat> loadImages(char** fileNames)
int perfromOperation(int operation, char** fileNames, const Config& config) int perfromOperation(int operation, char** fileNames, const Config& config)
{ {
std::vector<cv::Mat> inImages; std::vector<cv::Mat> inImages;
if(operation == CREATE_MAP || operation == APPLY_MAP || operation == APPLY_CURVE || operation == SHOW_IMAGE) if(operation == CREATE_MAP || operation == APPLY_MAP || operation == APPLY_CURVE)
{ {
inImages = loadImages(fileNames); inImages = loadImages(fileNames);
@ -152,7 +143,7 @@ int perfromOperation(int operation, char** fileNames, const Config& config)
if(operation == CREATE_CHARUCO) if(operation == CREATE_CHARUCO)
{ {
std::string fileName = config.output.empty() ? "out.png" : config.output; std::string fileName = config.output.empty() ? "out.png" : config.output;
createCharucoBoard(config.size*X_BOARD_SIZE, fileName); createCharucoBoard(config.size*14, fileName);
Log(Log::INFO)<<"Exported charuco map of size "<<config.size*14<<" to "<<fileName; Log(Log::INFO)<<"Exported charuco map of size "<<config.size*14<<" to "<<fileName;
return 0; return 0;
} }
@ -211,10 +202,7 @@ int perfromOperation(int operation, char** fileNames, const Config& config)
map.outputCellSize = config.size; map.outputCellSize = config.size;
if(!map.xMat.data) if(!map.xMat.data)
{
Log(Log::ERROR)<<"could not load remap map from "<<std::string(fileNames[i])+".mat";
return -1; return -1;
}
RemapedImage norm; RemapedImage norm;
if(!config.norm.empty()) if(!config.norm.empty())
@ -222,7 +210,7 @@ int perfromOperation(int operation, char** fileNames, const Config& config)
cv::Mat tmp = cv::imread(config.norm); cv::Mat tmp = cv::imread(config.norm);
if(!tmp.data) if(!tmp.data)
{ {
Log(Log::WARN)<<"could not open normalize file "<<config.norm; Log(Log::WARN)<<"could not open normalize file " <<config.norm;
} }
norm = applyRemap(tmp, map); norm = applyRemap(tmp, map);
if(config.verbose) if(config.verbose)
@ -242,15 +230,6 @@ int perfromOperation(int operation, char** fileNames, const Config& config)
{ {
cv::imshow( "Viewer", remaped.image ); cv::imshow( "Viewer", remaped.image );
cv::waitKey(0); cv::waitKey(0);
cv::imshow( "Viewer", remaped.angle);
cv::waitKey(0);
}
applyKfactor(remaped.image, remaped.angle, config.kFactor);
if(config.verbose)
{
cv::imshow("Viewer", remaped.image );
cv::waitKey(0);
} }
remapedImages.push_back(remaped); remapedImages.push_back(remaped);
@ -282,23 +261,17 @@ int perfromOperation(int operation, char** fileNames, const Config& config)
cv::FileStorage fs(config.curve, cv::FileStorage::READ); cv::FileStorage fs(config.curve, cv::FileStorage::READ);
cv::Mat curve; cv::Mat curve;
fs["cal"]>>curve; fs["curve"]>>curve;
if(!curve.data || curve.type() != CV_32FC1 || curve.rows != 2 || curve.cols < 3) if(!curve.data || curve.type() != CV_32FC1 || curve.rows != 2 || curve.cols < 3)
{ {
Log(Log::INFO)<<"invalid curve"; Log(Log::INFO)<<"invalid curve";
return -1; return -1;
} }
if(inImages[0].channels() > 1)
cvtColor(inImages[0], inImages[0], cv::COLOR_BGR2GRAY); cvtColor(inImages[0], inImages[0], cv::COLOR_BGR2GRAY);
if(inImages[0].type() != CV_32FC1)
inImages[0].convertTo(inImages[0], CV_32F); inImages[0].convertTo(inImages[0], CV_32F);
Log(Log::DEBUG)<<"applyCurve";
applyCurve(inImages[0], curve); applyCurve(inImages[0], curve);
cv::FileStorage fsO("out.mat", cv::FileStorage::WRITE);
fsO<<"image"<<inImages[0];
fsO.release();
} }
else if(operation == CREATE_CURVE) else if(operation == CREATE_CURVE)
{ {
@ -350,16 +323,6 @@ int perfromOperation(int operation, char** fileNames, const Config& config)
std::cout<<"Curve saved to "<<(!config.output.empty() ? config.output : "curve.mat")<<'\n'; std::cout<<"Curve saved to "<<(!config.output.empty() ? config.output : "curve.mat")<<'\n';
} }
else if(operation == SHOW_IMAGE)
{
cv::namedWindow("Show Image", cv::WINDOW_NORMAL );
for(size_t i = 0; i < inImages.size(); ++i)
{
cv::imshow("Show Image", inImages[i]);
cv::waitKey(0);
}
cv::destroyWindow("Show Image");
}
else if(operation == EXIT) else if(operation == EXIT)
return -1; return -1;
return 0; return 0;

View file

@ -178,7 +178,7 @@ bool findClosest(size_t& index, const cv::Point2f point, const std::vector<cv::P
return found; return found;
} }
void interpolateMissingOnX(cv::Mat& mat) void interpolateMissing(cv::Mat& mat)
{ {
assert(mat.type() == CV_32FC1); assert(mat.type() == CV_32FC1);
@ -223,48 +223,34 @@ void interpolateMissingOnX(cv::Mat& mat)
} }
} }
void interpolateMissingOnY(cv::Mat& mat) void fillMissing(cv::Mat& mat)
{ {
assert(mat.type() == CV_32FC1); assert(mat.type() == CV_32FC1);
for(int x = 0; x < mat.cols; ++x) bool finished = true;
{
for(int y = 0; y < mat.rows; y++) for(int y = 0; y < mat.rows; y++)
{ {
if(mat.at<float>(y,x) < 0) float* col = mat.ptr<float>(y);
for(int x = 0; x < mat.cols; ++x)
{ {
int closestA = -1; if(col[x] < 0 && col[x] > -2)
int closestB = -1;
int dist = std::numeric_limits<int>::max();
for(int i = 0; i < mat.rows; i++)
{ {
if(i != closestA && mat.at<float>(i,x) >= 0 && abs(i-y) <= dist) if(y > 0 && mat.at<float>(y-1,x) >= 0)
{ {
closestB = closestA; col[x] = mat.at<float>(y-1,x);
closestA = i; finished = false;
dist = abs(i-y);
} }
} else if(y < mat.rows-1 && mat.at<float>(y+1,x) >= 0)
if(closestA < 0 || closestB < 0)
{ {
closestA = -1; col[x] = mat.at<float>(y+1,x);
closestB = -1; finished = false;
dist = std::numeric_limits<int>::max(); }
for(int i = mat.rows-1; i >= 0; --i) if(col[x] > 0 && ((x+1 < mat.cols && col[x] > col[x+1]) || (x > 0 && col[x] < col[x-1])))
{ col[x] = -2;
if(i != closestA && mat.at<float>(i,x) >= 0 && abs(i-y) <= dist)
{
closestB = closestA;
closestA = i;
dist = abs(i-y);
}
}
}
float slope = (mat.at<float>(closestB,x) - mat.at<float>(closestA,x))/(closestB-closestA);
mat.at<float>(y,x) = mat.at<float>(closestA,x) - (closestA-y)*slope;
} }
} }
} }
if(!finished) fillMissing(mat);
} }
bool findDeadSpace(const cv::Mat& mat, cv::Rect& roi) bool findDeadSpace(const cv::Mat& mat, cv::Rect& roi)
@ -301,25 +287,66 @@ bool findDeadSpace(const cv::Mat& mat, cv::Rect& roi)
return true; return true;
} }
void removeSparseCols(cv::Mat& mat, float reject, bool front) bool deleteEmptyCols(cv::Mat& mat)
{
assert(mat.type() == CV_32FC1);
std::vector<size_t> cols;
cols.reserve(mat.cols);
for(int x = 0; x < mat.cols; x++)
{
bool empty = true;
for(int y = 0; y < mat.rows; y++)
{
if(mat.at<float>(x,y) > 0)
{
empty = false;
break;
}
}
if(!empty)
cols.push_back(x);
}
if(mat.cols < static_cast<long int>(cols.size()))
{
cv::Mat tmp(cv::Size(cols.size(), mat.rows), CV_32FC1);
for(auto& col : cols)
{
cv::Rect roi(cv::Point2i(col, 0), cv::Size(1, mat.rows));
mat.copyTo(tmp(roi));
}
mat.release();
mat = tmp;
return true;
}
return false;
}
void removeSparseCols(cv::Mat& mat, bool front)
{ {
assert(mat.type() == CV_32FC1); assert(mat.type() == CV_32FC1);
int count = 0; int count = 0;
for(int y = 0; y < mat.rows; ++y) for(int y = 0; y < mat.rows; ++y)
{ {
if((front && mat.at<float>(y,0) >= 0) || (!front && mat.at<float>(y,mat.cols-1) >= 0)) if(front && mat.at<float>(y,0) >= 0) ++count;
++count; else if(mat.at<float>(y,mat.cols-1) >= 0) ++count;
} }
cv::Rect roi; cv::Rect roi;
bool rej = (count < mat.rows*reject); bool rej = (count < mat.rows/2);
roi.x=front ? rej : 0; roi.x=front ? rej : 0;
roi.y=0; roi.y=0;
roi.width = mat.cols - rej; roi.width = mat.cols - rej;
roi.height = mat.rows; roi.height = mat.rows;
mat = mat(roi); mat = mat(roi);
if(rej) if(rej)
removeSparseCols(mat, reject, front); removeSparseCols(mat, front);
} }
static float linInterpolate(float A, float B, float x) static float linInterpolate(float A, float B, float x)

View file

@ -37,13 +37,15 @@ bool findClosest(size_t& index, const cv::Point2f point, const std::vector<cv::P
void thompsonTauTest(const std::vector<float>& in, std::vector<size_t>& outliers, float criticalValue); void thompsonTauTest(const std::vector<float>& in, std::vector<size_t>& outliers, float criticalValue);
void interpolateMissingOnX(cv::Mat& mat); void interpolateMissing(cv::Mat& mat);
void interpolateMissingOnY(cv::Mat& mat); void fillMissing(cv::Mat& mat);
bool findDeadSpace(const cv::Mat& mat, cv::Rect& roi); bool findDeadSpace(const cv::Mat& mat, cv::Rect& roi);
void removeSparseCols(cv::Mat& mat, float reject, bool front); bool deleteEmptyCols(cv::Mat& mat);
void removeSparseCols(cv::Mat& mat, bool front);
bool bilinearResize(const cv::Mat& inImage, cv::Mat& outImage, cv::Size size); bool bilinearResize(const cv::Mat& inImage, cv::Mat& outImage, cv::Size size);

View file

@ -66,7 +66,7 @@ static void sortIntoRemapMaps(const std::vector<DetectedPoint>& points, cv::Mat&
xMat = -1; xMat = -1;
yMat = -1; yMat = -1;
Log(Log::DEBUG)<<__func__<<"Grid: "<<xGridSize<<'x'<<yGridSize; Log(Log::DEBUG)<<"Grid: "<<xGridSize<<'x'<<yGridSize;
for(int y = 0; y < xMat.rows; y++) for(int y = 0; y < xMat.rows; y++)
{ {
@ -97,20 +97,22 @@ bool createRemapMap(const cv::Mat& image, RemapMap& out, const std::vector<Detec
Log(Log::DEBUG)<<__func__<<": xMat raw\n"<<out.xMat; Log(Log::DEBUG)<<__func__<<": xMat raw\n"<<out.xMat;
int cols = out.xMat.cols; int cols = out.xMat.cols;
removeSparseCols(out.xMat, 0.75,true); removeSparseCols(out.xMat, true);
out.topLeftCoordinate.x += cols-out.xMat.cols; out.topLeftCoordinate.x += cols-out.xMat.cols;
removeSparseCols(out.xMat, 0.75, false); removeSparseCols(out.xMat, false);
removeSparseCols(out.yMat, 0.75, true); removeSparseCols(out.yMat, true);
removeSparseCols(out.yMat, 0.75, false); removeSparseCols(out.yMat, false);
Log(Log::DEBUG)<<__func__<<": xMat rejcted\n"<<out.xMat; Log(Log::DEBUG)<<__func__<<": xMat rejcted\n"<<out.xMat;
fillMissing(out.xMat);
Log(Log::DEBUG)<<__func__<<": xMat filled\n"<<out.xMat; Log(Log::DEBUG)<<__func__<<": xMat filled\n"<<out.xMat;
interpolateMissingOnY(out.xMat); interpolateMissing(out.xMat);
interpolateMissingOnY(out.yMat); interpolateMissing(out.yMat);
sanityCheckMap(out.xMat, 0, image.cols-1, -1, -1); sanityCheckMap(out.xMat, 0, image.cols-1, -1, -1);
sanityCheckMap(out.yMat, 0, image.rows-1, -1, -1); sanityCheckMap(out.yMat, 0, image.rows-1, -1, -1);
interpolateMissingOnY(out.xMat); fillMissing(out.xMat);
interpolateMissingOnY(out.yMat); interpolateMissing(out.xMat);
interpolateMissing(out.yMat);
sanityCheckMap(out.xMat, 0, image.cols-1, 0, image.cols-1); sanityCheckMap(out.xMat, 0, image.cols-1, 0, image.cols-1);
sanityCheckMap(out.yMat, 0, image.rows-1, 0, image.rows-1); sanityCheckMap(out.yMat, 0, image.rows-1, 0, image.rows-1);
@ -157,82 +159,17 @@ RemapMap loadRemapMap(const std::string& fileName)
return map; return map;
} }
void applyKfactor(cv::Mat& image, const cv::Mat& angleMat, float kFactor)
{
assert(image.type() == CV_8UC1 && angleMat.type() == CV_32FC1);
for(int y = 0; y < image.rows; y++)
{
uint8_t* colx = image.ptr<uint8_t>(y);
const float* anglex = angleMat.ptr<float>(y);
for(int x = 0; x < image.cols; x++)
{
int value = colx[x]*(1-(anglex[x]*kFactor));
if(value < 0)
value = 0;
else if(value > 255)
value = 255;
colx[x] = value;
}
}
}
static void generateAngleMats(const cv::Mat& xMat, const cv::Mat& yMat, cv::Mat& greatestAngle)
{
std::cout<<xMat<<std::endl;
greatestAngle.create(xMat.rows-1, xMat.cols-1, CV_32FC1);
double max = 0;
for(int y = 0; y < xMat.rows-1; y++)
{
for(int x = 0; x < xMat.cols-1; x++)
{
cv::Point2f pA(xMat.at<float>(y,x), yMat.at<float>(y,x));
cv::Point2f pB(xMat.at<float>(y,x+1), yMat.at<float>(y,x+1));
cv::Point2f pC(xMat.at<float>(y+1,x), yMat.at<float>(y+1,x));
double normX = cv::norm(pA-pB);
double normY = cv::norm(pA-pC);
if(normX > max)
max = normX;
if(normY > max)
max = normY;
}
}
for(int y = 0; y < xMat.rows-1; y++)
{
for(int x = 0; x < xMat.cols-1; x++)
{
cv::Point2f pA(xMat.at<float>(y,x), yMat.at<float>(y,x));
cv::Point2f pB(xMat.at<float>(y,x+1), yMat.at<float>(y,x+1));
cv::Point2f pC(xMat.at<float>(y+1,x), yMat.at<float>(y+1,x));
double normX = cv::norm(pA-pB);
double normY = cv::norm(pA-pC);
greatestAngle.at<float>(y,x) = 1-(std::min(normX, normY)/max);
if(y == 0)
Log(Log::DEBUG)<<greatestAngle.at<float>(y,x);
}
}
}
RemapedImage applyRemap(const cv::Mat& image, const RemapMap &map) RemapedImage applyRemap(const cv::Mat& image, const RemapMap &map)
{ {
RemapedImage out; RemapedImage out;
cv::Mat xMapResized; cv::Mat xMapResized;
cv::Mat yMapResized; cv::Mat yMapResized;
const cv::Size outputSize(map.outputCellSize*map.xMat.cols,map.outputCellSize*map.xMat.rows); const cv::Size outputSize(map.outputCellSize*map.xMat.cols,map.outputCellSize*map.xMat.rows);
cv::Rect noBorderRoi(map.outputCellSize/2, map.outputCellSize/2,
outputSize.width-map.outputCellSize, outputSize.height-map.outputCellSize);
generateAngleMats(map.xMat, map.yMat, out.angle);
cv::Mat angleResized;
cv::resize(out.angle, angleResized, outputSize, cv::INTER_LINEAR);
out.angle = angleResized(noBorderRoi);
cv::resize(map.xMat, xMapResized, outputSize, cv::INTER_LINEAR); cv::resize(map.xMat, xMapResized, outputSize, cv::INTER_LINEAR);
cv::resize(map.yMat, yMapResized, outputSize, cv::INTER_LINEAR); cv::resize(map.yMat, yMapResized, outputSize, cv::INTER_LINEAR);
cv::Rect noBorderRoi(map.outputCellSize/2, map.outputCellSize/2,
outputSize.width-map.outputCellSize, outputSize.height-map.outputCellSize);
cv::Mat xMapRed = xMapResized(noBorderRoi); cv::Mat xMapRed = xMapResized(noBorderRoi);
cv::Mat yMapRed = yMapResized(noBorderRoi); cv::Mat yMapRed = yMapResized(noBorderRoi);
cv::remap(image, out.image, xMapRed, yMapRed, cv::INTER_LINEAR); cv::remap(image, out.image, xMapRed, yMapRed, cv::INTER_LINEAR);
@ -261,10 +198,10 @@ cv::Mat simpleStich(const std::vector<RemapedImage>& images)
if(topLeft.y > image.origin.y) if(topLeft.y > image.origin.y)
topLeft.y = image.origin.y; topLeft.y = image.origin.y;
Log(Log::DEBUG)<<__func__<<"image: "<<image.image.rows<<'x'<<image.image.cols<<" at "<<image.origin.x<<'x'<<image.origin.y; Log(Log::DEBUG)<<"image: "<<image.image.rows<<'x'<<image.image.cols<<" at "<<image.origin.x<<'x'<<image.origin.y;
} }
Log(Log::DEBUG)<<__func__<<"outputSize: "<<outputSize; Log(Log::DEBUG)<<"outputSize: "<<outputSize;
cv::Mat out(outputSize, images[0].image.type(), cv::Scalar::all(0)); cv::Mat out(outputSize, images[0].image.type(), cv::Scalar::all(0));
@ -282,13 +219,9 @@ cv::Mat simpleStich(const std::vector<RemapedImage>& images)
cv::Mat stich(std::vector<RemapedImage>& images, bool seamAdjust) cv::Mat stich(std::vector<RemapedImage>& images, bool seamAdjust)
{ {
assert(images.size() > 0);
for(auto& image : images) for(auto& image : images)
assert(image.image.type() == CV_8UC3 || image.image.type() == CV_8UC1); assert(image.image.type() == CV_8UC3 || image.image.type() == CV_8UC1);
Log(Log::DEBUG)<<__func__<<" got "<<images.size()<<" of type "<<images[0].image.type()<<" size "<<images[0].image.size();
for(auto& image : images) for(auto& image : images)
{ {
if(image.image.type() == CV_8UC1) if(image.image.type() == CV_8UC1)

View file

@ -23,9 +23,6 @@
#include <opencv2/core/ocl.hpp> #include <opencv2/core/ocl.hpp>
#include "detectedpoint.h" #include "detectedpoint.h"
static constexpr unsigned int X_BOARD_SIZE = 20;
static constexpr unsigned int Y_BOARD_SIZE = 12;
void createCharucoBoard(unsigned int size, const std::string& fileName); void createCharucoBoard(unsigned int size, const std::string& fileName);
std::vector<DetectedPoint> detectCharucoPoints(cv::Mat image, bool verbose = true); std::vector<DetectedPoint> detectCharucoPoints(cv::Mat image, bool verbose = true);

View file

@ -25,7 +25,6 @@
struct RemapedImage struct RemapedImage
{ {
cv::Mat image; cv::Mat image;
cv::Mat angle;
cv::Point2i origin; cv::Point2i origin;
}; };
@ -45,7 +44,5 @@ bool createRemapMap(const cv::Mat& image, RemapMap& out, const std::vector<Detec
RemapedImage applyRemap(const cv::Mat& image, const RemapMap &map); RemapedImage applyRemap(const cv::Mat& image, const RemapMap &map);
void applyKfactor(cv::Mat& image ,const cv::Mat& angleMat, float kFactor);
cv::Mat stich(std::vector<RemapedImage>& images, bool seamAdjust = false); cv::Mat stich(std::vector<RemapedImage>& images, bool seamAdjust = false);
cv::Mat simpleStich(const std::vector<RemapedImage>& images); cv::Mat simpleStich(const std::vector<RemapedImage>& images);