diff --git a/apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/specular_estimation.cc.o b/apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/specular_estimation.cc.o index 219505ab1ce78f01cbbc44762d6040461a33a6fc..1271b541311c20f58f61c6862a9e4ccf72092dfd 100644 Binary files a/apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/specular_estimation.cc.o and b/apps/specular_estimation/CMakeFiles/specular_estimation.dir/src/specular_estimation.cc.o differ diff --git a/apps/specular_estimation/src/OpenCV.h b/apps/specular_estimation/src/OpenCV.h index 4534a3d9611ae83321da73d64b748a27c298be2a..7c90b0f8502783a91c9b35ddf8461a78ec97d123 100644 --- a/apps/specular_estimation/src/OpenCV.h +++ b/apps/specular_estimation/src/OpenCV.h @@ -26,6 +26,7 @@ void displayTexture(cv::Mat texture, std::string modelPath, bool saveTexture); void displayNormalMap(cv::Mat normals, std::string modelPath, bool saveNormalMap); void displayHeightMap(cv::Mat Z, std::string modelPath, bool saveHeightMap); cv::Mat scaleImageIntensity(cv::Mat image); +void loadSurfaceNormals(cv::Mat lightDirections, int width, int height, int imageScale, std::string modelPath, cv::Mat& normals, cv::Mat& Z, std::vector< cv::Mat > modelImages); void photometricStereo(std::string imageName, std::string calibration, std::string modelPath, int imageScale, int cropping, bool showTexture, cv::Mat& Z, cv::Mat& normals, cv::Mat& texture, cv::Mat& lightDirections, cv::Mat& lightDirectionsPerspective, std::vector< cv::Mat > & textureImages, std::vector< cv::Mat > & modelImages, std::vector< cv::Mat > calibrationImages, cv::Rect calibrationBoundingBox, int& width, int& height, std::vector< cv::Vec3d > rvecs, std::vector< cv::Vec3d > tvecs) { @@ -44,6 +45,53 @@ void photometricStereo(std::string imageName, std::string calibration, std::stri texture = createTexture(modelPath, imageScale, textureImages, width, height); + //loadSurfaceNormals(lightDirections, width, height, imageScale, modelPath, normals, Z, modelImages); + + normals = cv::Mat(height, width, CV_32FC3, cv::Scalar(0,0,1)); + Z = cv::Mat(height, width, CV_32FC2, cv::Scalar::all(0)); + + cv::GaussianBlur(Z, Z, cv::Size(3, 3), 0, 0); + //cv::resize(Z, Z, cv::Size(), 0.5, 0.5, cv::INTER_LINEAR); + //cv::resize(Z, Z, cv::Size(), 2, 2, cv::INTER_LINEAR); + + //flip(Z, Z, 0); + + // Show the mesh, texture, normal map and height map. + // Setting the last argument to true writes these images to the image folder. + // displayTexture needs to be executed before displayMesh if there is not already a texture file. + //displayTexture(texture, modelPath, showTexture); + //displayNormalMap(normals, modelPath, true); + //displayHeightMap(Z, modelPath, true); + //displayMesh(width, height, -Z, lightDirections, imageName, modelPath, texturePath, true, showTexture); + + // Wait for a keystroke before closing the window + //cv::waitKey(0); +} + +void loadImages(std::string imageName, std::string calibration, int& width, int& height, int imageScale, std::vector< cv::Mat > & textureImages, std::string calibrationPath, std::vector< cv::Mat > & calibrationImages, std::string modelPath, std::vector< cv::Mat > & modelImages, cv::Rect & calibrationBoundingBox) { + + // Obtain the height and width of the images prior to resizing + int originalHeight; + int originalWidth; + + cv::Mat calibrationMask = loadCalibrationMask(calibrationPath, originalHeight, originalWidth); + //cv::Mat modelMask = loadModelMask(modelPath, imageScale, originalHeight, originalWidth); + + // Obtain the height and width of the images + height = calibrationMask.rows / imageScale; + width = calibrationMask.cols / imageScale; + + // Obtain the bounding box that contains the chrome sphere. Removing unnecessary space reduces the computation required to determine the incident light direction in each image + calibrationBoundingBox = getBoundingBox(calibrationMask); + + //cropImages(modelBoundingBox, modelMask, croppedHeight, croppedWidth, cropping, modelPath, imageScale); + + //loadImages(calibrationImages, modelImages, textureImages, calibrationPath, modelPath, imageScale, modelMask, modelBoundingBox, originalWidth, originalHeight, width, height, croppedWidth, croppedHeight); + loadCalibrationImages(calibrationImages, calibrationPath, originalWidth, originalHeight); + loadModelImages(modelImages, textureImages, modelPath, imageScale, originalWidth, originalHeight, width, height); +} + +void loadSurfaceNormals(cv::Mat lightDirections, int width, int height, int imageScale, std::string modelPath, cv::Mat& normals, cv::Mat& Z, std::vector< cv::Mat > modelImages) { // Create Mats to store the light directions, surface normals, and p, q gradients cv::Mat lightDirectionsInverted; cv::invert(lightDirections, lightDirectionsInverted, cv::DECOMP_SVD); @@ -67,7 +115,8 @@ void photometricStereo(std::string imageName, std::string calibration, std::stri std::string scale = stm.str(); std::string normalMapName = modelPath + "normalMap" + scale + ".yml"; - std::string globalHeightsName = modelPath + "globalHeights" + scale + ".yml"; + std::string pGradientsName = modelPath + "pGradients" + scale + ".yml"; + std::string qGradientsName = modelPath + "qGradients" + scale + ".yml"; cv::FileStorage storageRead; @@ -75,42 +124,49 @@ void photometricStereo(std::string imageName, std::string calibration, std::stri storageRead["normals"] >> normals; storageRead.release(); /* - storageRead.open(globalHeightsName, cv::FileStorage::READ); - storageRead["globalHeights"] >> globalHeights; + storageRead.open(pGradientsName, cv::FileStorage::READ); + storageRead["pGradients"] >> Z.at<cv::Vec2f>[0]; storageRead.release(); - */ + storageRead.open(qGradientsName, cv::FileStorage::READ); + storageRead["qGradients"] >> Z.at<cv::Vec2f>[1]; + storageRead.release(); + */ cv::FileStorage storageWrite; - if (!normals.data) { - storageWrite.open(normalMapName, cv::FileStorage::WRITE); - + if (!normals.data) { normals = cv::Mat(height, width, CV_32FC3, cv::Scalar::all(0)); // Estimate the surface normals and p, q gradients getSurfaceNormals(normals, pGradients, qGradients, lightDirectionsInverted, modelImages); std::cout << "Surface normals have been estimated.\n\n"; + storageWrite.open(normalMapName, cv::FileStorage::WRITE); storageWrite << "normals" << normals; storageWrite.release(); } /* if (!Z.data) { - storageWrite.open(globalHeightsName, cv::FileStorage::WRITE); - Z = cv::Mat(height, width, CV_32FC2, cv::Scalar::all(0)); // global integration of surface normals Z = globalHeights(pGradients, qGradients); std::cout << "Height map has been created.\n\n"; - storageWrite << "globalHeights" << Z; + storageWrite.open(pGradientsName, cv::FileStorage::WRITE); + storageWrite << "pGradients" << Z.at<cv::Vec2f>[0]; + storageWrite.release(); + + storageWrite.open(qGradientsName, cv::FileStorage::WRITE); + storageWrite << "qGradients" << Z.at<cv::Vec2f>[1]; storageWrite.release(); } */ + Z = cv::Mat(height, width, CV_32FC2, cv::Scalar::all(0)); // global integration of surface normals Z = globalHeights(pGradients, qGradients); std::cout << "Height map has been created.\n\n"; - + + /* normals = cv::imread(modelPath + "normalMap" + scale + ".png"); @@ -124,9 +180,6 @@ void photometricStereo(std::string imageName, std::string calibration, std::stri cv::imwrite(modelPath + "normalMap" + scale + ".png", normals); } - - cv::FileStorage file("globalHeights" + scale + ".xml", cv::FileStorage::WRITE); - Z = cv::imread(modelPath + "globalHeights" + scale + ".png"); if (!Z.data) { @@ -139,45 +192,6 @@ void photometricStereo(std::string imageName, std::string calibration, std::stri cv::imwrite(modelPath + "globalHeights" + scale + ".png", Z); } */ - cv::GaussianBlur(Z, Z, cv::Size(3, 3), 0, 0); - //cv::resize(Z, Z, cv::Size(), 0.5, 0.5, cv::INTER_LINEAR); - //cv::resize(Z, Z, cv::Size(), 2, 2, cv::INTER_LINEAR); - - //flip(Z, Z, 0); - - // Show the mesh, texture, normal map and height map. - // Setting the last argument to true writes these images to the image folder. - // displayTexture needs to be executed before displayMesh if there is not already a texture file. - //displayTexture(texture, modelPath, showTexture); - //displayNormalMap(normals, modelPath, true); - //displayHeightMap(Z, modelPath, true); - //displayMesh(width, height, -Z, lightDirections, imageName, modelPath, texturePath, true, showTexture); - - // Wait for a keystroke before closing the window - //cv::waitKey(0); -} - -void loadImages(std::string imageName, std::string calibration, int& width, int& height, int imageScale, std::vector< cv::Mat > & textureImages, std::string calibrationPath, std::vector< cv::Mat > & calibrationImages, std::string modelPath, std::vector< cv::Mat > & modelImages, cv::Rect & calibrationBoundingBox) { - - // Obtain the height and width of the images prior to resizing - int originalHeight; - int originalWidth; - - cv::Mat calibrationMask = loadCalibrationMask(calibrationPath, originalHeight, originalWidth); - //cv::Mat modelMask = loadModelMask(modelPath, imageScale, originalHeight, originalWidth); - - // Obtain the height and width of the images - height = calibrationMask.rows / imageScale; - width = calibrationMask.cols / imageScale; - - // Obtain the bounding box that contains the chrome sphere. Removing unnecessary space reduces the computation required to determine the incident light direction in each image - calibrationBoundingBox = getBoundingBox(calibrationMask); - - //cropImages(modelBoundingBox, modelMask, croppedHeight, croppedWidth, cropping, modelPath, imageScale); - - //loadImages(calibrationImages, modelImages, textureImages, calibrationPath, modelPath, imageScale, modelMask, modelBoundingBox, originalWidth, originalHeight, width, height, croppedWidth, croppedHeight); - loadCalibrationImages(calibrationImages, calibrationPath, originalWidth, originalHeight); - loadModelImages(modelImages, textureImages, modelPath, imageScale, originalWidth, originalHeight, width, height); } // Return an image comprised of the median intensities diff --git a/bin/specular_estimation b/bin/specular_estimation index 980789a48a5aa611d99b2b3aac9006fd506f5bc4..31576dcf5d950b2f11c22dbea51204b7969e0313 100755 Binary files a/bin/specular_estimation and b/bin/specular_estimation differ