Skip to content
Snippets Groups Projects
Commit 24a65039 authored by tw00275's avatar tw00275
Browse files

Chrome sphere and Macbeth images are loaded

parent 91139ecf
No related branches found
No related tags found
No related merge requests found
Showing
with 500 additions and 32 deletions
......@@ -3,7 +3,10 @@
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**"
"${workspaceFolder}/**",
"/usr/include",
"/usr/local/include",
"/usr/include/eigen3"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
......
{
"files.associations": {
"memory": "cpp",
"array": "cpp",
"string_view": "cpp",
"iosfwd": "cpp",
"deque": "cpp",
"vector": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"complex": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"list": "cpp",
"unordered_map": "cpp",
"exception": "cpp",
"fstream": "cpp",
"functional": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numeric": "cpp",
"optional": "cpp",
"ostream": "cpp",
"ratio": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"system_error": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"type_traits": "cpp",
"tuple": "cpp",
"typeinfo": "cpp",
"utility": "cpp"
},
"C_Cpp.errorSquiggles": "Disabled"
}
\ No newline at end of file
......@@ -111,6 +111,18 @@ cstdio
-
Eigen/SparseCholesky
-
opencv2/opencv.hpp
-
opencv2/core.hpp
-
opencv2/highgui.hpp
-
opencv2/imgproc.hpp
-
opencv2/tracking.hpp
-
opencv2/calib3d.hpp
-
/home/thomas/Documents/Minimisation/apps/specular_estimation/src/PhotometricStereo.h
string
......
......@@ -186,6 +186,7 @@ apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStere
/usr/include/eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h
/usr/include/eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h
/usr/include/eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h
/usr/local/include/opencv/cxcore.h
/usr/local/include/opencv2/calib3d.hpp
/usr/local/include/opencv2/core.hpp
/usr/local/include/opencv2/core/affine.hpp
......@@ -193,6 +194,7 @@ apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStere
/usr/local/include/opencv2/core/bufferpool.hpp
/usr/local/include/opencv2/core/check.hpp
/usr/local/include/opencv2/core/core.hpp
/usr/local/include/opencv2/core/core_c.h
/usr/local/include/opencv2/core/cuda.hpp
/usr/local/include/opencv2/core/cuda.inl.hpp
/usr/local/include/opencv2/core/cuda_types.hpp
......@@ -215,6 +217,7 @@ apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStere
/usr/local/include/opencv2/core/saturate.hpp
/usr/local/include/opencv2/core/traits.hpp
/usr/local/include/opencv2/core/types.hpp
/usr/local/include/opencv2/core/types_c.h
/usr/local/include/opencv2/core/utility.hpp
/usr/local/include/opencv2/core/version.hpp
/usr/local/include/opencv2/core/vsx_utils.hpp
......@@ -261,6 +264,7 @@ apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStere
/usr/local/include/opencv2/imgcodecs.hpp
/usr/local/include/opencv2/imgproc.hpp
/usr/local/include/opencv2/imgproc/imgproc.hpp
/usr/local/include/opencv2/imgproc/types_c.h
/usr/local/include/opencv2/ml.hpp
/usr/local/include/opencv2/ml/ml.inl.hpp
/usr/local/include/opencv2/objdetect.hpp
......@@ -287,6 +291,12 @@ apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStere
/usr/local/include/opencv2/stitching/warpers.hpp
/usr/local/include/opencv2/superres.hpp
/usr/local/include/opencv2/superres/optical_flow.hpp
/usr/local/include/opencv2/tracking.hpp
/usr/local/include/opencv2/tracking/feature.hpp
/usr/local/include/opencv2/tracking/onlineBoosting.hpp
/usr/local/include/opencv2/tracking/onlineMIL.hpp
/usr/local/include/opencv2/tracking/tldDataset.hpp
/usr/local/include/opencv2/tracking/tracker.hpp
/usr/local/include/opencv2/video.hpp
/usr/local/include/opencv2/video/background_segm.hpp
/usr/local/include/opencv2/video/tracking.hpp
......
......@@ -185,6 +185,7 @@ apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStere
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/include/eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/include/eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/include/eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv/cxcore.h
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/calib3d.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/affine.hpp
......@@ -192,6 +193,7 @@ apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStere
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/bufferpool.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/check.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/core.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/core_c.h
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/cuda.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/cuda.inl.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/cuda_types.hpp
......@@ -214,6 +216,7 @@ apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStere
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/saturate.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/traits.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/types.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/types_c.h
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/utility.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/version.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/core/vsx_utils.hpp
......@@ -260,6 +263,7 @@ apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStere
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/imgcodecs.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/imgproc.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/imgproc/imgproc.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/imgproc/types_c.h
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/ml.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/ml/ml.inl.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/objdetect.hpp
......@@ -286,6 +290,12 @@ apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStere
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/stitching/warpers.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/superres.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/superres/optical_flow.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/tracking.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/tracking/feature.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/tracking/onlineBoosting.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/tracking/onlineMIL.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/tracking/tldDataset.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/tracking/tracker.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/video.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/video/background_segm.hpp
apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/PhotometricStereo.cc.o: /usr/local/include/opencv2/video/tracking.hpp
......
No preview for this file type
No preview for this file type
......@@ -322,7 +322,7 @@ cv::Rect getBoundingBox(cv::Mat Mask) {
}
// Estimate the surface normals and p, q gradients
void getSurfaceNormals(cv::Mat& normals, cv::Mat& pGradients, cv::Mat& qGradients, cv::Mat lightDirectionsInverted, std::vector< cv::Mat > modelImages) {
void getSurfaceNormals(cv::Mat& normals, cv::Mat& pGradients, cv::Mat& qGradients, cv::Mat lightDirectionsInverted, std::vector<cv::Mat> modelImages) {
std::cout << "\nEstimating Surface Normals.\n";
......@@ -570,7 +570,7 @@ void loadModelImages(std::vector<cv::Mat>& modelImages, std::vector<cv::Mat>& te
std::cout << std::endl;
}
cv::Mat getLightDirections(std::vector< cv::Mat > calibrationImages, cv::Rect calibrationBoundingBox) {
cv::Mat getLightDirections(std::vector<cv::Mat> calibrationImages, cv::Rect calibrationBoundingBox) {
cv::Mat lightDirections(int(calibrationImages.size()), 3, CV_32F);
......
......@@ -7,6 +7,14 @@
#include <cstdio>
#include <Eigen/SparseCholesky>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp> // Core contains the definitions of the basic building blocks of the OpenCV library
#include <opencv2/highgui.hpp> // HighGUI contains the functions for input and output operations
#include <opencv2/imgproc.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/calib3d.hpp>
using namespace cv;
namespace phoSte {
namespace {
......@@ -99,11 +107,41 @@ phoSte::light getLightDirection(const phoSte::circle& metalCircle,
return phoSte::light(lx, ly, lz);
}
cv::Vec3f getLightDirectionFromSphere(cv::Mat Image, cv::Rect boundingBox) {
const int THRESH = 254;
const float radius = boundingBox.width / 2.0f;
cv::Mat Binary;
threshold(Image, Binary, THRESH, 255, CV_THRESH_BINARY);
cv::Mat SubImage(Binary, boundingBox);
// calculate center of pixels
cv::Moments m = moments(SubImage, false);
cv::Point center(int(m.m10 / m.m00), int(m.m01 / m.m00));
// x,y are swapped here // TODO check if necessary
float x = (center.y - radius) / radius;
float y = (center.x - radius) / radius;
float z = sqrt(1.0f - pow(x, 2.0f) - pow(y, 2.0f));
return cv::Vec3f(x, y, z);
}
phoSte::light getLightDirection(cv::Mat calibrationImage, cv::Rect calibrationBoundingBox) {
cv::Vec3f light = getLightDirectionFromSphere(calibrationImage, calibrationBoundingBox);
double lx = light[0];
double ly = light[1];
double lz = light[2];
return phoSte::light(lx, ly, lz);
}
void swapNum(double& a, double& b) {
double tmp = a;
a = b;
b = tmp;
}
// find the num at the ratio of the nums
......@@ -149,6 +187,7 @@ photometryStero::~photometryStero() {
}
}
// Read in the file names for the images
photometryStero::photometryStero(int n, int startI, int endI, std::string path,
std::string metal1Phere1Name, std::string metal2Phere1Name,
std::string lambertPhereName, std::string objectName,
......@@ -172,6 +211,87 @@ photometryStero::photometryStero(int n, int startI, int endI, std::string path,
mMaskNames.push_back(path + objectName);
}
photometryStero::photometryStero(int imageNumber, std::string modelPath, std::string calibrationPath, std::string macbethPath, std::string imageName, std::string calibration, double discardRatio): mDiscardRatio(discardRatio), imageNum(imageNumber) {
bool loadedImages = false;
imageNumber = 0;
// Load all of the model images
while (!loadedImages) {
// The index of the loop is converted into a stringstream, then to the string called "indexString"
// Using 'to_string' directly gives the error "'to_string' is not a member of 'std'"
std::ostringstream stm;
stm << imageNumber;
std::string indexString = stm.str();
std::string imageNameStr = modelPath + indexString + ".png";
cv::Mat modelImage = cv::imread(modelPath + indexString + ".png", cv::IMREAD_COLOR);
if (!modelImage.data) { // Check if any images failed to load
std::cout << imageNumber << " model images have been loaded." << std::endl;
loadedImages = true;
}
else {
mImageNames.push_back(imageNameStr);
imageNumber++;
}
}
loadedImages = false;
imageNumber = 0;
// Load all of the calibration images
while (!loadedImages) {
// The index of the loop is converted into a stringstream, then to the string called "indexString"
// Using 'to_string' directly gives the error "'to_string' is not a member of 'std'"
std::ostringstream stm;
stm << imageNumber;
std::string indexString = stm.str();
std::string calibrationNameStr = calibrationPath + indexString + ".png";
cv::Mat calibrationImage = cv::imread(calibrationPath + indexString + ".png", cv::IMREAD_COLOR);
if (!calibrationImage.data) { // Check if any images failed to load
std::cout << imageNumber << " calibration images have been loaded." << std::endl;
loadedImages = true;
}
else {
mCalibrationNames.push_back(calibrationNameStr);
imageNumber++;
}
}
std::string maskName = calibrationPath + "mask.png";
mMaskNames.push_back(maskName);
loadedImages = false;
imageNumber = 0;
// Load all of the calibration images
while (!loadedImages) {
// The index of the loop is converted into a stringstream, then to the string called "indexString"
// Using 'to_string' directly gives the error "'to_string' is not a member of 'std'"
std::ostringstream stm;
stm << imageNumber;
std::string indexString = stm.str();
std::string macbethNameStr = macbethPath + indexString + ".png";
cv::Mat macbethImage = cv::imread(macbethPath + indexString + ".png", cv::IMREAD_COLOR);
if (!macbethImage.data) { // Check if any images failed to load
std::cout << imageNumber << " Macbeth images have been loaded." << std::endl;
loadedImages = true;
}
else {
mMacbethNames.push_back(macbethNameStr);
imageNumber++;
}
}
}
// read image and mask image according to the name
// return true if read successfully
// return false if read fail
......@@ -195,6 +315,12 @@ bool photometryStero::readImage() {
+ 0.1140 * image.col(2));
p2Image = p2Image.reshape(0, PFMAccessI->GetHeight());
mp2Images.push_back(p2Image);
/*std::ostringstream stm;
stm << i;
std::string number = stm.str();
std::string path = "/home/thomas/Documents/Photometric-Stereo/Assignment_1/Apple/" + number + ".png";
cv::imwrite(path, p2Image);*/
}
// read the maskImage
for(int i = 0; i < mMaskNames.size(); i++) {
......@@ -206,6 +332,53 @@ bool photometryStero::readImage() {
return true;
}
bool photometryStero::readImage(std::string modelPath, std::string calibrationPath, std::string macbethPath) {
if(mImageNames.empty() || mMaskNames.empty() || mCalibrationNames.empty() || mMacbethNames.empty())
return false;
// read the image
for(int i = 0; i < mImageNames.size(); i++) {
std::ostringstream stm;
stm << i;
std::string indexString = stm.str();
cv::Mat modelImage = cv::imread(modelPath + indexString + ".png", cv::IMREAD_COLOR);
mp2Images.push_back(modelImage);
}
// read the calibration image
for(int i = 0; i < mCalibrationNames.size(); i++) {
std::ostringstream stm;
stm << i;
std::string indexString = stm.str();
cv::Mat calibrationImage = cv::imread(calibrationPath + indexString + ".png", cv::IMREAD_COLOR);
mp2CalibrationImages.push_back(calibrationImage);
}
// read the macbeth image
for(int i = 0; i < mMacbethNames.size(); i++) {
std::ostringstream stm;
stm << i;
std::string indexString = stm.str();
cv::Mat macbethImage = cv::imread(macbethPath + indexString + ".png", cv::IMREAD_COLOR);
mp2MacbethImages.push_back(macbethImage);
}
// read the maskImage
//for(int i = 0; i < mMaskNames.size(); i++) {
// cv::Mat p2Mask = cv::imread(calibrationPath + "mask.png", cv::IMREAD_GRAYSCALE);
// if(! p2Mask.data )
// return false;
// mp2Mask.push_back(p2Mask);
//}
cv::Mat p2Mask = cv::imread(calibrationPath + "mask.png", cv::IMREAD_GRAYSCALE);
if(! p2Mask.data )
return false;
mp2Mask.push_back(p2Mask);
return true;
}
void photometryStero::getLightInformation(const int metalIndex, const int lambIndex) {
// get the metal circle
cv::threshold(mp2Mask[metalIndex], mp2Mask[metalIndex], 255 / 2, 255, cv::THRESH_BINARY);
......@@ -235,7 +408,7 @@ void photometryStero::getLightInformation(const int metalIndex, const int lambIn
mostPointIdx = i;
}
}
m_lambSpere = getCircle(lambContour[mostPointIdx]);
//m_lambSpere = getCircle(lambContour[mostPointIdx]);
// get the direction and the intensity of every image
for(int i = 0; i < mp2Images.size(); i++) {
......@@ -248,11 +421,47 @@ void photometryStero::getLightInformation(const int metalIndex, const int lambIn
}
}
void photometryStero::getLightInformation(const int metalIndex, const int lambIndex, cv::Rect boundingBox) {
m_metalSphere = phoSte::circle(boundingBox.x + (boundingBox.width/2), boundingBox.y + (boundingBox.height/2), boundingBox.width);
for(int i = 0; i < mp2Images.size(); i++) {
cv::Point metalMaxPoint;
cv::minMaxLoc(mp2Images[i], NULL, NULL, NULL, &metalMaxPoint, mp2Mask[metalIndex]);
m_light.push_back(getLightDirection(m_metalSphere, metalMaxPoint));
/*
const int THRESH = 254;
const float radius = boundingBox.width / 2.0f;
cv::Mat Binary;
threshold(mp2Images[i], Binary, THRESH, 255, CV_THRESH_BINARY);
cv::Mat SubImage(Binary, boundingBox);
// calculate center of pixels
cv::Moments m = moments(SubImage, false);
cv::Point center(int(m.m10 / m.m00), int(m.m01 / m.m00));
// x,y are swapped here // TODO check if necessary
float x = (center.y - radius) / radius;
float y = (center.x - radius) / radius;
float z = sqrt(1.0f - pow(x, 2.0f) - pow(y, 2.0f));
m_light.push_back(phoSte::light(x, y, z));
*/
double lightIntensity;
cv::minMaxLoc(mp2Images[i], NULL, &lightIntensity, NULL, NULL, mp2Mask[lambIndex]);
m_light[i].mIntensity = lightIntensity;
}
}
// calculate the norm and albedo for every pixel
// here, threshold is for the dark discard
void photometryStero::getPixelNormAndAlbedo(const int objectIndex) {
// calculate the pixel num
std::vector<double> pixelThreshold;
//std::vector<double> pixelThreshold;
for(int i = 0; i < mp2Mask[objectIndex].rows; i++) {
for(int j = 0; j < mp2Mask[objectIndex].cols; j++) {
if(mp2Mask[objectIndex].at<unsigned char>(i, j) >= 255) {
......@@ -261,6 +470,9 @@ void photometryStero::getPixelNormAndAlbedo(const int objectIndex) {
}
}
}
std::cout << "Calculated the pixel coordinates within the mask\n";
std::vector<std::vector<double>> allPixelValue;
allPixelValue.reserve(imageNum);
int objectPixelNum = mObjectX.size();
......
......@@ -44,15 +44,16 @@ struct light {
class photometryStero {
public:
// fill the imageNames and maskNames
// use image with euqal distance
photometryStero(int n, int startI, int endI, std::string path,
std::string metal1Phere1Name, std::string metal2Phere1Name,
std::string lambertPhereName, std::string objectName, double discardRatio = 0.1);
// use image with equal distance
photometryStero(int n, int startI, int endI, std::string path, std::string metal1Phere1Name, std::string metal2Phere1Name, std::string lambertPhereName, std::string objectName, double discardRatio = 0.1);
photometryStero(int imageNumber, std::string modelPath, std::string calibrationPath, std::string macbethPath, std::string imageName, std::string calibration, double discardRatio = 0.1);
photometryStero(const photometryStero&) = delete;
photometryStero& operator = (const photometryStero&) = delete;
~photometryStero();
bool readImage(); // read the images and masks according to the ImageNames
bool readImage(std::string modelPath, std::string calibrationPath, std::string macbethPath);
void getLightInformation(const int metalIndex, const int lambIndex);
void getLightInformation(const int metalIndex, const int lambIndex, cv::Rect boundingBox);
void getPixelNormAndAlbedo(const int objectIndex);
cv::Mat outputNormalImage(int objectIndex);
cv::Mat outputAlbedoImage(int objectIndex);
......@@ -65,16 +66,20 @@ class photometryStero {
void addSmallMaskForObject(int size, int midX, int midY);
private:
const int imageNum; // the num of images used to calculate;
std::vector<std::string> mImageNames; // the name of images
std::vector<std::string> mMaskNames; // the name of mask
std::vector<std::string> mImageNames; // the file names of the model images
std::vector<std::string> mMaskNames; // the file name of the mask image
std::vector<std::string> mCalibrationNames; // the file names of the chrome sphere images
std::vector<std::string> mMacbethNames; // the file names of the Macbeth images
std::vector<cv::Mat> mp2Images;
std::vector<cv::Mat> mp2CalibrationImages;
std::vector<cv::Mat> mp2MacbethImages;
std::vector<cv::Mat> mp2Mask;
// when the PFMACCess destructs, the data will be destroyed
// so it's very dangerous, it should not be copied
std::vector<CPFMAccess*> mImageStorage;
// tht circle data for the metalSphere
phoSte::circle m_metalSphere;
phoSte::circle m_lambSpere;
//phoSte::circle m_lambSpere;
std::vector<phoSte::light> m_light;
cv::Mat mN;
cv::Mat mAlbedo;
......@@ -82,6 +87,11 @@ class photometryStero {
std::vector<int> mObjectY;
std::vector<int> mInvalidIndex;
const double mDiscardRatio;
std::string modelPath;
std::string calibrationPath;
std::string imageName;
std::string calibration;
};
}
......
......@@ -43,13 +43,6 @@ int main(int argc, char** argv) {
std::cout << std::endl;
drawAppleNormal();
drawAppleAlbedo();
drawAppleNormalWithAlbedo();
getAppleHeight();
// Define the paths for the model images, calibration images and the albedo texture
//const std::string sourcePath = "/user/HS222/tw00275/PhD/Minimisation/apps/specular_estimation/src/";
//const std::string imagesPath = "/media/tw00275/ESD-USB/";
......@@ -58,20 +51,21 @@ int main(int argc, char** argv) {
const std::string folderPath = "2017-12-04";
const std::string modelPath = imagesPath + folderPath + "/" + imageName + "/" + imageName + ".";
const std::string calibrationPath = imagesPath + folderPath + "/" + calibration + "/" + calibration + ".";
const std::string macbethPath = imagesPath + folderPath + "/macbeth/macbeth.";
const std::string texturePath = modelPath + "texture.png";
detectMacbeth("/home/thomas/Documents/2017-12-04/macbeth/macbeth.0.png");
//detectMacbeth("/home/thomas/Documents/2017-12-04/macbeth/macbeth.0.png");
// A vector of Mats allow multiple images to be allocated to the same object
// textureImages are the full colour photographs that are used to create the texture
// modelImages are the greyscale version of textureImages which are used to calculate the surface normals
// calibrationImages contain the reflections of the chrome sphere, and are used to determine the light directions
// charucoImages contain the ChArUco board, and are used to calibrate the camera
std::vector< cv::Mat > textureImages, modelImages, calibrationImages, charucoImages;
std::vector<cv::Mat> textureImages, modelImages, calibrationImages, charucoImages;
cv::Mat heightMap, normalMap, texture, lightDirections;
cv::Rect calibrationBoundingBox;
int width, height;
/*
// Load the textureImages, modelImages, calibrationImages and charucoImages, then determine the bounding box around the chrome sphere
loadImages(imageName, calibration, width, height, imageScale, textureImages, calibrationPath, calibrationImages, modelPath, modelImages, calibrationBoundingBox);
......@@ -80,7 +74,7 @@ int main(int argc, char** argv) {
// The rotation matrix is created from the rotation and translation vectors, and describes the rotation of the ChArUco board
// The inverse of this transformation is applied to the light directions
// The perspective transform warps the model images to align them with the ChArUco board
std::vector< cv::Vec3d > rvecs, tvecs;
std::vector<cv::Vec3d> rvecs, tvecs;
cv::Mat rotationMatrix, rotationVector, charucoBoardImage, cameraMatrix, distortionCoefficients, perspectiveTransform, lightDirectionsPerspective = cv::Mat(numberOfLights, 3, CV_32F);
cv::Ptr<cv::aruco::CharucoBoard> charucoBoard;
......@@ -88,16 +82,180 @@ int main(int argc, char** argv) {
//charucoAlignment(charucoImages, textureImages, numberOfLights, width, height, rotationMatrix, rotationVector, perspectiveTransform, lightDirections, lightDirectionsPerspective, rvecs, tvecs, charucoBoard, charucoBoardImage, cameraMatrix, distortionCoefficients);
//rotationMatrix =
//rotationVector =
//perspectiveTransform =
//lightDirectionsPerspective =
//std::vector<cv::Vec3d>& rvecs
//std::vector<cv::Vec3d>& tvecs
photometricStereo(imageName, calibration, modelPath, imageScale, heightMap, normalMap, texture, lightDirections, lightDirectionsPerspective, textureImages, modelImages, calibrationImages, calibrationBoundingBox, width, height, rvecs, tvecs);
*/
//phoSte::photometryStero B(21, 2, 22, "/home/thomas/Documents/Photometric-Stereo/Assignment_1/Apple/", "mask_dir_1.png", "mask_dir_2.png", "mask_I.png", "applemask.png");
//B.readImage();
phoSte::photometryStero A(0, modelPath, calibrationPath, macbethPath, imageName, calibration, 0.1);
A.readImage(modelPath, calibrationPath, macbethPath);
cv::Mat calibrationMask = loadCalibrationMask(calibrationPath, height, width);
calibrationBoundingBox = getBoundingBox(calibrationMask);
A.getLightInformation(1, 2, calibrationBoundingBox);
std::cout << "Got light information\n";
A.getPixelNormAndAlbedo(3);
std::cout << "Got Normal and Albedo\n";
cv::Mat result = A.outputNormalImage(3);
cv::imshow("apple normal image", result);
cv::imwrite(modelPath + "normal", result);
cv::waitKey(0);
int numberOfLights = 6;
/*
int imageNum = numberOfLights;
int objectPixelNum = width;
std::vector<phoSte::light> m_light;
for (int i = 0; i < numberOfLights; i++) {
m_light.push_back(phoSte::light(lightDirections.at<float>(i, 0), lightDirections.at<float>(i, 1), lightDirections.at<float>(i, 2)));
}
cv::Mat I(imageNum, objectPixelNum, CV_64F);
cv::Mat L(imageNum, 3, CV_64F);
cv::Mat mN(3, objectPixelNum, CV_64F);
cv::Mat mAlbedo(1, objectPixelNum, CV_64F);
double *pL = (double *)L.data;
for(int i = 0; i < imageNum; i++) {
*pL = m_light[i].mx;
*(pL + 1) = m_light[i].my;
*(pL + 2) = m_light[i].mz;
pL += 3;
}
cv::Mat LPseudoInvert;
cv::invert(L, LPseudoInvert, cv::DECOMP_SVD);
double *pI = (double *)I.data;
double *pN = (double *)mN.data;
for(int i = 0; i < objectPixelNum; i++) {
int inValidNum = 0;
cv::Mat specificL;
for(int j = 0; j < imageNum; j++) {
//if(allPixelValue[j][i] < allThreshold[j]) {
inValidNum ++;
if(inValidNum == 1) {
L.copyTo(specificL);
}
double *p2LRow = specificL.ptr<double>(j);
*(p2LRow) = 0;
*(p2LRow + 1) = 0;
*(p2LRow + 2) = 0;
*(pI + j * objectPixelNum + i) = 0;
} else {
*(pI + j * objectPixelNum + i) = allPixelValue[j][i] / m_light[j].mIntensity;
}
if(imageNum - inValidNum < 3) {
break;
}
}
if(inValidNum == 0) {
mN.col(i) = LPseudoInvert * I.col(i);
double nx = mN.col(i).at<double>(0, 0);
double ny = mN.col(i).at<double>(1, 0);
double nz = mN.col(i).at<double>(2, 0);
mAlbedo.at<double>(0, i) = sqrt(nx * nx + ny * ny + nz * nz);
} else if(imageNum - inValidNum >= 3) {
cv::Mat specificLPseudoInvert;
cv::invert(specificL, specificLPseudoInvert, cv::DECOMP_SVD);
mN.col(i) = specificLPseudoInvert * I.col(i);
double nx = mN.col(i).at<double>(0, 0);
double ny = mN.col(i).at<double>(1, 0);
double nz = mN.col(i).at<double>(2, 0);
mAlbedo.at<double>(0, i) = sqrt(nx * nx + ny * ny + nz * nz);
} else {
mN.at<double>(0, i) = 0;
mN.at<double>(1, i) = 0;
mN.at<double>(2, i) = 0;
mAlbedo.at<double>(0, i) = 0;
//mInvalidIndex.push_back(i);
}
}
//cv::Mat normal = A.outputNormalImage(3);
cv::Mat normal = cv::Mat::zeros(height, width, CV_32FC3);
//int nextInvalid = mInvalidIndex.empty() ? INT_MAX : mInvalidIndex[0];
int nextInvalidIndex = 0;
int invalidPixelNum = 0;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
double nx = mN.at<double>(0, i);
double ny = mN.at<double>(1, i);
double nz = mN.at<double>(2, i);
if (i == nextInvalid) {
invalidPixelNum++;
normal.at<cv::Vec3f>(j, i)[0] = 0;
normal.at<cv::Vec3f>(j, i)[1] = 0;
normal.at<cv::Vec3f>(j, i)[2] = 0;
if (nextInvalidIndex + 1 == mInvalidIndex.size()) {
nextInvalid = INT_MAX;
} else {
nextInvalidIndex++;
nextInvalid = mInvalidIndex[nextInvalidIndex];
}
} else {
double rootsquareSum = sqrt(nx * nx + ny * ny + nz * nz);
float nxf = (1 + nx / rootsquareSum) / 2;
float nyf = (1 + ny / rootsquareSum) / 2;
float nzf = (1 + nz / rootsquareSum) / 2;
normal.at<cv::Vec3f>(j, i)[0] = nxf;
normal.at<cv::Vec3f>(j, i)[1] = nyf;
normal.at<cv::Vec3f>(j, i)[2] = nzf;
//}
}
}
cv::imshow("Surface Normals", normal);
//cv::imwrite("/home/thomas/Documents/Photometric-Stereo/Assignment_1/Apple/normal.jpg", normal);
cv::waitKey(0);*/
/*
rotationMatrix =
rotationVector =
perspectiveTransform =
lightDirectionsPerspective =
std::vector< cv::Vec3d > & rvecs
std::vector< cv::Vec3d > & tvecs
cv::Mat albedo = A.outputAlbedoImage(3);
cv::imshow("Albedo", albedo);
cv::waitKey(0);
cv::Mat normalWithAlbedo = A.outputNormalWithAlbedo(3);
cv::imshow("Albedo with Surface Normals", normalWithAlbedo);
cv::waitKey(0);
cv::Mat heights = A.getHeightMap(2, -0.1);
//std::string fileName = "appleDepth.png";
//cv::imwrite(path + fileName, heightMap);
cv::imshow("Height Map", heights);
cv::waitKey(0);
*/
/*phoSte::photometryStero A(21, 2, 22, "/home/thomas/Documents/Photometric-Stereo/Assignment_1/Apple/", "mask_dir_1.png", "mask_dir_2.png", "mask_I.png", "applemask.png");
A.readImage();
A.getLightInformation(1, 2);
A.getPixelNormAndAlbedo(3);
cv::Mat normal = A.outputNormalImage(3);
cv::imshow("Surface Normals", normal);
//cv::imwrite("/home/thomas/Documents/Photometric-Stereo/Assignment_1/Apple/normal.jpg", normal);
cv::waitKey(0);
cv::Mat albedo = A.outputAlbedoImage(3);
cv::imshow("Albedo", albedo);
cv::waitKey(0);
cv::Mat normalWithAlbedo = A.outputNormalWithAlbedo(3);
cv::imshow("Albedo with Surface Normals", normalWithAlbedo);
cv::waitKey(0);
cv::Mat heights = A.getHeightMap(2, -0.1);
//std::string fileName = "appleDepth.png";
//cv::imwrite(path + fileName, heightMap);
cv::imshow("Height Map", heights);
cv::waitKey(0);
*/
photometricStereo(imageName, calibration, modelPath, imageScale, heightMap, normalMap, texture, lightDirections, lightDirectionsPerspective, textureImages, modelImages, calibrationImages, calibrationBoundingBox, width, height, rvecs, tvecs);
glm::vec3 position, lightInvDir;
glm::mat4 depthProjectionMatrix, depthViewMatrix, depthModelMatrix = glm::mat4(1.0), depthMVP, ModelMatrix = glm::mat4(1.0), MVP, ViewMatrix, depthBiasMVP, ProjectionMatrix;
......@@ -114,7 +272,7 @@ int main(int argc, char** argv) {
std::vector<cv::Vec3d> residuals;
int lightNumber = 0;
bool calculateResidual = false, perspectiveProjection, shadowControl;
double totalResidual, residualValue, SpecularIntensity = 0.5d, SpecularPower = 2.0d;
double totalResidual, residualValue, SpecularIntensity = 0.5, SpecularPower = 2.0;
cv::Mat residualImage;
std::vector<glm::vec3> lightInvDirs;
......
No preview for this file type
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment