From ba64a25d987f380c1a2fce21cf28254e426bf2cb Mon Sep 17 00:00:00 2001 From: youssef Shaban <85808789+youssef-shaban@users.noreply.github.com> Date: Wed, 3 May 2023 22:58:36 +0300 Subject: [PATCH] adding BGR2LUV --- CV/segmentation.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++ CV/segmentation.h | 1 + CV/thresholding.cpp | 5 ++-- a01-team06.pro | 14 ++++----- utilities/scene.cpp | 2 +- 5 files changed, 81 insertions(+), 10 deletions(-) diff --git a/CV/segmentation.cpp b/CV/segmentation.cpp index f681b9a..77627ec 100644 --- a/CV/segmentation.cpp +++ b/CV/segmentation.cpp @@ -551,3 +551,72 @@ void Segmentation::regionGrowing(cv::Mat inputImage, cv::Mat& outputImage, std:: } outputImage = inputImage; } + +void Segmentation::bgr_to_luv(cv::Mat& img_bgr, cv::Mat& output) { + + + // Split channels + std::vector bgr; + cv::split(img_bgr, bgr); + + const double ref_X = 0.95047; + const double ref_Y = 1.0; + const double ref_Z = 1.08883; + + // Convert BGR to XYZ + cv::Mat XYZ(img_bgr.size(), CV_64FC3); + for (int i = 0; i < img_bgr.rows; i++) { + for (int j = 0; j < img_bgr.cols; j++) { + double B = bgr[0].at(i, j) / 255.0; + double G = bgr[1].at(i, j) / 255.0; + double R = bgr[2].at(i, j) / 255.0; + + double X = 0.412453 * R + 0.357580 * G + 0.180423 * B; + double Y = 0.212671 * R + 0.715160 * G + 0.072169 * B; + double Z = 0.019334 * R + 0.119193 * G + 0.950227 * B; + + XYZ.at(i, j) = cv::Vec3d(X, Y, Z); + } + } + + // Convert XYZ to LUV + cv::Mat img_luv = cv::Mat(img_bgr.size(), CV_64FC3); + for (int i = 0; i < XYZ.rows; i++) { + for (int j = 0; j < XYZ.cols; j++) { + double X = XYZ.at(i, j)[0]; + double Y = XYZ.at(i, j)[1]; + double Z = XYZ.at(i, j)[2]; + + double var_U = (4 * X) / (X + 15 * Y + 3 * Z); + double var_V = (9 * Y) / (X + 15 * Y + 3 * Z); + + double var_Y = Y / ref_Y; + if (var_Y > 0.008856) { + var_Y = std::pow(var_Y, 1.0 / 3.0); + } + else { + var_Y = (7.787 * var_Y) + (16.0 / 116.0); + } + + double ref_U = (4 * ref_X) / (ref_X + 15 * ref_Y + 3 * ref_Z); + double ref_V = (9 * ref_Y) / (ref_X + 15 * ref_Y + 3 * ref_Z); + + double L = (116 * var_Y) - 16; + double u = 13 * L * (var_U - ref_U); + double v = 13 * L * (var_V - ref_V); + + img_luv.at(i, j) = cv::Vec3d(L - 16, u, v); + } + } + + std::vector channels; + cv::split(img_luv, channels); + + + channels[0] = channels[0] * (255.0f / 100.0f); + channels[1] = (channels[1] + 134) * (255.0f / 354.0f); + channels[2] = (channels[2] + 140) * (255.0f / 262.0f); + cv::merge(channels, output); + + output.convertTo(output, CV_8UC3); +} diff --git a/CV/segmentation.h b/CV/segmentation.h index cee5fcf..70af6d8 100644 --- a/CV/segmentation.h +++ b/CV/segmentation.h @@ -25,5 +25,6 @@ class Segmentation static void closetClusters(std::vector clusters, std::vector& minDistances, std::mutex& myMutex, int start_i, int end_i); static double generateKClusters(cv::InputArray _data, int K, cv::InputOutputArray _bestLabels, cv::TermCriteria criteria, int attempts, cv::OutputArray _centers); static void createRegion(cv::Mat input, cv::Mat& output, std::vector> ®ions, std::vector seeds, int threshold); + static void bgr_to_luv(cv::Mat& img_bgr, cv::Mat& output); }; #endif // SEGMENTATION_H diff --git a/CV/thresholding.cpp b/CV/thresholding.cpp index b88e929..bfb7460 100644 --- a/CV/thresholding.cpp +++ b/CV/thresholding.cpp @@ -162,7 +162,7 @@ void Thresholding::localThreshold(cv::Mat& img, cv::Mat& output, int pieceSize) cv::Rect area(col, row, width, height); cv::Mat piece = img(area); cv::Mat outputPiece(piece.size(), piece.type()); - Thresholding::otsuThresholding(piece, outputPiece); + Thresholding::multiLevelOtsu(piece, outputPiece, 2); outputPiece.copyTo(output(area)); @@ -199,7 +199,8 @@ void Thresholding::multiLevelOtsu(cv::Mat img, cv::Mat& output, int M) } if (i == thresholds.size()) i--; - output.at(row, col) = thresholds[i - 1]; + + output.at(row, col) = 255 * (((double)i - 1) / (thresholds.size() - 1)); } } diff --git a/a01-team06.pro b/a01-team06.pro index 7d0e001..6da502f 100644 --- a/a01-team06.pro +++ b/a01-team06.pro @@ -78,14 +78,14 @@ FORMS += \ -INCLUDEPATH += C:\opencv\build\include +INCLUDEPATH += C:\Users\youss\Documents\libraries\opencv\build\include -LIBS += C:\opencv\release\bin\libopencv_core470.dll -LIBS += C:\opencv\release\bin\libopencv_highgui470.dll -LIBS += C:\opencv\release\bin\libopencv_imgcodecs470.dll -LIBS += C:\opencv\release\bin\libopencv_imgproc470.dll -LIBS += C:\opencv\release\bin\libopencv_features2d470.dll -LIBS += C:\opencv\release\bin\libopencv_calib3d470.dll +LIBS += C:\Users\youss\Documents\libraries\opencv\release\bin\libopencv_core470.dll +LIBS += C:\Users\youss\Documents\libraries\opencv\release\bin\libopencv_highgui470.dll +LIBS += C:\Users\youss\Documents\libraries\opencv\release\bin\libopencv_imgcodecs470.dll +LIBS += C:\Users\youss\Documents\libraries\opencv\release\bin\libopencv_imgproc470.dll +LIBS += C:\Users\youss\Documents\libraries\opencv\release\bin\libopencv_features2d470.dll +LIBS += C:\Users\youss\Documents\libraries\opencv\release\bin\libopencv_calib3d470.dll # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin diff --git a/utilities/scene.cpp b/utilities/scene.cpp index bca39a4..2d0deec 100644 --- a/utilities/scene.cpp +++ b/utilities/scene.cpp @@ -44,7 +44,7 @@ void Scene::mousePressEvent(QGraphicsSceneMouseEvent *event) if(!this->drawFlag){ QPointF point = event->scenePos(); this->center= point; - this->drawFlag=true; + // this->drawFlag=true; drawCircle(); } }