From 2e3d0d29383342e73f6f3c255cb8da62dad17a64 Mon Sep 17 00:00:00 2001 From: uvos Date: Thu, 1 Jul 2021 23:36:55 +0200 Subject: [PATCH 01/10] Fix charuco algo when an image spanns the break between ends of the board up board size a bit --- src/charuco.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++---- src/main.cpp | 2 +- 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/src/charuco.cpp b/src/charuco.cpp index 14f8b2b..48b8ef4 100644 --- a/src/charuco.cpp +++ b/src/charuco.cpp @@ -20,9 +20,10 @@ #include "uvosunwrap/charuco.h" #include #include +#include "uvosunwrap/log.h" -static constexpr unsigned int X_BOARD_SIZE = 18; -static constexpr unsigned int Y_BOARD_SIZE = 10; +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) @@ -30,9 +31,65 @@ void createCharucoBoard(unsigned int size, const std::string& fileName) cv::Ptr board = cv::aruco::CharucoBoard::create(X_BOARD_SIZE, Y_BOARD_SIZE, 0.03f, 0.02f, cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_250 )); - cv::Mat charucoImage; - board->draw(cv::Size((size*18)/10, size), charucoImage, 0, 1); - cv::imwrite(fileName, charucoImage); + cv::Mat charucoImage; + double cellSize = size/(double)Y_BOARD_SIZE; + board->draw(cv::Size((size*X_BOARD_SIZE)/Y_BOARD_SIZE, size), charucoImage, 0, 1); + cv::Mat charucoImageWithBorder = + cv::Mat::zeros(cv::Size(cellSize*(X_BOARD_SIZE+2), 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& detections) +{ + int xMin = std::numeric_limits::max(); + int xMax = std::numeric_limits::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(X_BOARD_SIZE/2)) + return; + + Log(Log::DEBUG)<<"Image contains seam"; + + bool extantCol[X_BOARD_SIZE] = {0}; + for(auto& point : detections) + { + if(!extantCol[point.coordinate.x]) + extantCol[point.coordinate.x] = true; + } + + 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 "< detectCharucoPoints(cv::Mat image, bool verbose) @@ -86,6 +143,8 @@ std::vector detectCharucoPoints(cv::Mat image, bool verbose) detections.push_back(DetectedPoint(charucoCorners[i], coordiante)); } + seamAjust(detections); + return detections; } return std::vector(); diff --git a/src/main.cpp b/src/main.cpp index 3ec1c41..0ac8aef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -143,7 +143,7 @@ int perfromOperation(int operation, char** fileNames, const Config& config) if(operation == CREATE_CHARUCO) { std::string fileName = config.output.empty() ? "out.png" : config.output; - createCharucoBoard(config.size*14, fileName); + createCharucoBoard(config.size*42, fileName); Log(Log::INFO)<<"Exported charuco map of size "< Date: Fri, 2 Jul 2021 00:26:20 +0200 Subject: [PATCH 02/10] be more picky about front and back cols --- src/charuco.cpp | 6 +---- src/main.cpp | 2 +- src/matutils.cpp | 50 ++++------------------------------------ src/matutils.h | 4 +--- src/unwrap.cpp | 8 +++---- src/uvosunwrap/charuco.h | 3 +++ 6 files changed, 15 insertions(+), 58 deletions(-) diff --git a/src/charuco.cpp b/src/charuco.cpp index 48b8ef4..8628e0e 100644 --- a/src/charuco.cpp +++ b/src/charuco.cpp @@ -22,10 +22,6 @@ #include #include "uvosunwrap/log.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) { cv::Ptr board = @@ -35,7 +31,7 @@ void createCharucoBoard(unsigned int size, const std::string& fileName) double cellSize = size/(double)Y_BOARD_SIZE; board->draw(cv::Size((size*X_BOARD_SIZE)/Y_BOARD_SIZE, size), charucoImage, 0, 1); cv::Mat charucoImageWithBorder = - cv::Mat::zeros(cv::Size(cellSize*(X_BOARD_SIZE+2), cellSize*(Y_BOARD_SIZE+2)), CV_8UC1); + 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); diff --git a/src/main.cpp b/src/main.cpp index 0ac8aef..d1395e8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -143,7 +143,7 @@ int perfromOperation(int operation, char** fileNames, const Config& config) if(operation == CREATE_CHARUCO) { std::string fileName = config.output.empty() ? "out.png" : config.output; - createCharucoBoard(config.size*42, fileName); + createCharucoBoard(config.size*X_BOARD_SIZE, fileName); Log(Log::INFO)<<"Exported charuco map of size "< 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(x,y) > 0) - { - empty = false; - break; - } - } - - if(!empty) - cols.push_back(x); - } - - if(mat.cols < static_cast(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) +void removeSparseCols(cv::Mat& mat, float reject, bool front) { assert(mat.type() == CV_32FC1); @@ -339,14 +299,14 @@ void removeSparseCols(cv::Mat& mat, bool front) else if(mat.at(y,mat.cols-1) >= 0) ++count; } cv::Rect roi; - bool rej = (count < mat.rows/2); + bool rej = (count < mat.rows*reject); roi.x=front ? rej : 0; roi.y=0; roi.width = mat.cols - rej; roi.height = mat.rows; mat = mat(roi); if(rej) - removeSparseCols(mat, front); + removeSparseCols(mat, reject, front); } static float linInterpolate(float A, float B, float x) diff --git a/src/matutils.h b/src/matutils.h index 3e96024..3d711e9 100644 --- a/src/matutils.h +++ b/src/matutils.h @@ -43,9 +43,7 @@ void fillMissing(cv::Mat& mat); bool findDeadSpace(const cv::Mat& mat, cv::Rect& roi); -bool deleteEmptyCols(cv::Mat& mat); - -void removeSparseCols(cv::Mat& mat, bool front); +void removeSparseCols(cv::Mat& mat, float reject, bool front); bool bilinearResize(const cv::Mat& inImage, cv::Mat& outImage, cv::Size size); diff --git a/src/unwrap.cpp b/src/unwrap.cpp index 707ba5d..7414c96 100644 --- a/src/unwrap.cpp +++ b/src/unwrap.cpp @@ -97,11 +97,11 @@ bool createRemapMap(const cv::Mat& image, RemapMap& out, const std::vector #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); std::vector detectCharucoPoints(cv::Mat image, bool verbose = true); From 6fa7e9eb9d9327a3a9c5e26368508d812ac27394 Mon Sep 17 00:00:00 2001 From: uvos Date: Mon, 5 Jul 2021 11:26:23 +0200 Subject: [PATCH 03/10] add show image operation --- src/argpopt.h | 2 +- src/main.cpp | 29 ++++++++++++++++++++++----- src/matutils.cpp | 51 ++++++++++++++++++++++++++++++------------------ src/matutils.h | 4 ++-- src/unwrap.cpp | 20 ++++++++++--------- 5 files changed, 70 insertions(+), 36 deletions(-) diff --git a/src/argpopt.h b/src/argpopt.h index 1a40e30..7bee75a 100644 --- a/src/argpopt.h +++ b/src/argpopt.h @@ -40,7 +40,7 @@ struct Config const char *argp_program_version = "0.2"; const char *argp_program_bug_address = ""; static char doc[] = "Program to determine the lubricant thikness on a curved surface.\n\ -Possible operations: apply create curve mkcurve mkboard"; +Possible operations: apply create curve mkcurve mkboard show"; static char args_doc[] = "[OPERATION] IMAGE1 IMAGE2 ..."; static struct argp_option options[] = diff --git a/src/main.cpp b/src/main.cpp index d1395e8..23d6265 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,6 +42,7 @@ enum { APPLY_MAP, APPLY_CURVE, CREATE_CURVE, + SHOW_IMAGE, EXIT }; @@ -59,6 +60,8 @@ int selectOperation(char** opt) return CREATE_CURVE; else if(strcmp(opt[0], "mkboard" ) == 0) return CREATE_CHARUCO; + else if(strcmp(opt[0], "show" ) == 0) + return SHOW_IMAGE; else if(strcmp(opt[0], "exit" ) == 0) return EXIT; return -1; @@ -115,13 +118,19 @@ std::vector loadImages(char** fileNames) cv::Mat tmpImage; const std::string str(fileNames[i]); if(str.find(".mat") != std::string::npos) - openImageYml(fileNames[i]); - else - tmpImage = openImageImg(fileNames[i]); + { + Log(Log::DEBUG)<<__func__<<": "< loadImages(char** fileNames) int perfromOperation(int operation, char** fileNames, const Config& config) { std::vector inImages; - if(operation == CREATE_MAP || operation == APPLY_MAP || operation == APPLY_CURVE) + if(operation == CREATE_MAP || operation == APPLY_MAP || operation == APPLY_CURVE || operation == SHOW_IMAGE) { inImages = loadImages(fileNames); @@ -323,6 +332,16 @@ int perfromOperation(int operation, char** fileNames, const Config& config) 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) return -1; return 0; diff --git a/src/matutils.cpp b/src/matutils.cpp index bf4d893..5bea21d 100644 --- a/src/matutils.cpp +++ b/src/matutils.cpp @@ -178,7 +178,7 @@ bool findClosest(size_t& index, const cv::Point2f point, const std::vector(y); - for(int x = 0; x < mat.cols; ++x) + for(int y = 0; y < mat.rows; y++) { - if(col[x] < 0 && col[x] > -2) + if(mat.at(y,x) < 0) { - if(y > 0 && mat.at(y-1,x) >= 0) + int closestA = -1; + int closestB = -1; + int dist = std::numeric_limits::max(); + for(int i = 0; i < mat.rows; i++) { - col[x] = mat.at(y-1,x); - finished = false; + if(i != closestA && mat.at(i,x) >= 0 && abs(i-y) <= dist) + { + closestB = closestA; + closestA = i; + dist = abs(i-y); + } } - else if(y < mat.rows-1 && mat.at(y+1,x) >= 0) + if(closestA < 0 || closestB < 0) { - col[x] = mat.at(y+1,x); - finished = false; + closestA = -1; + closestB = -1; + dist = std::numeric_limits::max(); + for(int i = mat.rows-1; i >= 0; --i) + { + if(i != closestA && mat.at(i,x) >= 0 && abs(i-y) <= dist) + { + closestB = closestA; + closestA = i; + dist = abs(i-y); + } + } } - if(col[x] > 0 && ((x+1 < mat.cols && col[x] > col[x+1]) || (x > 0 && col[x] < col[x-1]))) - col[x] = -2; + float slope = (mat.at(closestB,x) - mat.at(closestA,x))/(closestB-closestA); + mat.at(y,x) = mat.at(closestA,x) - (closestA-y)*slope; } } } - if(!finished) - fillMissing(mat); } bool findDeadSpace(const cv::Mat& mat, cv::Rect& roi) @@ -295,8 +308,8 @@ void removeSparseCols(cv::Mat& mat, float reject, bool front) int count = 0; for(int y = 0; y < mat.rows; ++y) { - if(front && mat.at(y,0) >= 0) ++count; - else if(mat.at(y,mat.cols-1) >= 0) ++count; + if((front && mat.at(y,0) >= 0) || (!front && mat.at(y,mat.cols-1) >= 0)) + ++count; } cv::Rect roi; bool rej = (count < mat.rows*reject); diff --git a/src/matutils.h b/src/matutils.h index 3d711e9..6020967 100644 --- a/src/matutils.h +++ b/src/matutils.h @@ -37,9 +37,9 @@ bool findClosest(size_t& index, const cv::Point2f point, const std::vector& in, std::vector& outliers, float criticalValue); -void interpolateMissing(cv::Mat& mat); +void interpolateMissingOnX(cv::Mat& mat); -void fillMissing(cv::Mat& mat); +void interpolateMissingOnY(cv::Mat& mat); bool findDeadSpace(const cv::Mat& mat, cv::Rect& roi); diff --git a/src/unwrap.cpp b/src/unwrap.cpp index 7414c96..d0bfac4 100644 --- a/src/unwrap.cpp +++ b/src/unwrap.cpp @@ -66,7 +66,7 @@ static void sortIntoRemapMaps(const std::vector& points, cv::Mat& xMat = -1; yMat = -1; - Log(Log::DEBUG)<<"Grid: "<& images) if(topLeft.y > image.origin.y) topLeft.y = image.origin.y; - Log(Log::DEBUG)<<"image: "<& images) cv::Mat stich(std::vector& images, bool seamAdjust) { + assert(images.size() > 0); + for(auto& image : images) assert(image.image.type() == CV_8UC3 || image.image.type() == CV_8UC1); + Log(Log::DEBUG)<<__func__<<" got "< Date: Tue, 20 Jul 2021 15:33:29 +0200 Subject: [PATCH 04/10] add support for kfactor --- src/main.cpp | 12 ++++++- src/unwrap.cpp | 70 +++++++++++++++++++++++++++++++++++++++-- src/uvosunwrap/unwrap.h | 4 +++ 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 23d6265..42b37c1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -211,7 +211,10 @@ int perfromOperation(int operation, char** fileNames, const Config& config) map.outputCellSize = config.size; if(!map.xMat.data) + { + Log(Log::ERROR)<<"could not load remap map from "<(y); + const float* anglex = angleMat.ptr(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& xStrech, cv::Mat& yStrech) +{ + xStrech.create(xMat.rows, xMat.cols-1, CV_32FC1); + yStrech.create(yMat.rows-1, xMat.cols, CV_32FC1); + for(int y = 0; y < xMat.rows; y++) + { + const float* colx = xMat.ptr(y); + float max = 0; + for(int x = 0; x < xMat.cols-1; x++) + { + float strech = std::abs(colx[x]-colx[x+1]); + if(strech > max) + max = strech; + } + if(y == 0) + Log(Log::DEBUG)<<"AngleX on x"; + for(int x = 0; x < xMat.cols-1; x++) + { + xStrech.at(y,x) = 1-std::abs(colx[x]-colx[x+1])/max; + if(y == 0) + Log(Log::DEBUG)<(y,x); + } + } + + for(int x = 0; x < yMat.cols; x++) + { + float max = 0; + for(int y = 0; y < yMat.rows-1; y++) + { + float strech = yMat.at(y,x) - yMat.at(y+1,x); + if(strech > max) + max = strech; + } + for(int y = 0; y < yMat.rows-1; y++) + yStrech.at(y,x) = 1-std::abs(yMat.at(y,x) - yMat.at(y+1,x))/max; + } +} + RemapedImage applyRemap(const cv::Mat& image, const RemapMap &map) { RemapedImage out; cv::Mat xMapResized; cv::Mat yMapResized; 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.angleX, out.angleY); + cv::Mat angleXResized; + cv::Mat angleYResized; + cv::resize(out.angleX, angleXResized, outputSize, cv::INTER_LINEAR); + cv::resize(out.angleY, angleYResized, outputSize, cv::INTER_LINEAR); + out.angleX = angleXResized(noBorderRoi); + out.angleY = angleYResized(noBorderRoi); cv::resize(map.xMat, xMapResized, 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 yMapRed = yMapResized(noBorderRoi); cv::remap(image, out.image, xMapRed, yMapRed, cv::INTER_LINEAR); diff --git a/src/uvosunwrap/unwrap.h b/src/uvosunwrap/unwrap.h index 0bcc383..3ad470f 100644 --- a/src/uvosunwrap/unwrap.h +++ b/src/uvosunwrap/unwrap.h @@ -25,6 +25,8 @@ struct RemapedImage { cv::Mat image; + cv::Mat angleX; + cv::Mat angleY; cv::Point2i origin; }; @@ -44,5 +46,7 @@ bool createRemapMap(const cv::Mat& image, RemapMap& out, const std::vector& images, bool seamAdjust = false); cv::Mat simpleStich(const std::vector& images); From b5107bfc5a1a372421603e7efb8f029f6bdb5a38 Mon Sep 17 00:00:00 2001 From: uvos Date: Tue, 20 Jul 2021 23:19:22 +0200 Subject: [PATCH 05/10] improve kfactor support --- src/argpopt.h | 7 ++++- src/main.cpp | 12 ++++---- src/unwrap.cpp | 63 ++++++++++++++++++++--------------------- src/uvosunwrap/unwrap.h | 3 +- 4 files changed, 45 insertions(+), 40 deletions(-) diff --git a/src/argpopt.h b/src/argpopt.h index 7bee75a..7a1828e 100644 --- a/src/argpopt.h +++ b/src/argpopt.h @@ -35,6 +35,7 @@ struct Config bool quiet = false; bool interactive = false; bool simpleStich = false; + float kFactor = 0; }; const char *argp_program_version = "0.2"; @@ -56,6 +57,7 @@ static struct argp_option options[] = {"interactive", 'i', 0, 0, "interactivly process multiple commands" }, {"simpe-stich", 'a', 0, 0, "Use non blending sticher" }, {"curve", 'c', "File Name", 0, "curve file name" }, +{"kfactor", 'k', "Value", 0, "set the kfactor" }, { 0 } }; @@ -78,7 +80,7 @@ error_t parse_opt (int key, char *arg, struct argp_state *state) config->norm.assign(arg); break; case 's': - config->minSize=atol(arg); + config->minSize=strtod(arg, nullptr); break; case 'r': config->harris = true; @@ -98,6 +100,9 @@ error_t parse_opt (int key, char *arg, struct argp_state *state) case 'c': config->curve.assign(arg); break; + case 'k': + config->kFactor=strtod(arg, nullptr); + break; case ARGP_KEY_ARG: config->commandsFiles = &state->argv[state->next-1]; state->next = state->argc; diff --git a/src/main.cpp b/src/main.cpp index 42b37c1..8f8c5a1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -242,12 +242,14 @@ int perfromOperation(int operation, char** fileNames, const Config& config) { cv::imshow( "Viewer", remaped.image ); cv::waitKey(0); - cv::imshow( "Viewer", remaped.angleX); + cv::imshow( "Viewer", remaped.angle); cv::waitKey(0); - cv::imshow( "Viewer", remaped.angleY); - cv::waitKey(0); - applyKfactor(remaped.image, remaped.angleX, 3); - cv::imshow( "remaped.image", remaped.image ); + } + + applyKfactor(remaped.image, remaped.angle, config.kFactor); + if(config.verbose) + { + cv::imshow("Viewer", remaped.image ); cv::waitKey(0); } diff --git a/src/unwrap.cpp b/src/unwrap.cpp index 79abb46..3b7b113 100644 --- a/src/unwrap.cpp +++ b/src/unwrap.cpp @@ -176,41 +176,43 @@ void applyKfactor(cv::Mat& image, const cv::Mat& angleMat, float kFactor) } } -static void generateAngleMats(const cv::Mat& xMat, const cv::Mat& yMat, cv::Mat& xStrech, cv::Mat& yStrech) +static void generateAngleMats(const cv::Mat& xMat, const cv::Mat& yMat, cv::Mat& greatestAngle) { - xStrech.create(xMat.rows, xMat.cols-1, CV_32FC1); - yStrech.create(yMat.rows-1, xMat.cols, CV_32FC1); - for(int y = 0; y < xMat.rows; y++) + std::cout<(y); - float max = 0; for(int x = 0; x < xMat.cols-1; x++) { - float strech = std::abs(colx[x]-colx[x+1]); - if(strech > max) - max = strech; - } - if(y == 0) - Log(Log::DEBUG)<<"AngleX on x"; - for(int x = 0; x < xMat.cols-1; x++) - { - xStrech.at(y,x) = 1-std::abs(colx[x]-colx[x+1])/max; - if(y == 0) - Log(Log::DEBUG)<(y,x); + cv::Point2f pA(xMat.at(y,x), yMat.at(y,x)); + cv::Point2f pB(xMat.at(y,x+1), yMat.at(y,x+1)); + cv::Point2f pC(xMat.at(y+1,x), yMat.at(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 x = 0; x < yMat.cols; x++) + for(int y = 0; y < xMat.rows-1; y++) { - float max = 0; - for(int y = 0; y < yMat.rows-1; y++) + for(int x = 0; x < xMat.cols-1; x++) { - float strech = yMat.at(y,x) - yMat.at(y+1,x); - if(strech > max) - max = strech; + cv::Point2f pA(xMat.at(y,x), yMat.at(y,x)); + cv::Point2f pB(xMat.at(y,x+1), yMat.at(y,x+1)); + cv::Point2f pC(xMat.at(y+1,x), yMat.at(y+1,x)); + double normX = cv::norm(pA-pB); + double normY = cv::norm(pA-pC); + + greatestAngle.at(y,x) = 1-(std::min(normX, normY)/max); + + if(y == 0) + Log(Log::DEBUG)<(y,x); } - for(int y = 0; y < yMat.rows-1; y++) - yStrech.at(y,x) = 1-std::abs(yMat.at(y,x) - yMat.at(y+1,x))/max; } } @@ -223,13 +225,10 @@ RemapedImage applyRemap(const cv::Mat& image, const RemapMap &map) cv::Rect noBorderRoi(map.outputCellSize/2, map.outputCellSize/2, outputSize.width-map.outputCellSize, outputSize.height-map.outputCellSize); - generateAngleMats(map.xMat, map.yMat, out.angleX, out.angleY); - cv::Mat angleXResized; - cv::Mat angleYResized; - cv::resize(out.angleX, angleXResized, outputSize, cv::INTER_LINEAR); - cv::resize(out.angleY, angleYResized, outputSize, cv::INTER_LINEAR); - out.angleX = angleXResized(noBorderRoi); - out.angleY = angleYResized(noBorderRoi); + 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.yMat, yMapResized, outputSize, cv::INTER_LINEAR); diff --git a/src/uvosunwrap/unwrap.h b/src/uvosunwrap/unwrap.h index 3ad470f..185abbf 100644 --- a/src/uvosunwrap/unwrap.h +++ b/src/uvosunwrap/unwrap.h @@ -25,8 +25,7 @@ struct RemapedImage { cv::Mat image; - cv::Mat angleX; - cv::Mat angleY; + cv::Mat angle; cv::Point2i origin; }; From 55ef1ee471f2e6865882f2e06df8bdc5bdd64882 Mon Sep 17 00:00:00 2001 From: uvos Date: Sat, 24 Jul 2021 12:27:05 +0200 Subject: [PATCH 06/10] fix curve loading --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 8f8c5a1..74fec1a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -282,7 +282,7 @@ int perfromOperation(int operation, char** fileNames, const Config& config) cv::FileStorage fs(config.curve, cv::FileStorage::READ); cv::Mat curve; - fs["curve"]>>curve; + fs["cal"]>>curve; if(!curve.data || curve.type() != CV_32FC1 || curve.rows != 2 || curve.cols < 3) { Log(Log::INFO)<<"invalid curve"; From 7682906fb862b290806e80321e91d9bfc37a74ad Mon Sep 17 00:00:00 2001 From: uvos Date: Sat, 24 Jul 2021 12:30:00 +0200 Subject: [PATCH 07/10] fix curve application --- src/main.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 74fec1a..b1aeb6c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -289,9 +289,12 @@ int perfromOperation(int operation, char** fileNames, const Config& config) return -1; } - cvtColor(inImages[0], inImages[0], cv::COLOR_BGR2GRAY); + if(inImages[0].channels() > 1) + cvtColor(inImages[0], inImages[0], cv::COLOR_BGR2GRAY); + if(inImages[0].type() != CV_32FC1) inImages[0].convertTo(inImages[0], CV_32F); + Log(Log::DEBUG)<<"applyCurve"; applyCurve(inImages[0], curve); } else if(operation == CREATE_CURVE) From 83223788da39a257ba308b7dd68f6737265fd462 Mon Sep 17 00:00:00 2001 From: uvos Date: Mon, 26 Jul 2021 10:34:47 +0200 Subject: [PATCH 08/10] save curve result as yaml image --- src/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index b1aeb6c..562dfbe 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -296,6 +296,9 @@ int perfromOperation(int operation, char** fileNames, const Config& config) Log(Log::DEBUG)<<"applyCurve"; applyCurve(inImages[0], curve); + cv::FileStorage fsO("out.mat", cv::FileStorage::WRITE); + fsO<<"image"< Date: Mon, 23 Aug 2021 19:17:48 +0200 Subject: [PATCH 09/10] Renove black regidon when a board less than the board size is used (Experiamental) --- src/charuco.cpp | 8 ++++++-- src/main.cpp | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/charuco.cpp b/src/charuco.cpp index 8628e0e..c6138f1 100644 --- a/src/charuco.cpp +++ b/src/charuco.cpp @@ -55,11 +55,14 @@ static void seamAjust(std::vector& detections) 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; @@ -79,12 +82,13 @@ static void seamAjust(std::vector& detections) } } - Log(Log::DEBUG)<<"Left coordinate before seam "<>image; - if(matf.isOpened() && (!image.data || image.type() != CV_32FC1)) + if(matf.isOpened() && !image.data) { Log(Log::WARN)< Date: Mon, 23 Aug 2021 22:12:07 +0200 Subject: [PATCH 10/10] fix small mistake --- src/charuco.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/charuco.cpp b/src/charuco.cpp index c6138f1..cd58672 100644 --- a/src/charuco.cpp +++ b/src/charuco.cpp @@ -88,7 +88,7 @@ static void seamAjust(std::vector& detections) for(auto& point : detections) { if(point.coordinate.x < leftCoordinate) - point.coordinate.x = point.coordinate.x + point.coordinate.x; + point.coordinate.x = point.coordinate.x + rightMostPoint + 1; } }