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 47e7eca82e58fe36401b7f12dca217258b2eec99..5aa84aec02d0a140cbc82afd9f627b127ef2690b 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/specular_estimation.cc b/apps/specular_estimation/src/specular_estimation.cc index 96a57b33ab3b6ddfecc0202bb24621e69cc72b0a..c9b187a1d90f3822ec4236696014aabda3835e8c 100644 --- a/apps/specular_estimation/src/specular_estimation.cc +++ b/apps/specular_estimation/src/specular_estimation.cc @@ -1,6 +1,6 @@ #include "specular_estimation.h" -void specularEstimation(std::string imageName, std::string calibration, double Roughness, double Metallic); +void specularEstimation(std::string imageName, std::string calibration, double Roughness, double Metallic, double RoughnessSynthetic, double MetallicSynthetic, bool synthetic, bool denseSample); void renderSynthetic(std::string imageName, std::string calibration, double Roughness, double Metallic, double RoughnessSynthetic, double MetallicSynthetic); void denseRealSample(std::string imageName, std::string calibration, double Roughness, double Metallic); void denseSyntheticSample(std::string imageName, std::string calibration, double Roughness, double Metallic); @@ -133,21 +133,6 @@ void SpecularEstimation::DenseSample() { int main(int argc, char** argv) { - /*int windowWidth = 1092, windowHeight = 728; - cv::Mat black = cv::Mat(windowHeight, windowWidth, CV_8UC3, cv::Scalar::all(0)); - calibrateLights(windowWidth, windowHeight, black);*/ - - /*int windowWidth = 1092, windowHeight = 728; - cv::Mat image = cv::imread("/home/thomas/Documents/2018-09-05/uniformAlbedo/uniformAlbedo.albedo (another copy).png"); - for (double i = 0; i < 3; i += 0.1) { - for (double j = -100; j < 100; j+=10) { - cv::Mat textureImage = contrastBrightness(image, i, j); - cv::imshow("image", textureImage); - std::cout << "Gain: " << i << ", Bias: " << j << std::endl; - cv::waitKey(0); - } - }*/ - if (argc < 2) { std::cerr << "Enter the name of the object followed by the calibration set to use.\n"; return -1; @@ -159,71 +144,38 @@ int main(int argc, char** argv) { // Create strings to store the model folder name and calibration folder name // By default, the name of the chrome sphere calibration images folder is "chrome". This will be overwritten if a second argument is provided. std::string imageName, calibration = "chrome"; - // Using an image scale of 1 retains the full resolution - //int imageScale = 1; - // Show textue is set to false if cropping is used - //bool showTexture = true; // Read the name of the model folder if (argc >= 2) { // Read the file name from the command line argument and convert it from a char array to a string const char *argument1 = argv[1]; imageName = argument1; - } - /*if (argc >= 3) { // The specified calibration path will be used, otherwise "chrome" is used - const char *argument2 = argv[2]; - calibration = argument2; - }*/ - - /* - // Read the name of the calibration folder - - // Read the image scale - if (argc >= 4) { // An image scale is provided - // Scale down the images for faster processing and rendering - const char *argument3 = argv[3]; - std::stringstream stringValue; - stringValue << argument3; - stringValue >> imageScale; - if (imageScale > 1) - std::cout << "The images will be scaled to 1/" << imageScale << " of their original resolution in each axis." << std::endl; - else - imageScale = 1; - } - if ((argc < 2) || (argc > 4)) { - std::cerr << "Enter the name of the object followed by the calibration set to use.\n\nThe images can be scaled down by providing a number.\nFor instance, entering 2 will scale the x and y axes by 1/2." << std::endl; - return -1; } - std::cout << std::endl;*/ - - //specularEstimation(imageName, calibration, imageScale, showTexture); - - double Roughness = 0.5, Metallic = 0.5, Distance = 0.5, LightPower = 0.5; - bool denseSample = false; + double Roughness = 0.5, Metallic = 0.5, RoughnessSynthetic = 0.5, MetallicSynthetic = 0.5, Distance = 0.5, LightPower = 0.5; + bool synthetic = false, denseSample = false; if (argc >= 4) { const char *argument2 = argv[2], *argument3 = argv[3]; std::stringstream RoughnessValue, MetallicValue; RoughnessValue << argument2; - MetallicValue << argument3; + MetallicValue << argument3; RoughnessValue >> Roughness; - MetallicValue >> Metallic; + MetallicValue >> Metallic; - specularEstimation(imageName, calibration, Roughness, Metallic); + specularEstimation(imageName, calibration, Roughness, Metallic, RoughnessSynthetic, MetallicSynthetic, synthetic, denseSample); //denseSyntheticSample(imageName, calibration, Roughness, Metallic); //SpecularEstimation Solver(imageName, calibration, denseSample, Roughness, Metallic); } else if (argc >= 6) { - double RoughnessSynthetic, MetallicSynthetic; - const char *argument4 = argv[4], *argument5 = argv[5]; std::stringstream RoughnessSyntheticValue, MetallicSyntheticValue; RoughnessSyntheticValue << argument4; - MetallicSyntheticValue << argument5; + MetallicSyntheticValue << argument5; RoughnessSyntheticValue >> RoughnessSynthetic; - MetallicSyntheticValue >> MetallicSynthetic; + MetallicSyntheticValue >> MetallicSynthetic; - renderSynthetic(imageName, calibration, Roughness, Metallic, RoughnessSynthetic, MetallicSynthetic); + //renderSynthetic(imageName, calibration, Roughness, Metallic, RoughnessSynthetic, MetallicSynthetic); + specularEstimation(imageName, calibration, Roughness, Metallic, RoughnessSynthetic, MetallicSynthetic, synthetic, denseSample); //SpecularEstimation Solver(imageName, calibration, denseSample, Roughness, Metallic, RoughnessSynthetic, MetallicSynthetic); } else { //specularEstimation(imageName, calibration, Roughness, Metallic); @@ -231,30 +183,79 @@ int main(int argc, char** argv) { //SpecularEstimation Solver(imageName, calibration, denseSample, Roughness, Metallic); } - //denseSyntheticSample(imageName, calibration, Roughness, Metallic); - - return 0; } -void renderSynthetic(std::string imageName, std::string calibration, double Roughness, double Metallic, double RoughnessSynthetic, double MetallicSynthetic) { +void specularEstimation(std::string imageName, std::string calibration, double Roughness, double Metallic, double RoughnessSynthetic = 0.5, double MetallicSynthetic = 0.5, bool synthetic = false, bool denseSample = false) { - // Define the paths for the model images, calibration images and the albedo texture - //const std::string sourcePath = "/home/thomas/Documents/Minimisation/apps/specular_estimation/src/vboindexer.cpp"; + // Define the paths for the model images, calibration images and the albedo const std::string imagesPath = "/home/thomas/Documents/"; - const std::string folderPath = "2018-09-05"; - const std::string modelPath = imagesPath + folderPath + "/" + imageName + "/" + imageName + "."; + const std::string folderPath = "2018-08-31"; + const std::string modelPath = imagesPath + folderPath + "/" + imageName + "/" + imageName + "."; const std::string calibrationPath = imagesPath + folderPath + "/" + calibration + "/" + calibration + "."; - //const std::string calibrationPath = imagesPath + "2017-12-04" + "/" + calibration + "/" + calibration + "."; const std::string macbethPath = imagesPath + folderPath + "/macbeth/macbeth."; const std::string albedoPath = modelPath + "albedo.png"; const std::string normalPath = modelPath + "normal.png"; double Distance = 0.5, LightPower = 0.5; - - //const std::string calibrationPath2 = imagesPath + folderPath + "/" + calibration + "/" + calibration + "."; int numberOfLights = 6, width = 1092, height = 728; + cv::Mat residualImage, albedo, normalMap, heightMap; + std::vector<cv::Mat> textureImages; + + if (!synthetic) { + for (int i = 0; i < numberOfLights; i++) { + std::ostringstream stm; + stm << i; + std::string indexString = stm.str(); + + cv::Mat model = cv::imread(modelPath + indexString + ".png"); + textureImages.push_back(model); + } + + width = textureImages[0].cols; + height = textureImages[0].rows; + + // Load a premade dictionary of ArUco markers + int dictionaryId = 0; + cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + // Create a ChArUco board + int xSquares = 9; + int ySquares = 11; + float squareSideLength = 0.04f; + float markerSideLength = 0.02f; + cv::Ptr<cv::aruco::CharucoBoard> charucoBoard = cv::aruco::CharucoBoard::create(xSquares, ySquares, squareSideLength, markerSideLength, dictionary); + cv::Mat charucoBoardImage = drawCharuco(charucoBoard, height, ((height * xSquares) / ySquares), false, false); + cv::imwrite(imagesPath + "ChArUco board.png", charucoBoardImage); + + phoSte::photometryStero A(numberOfLights, modelPath, calibrationPath, macbethPath, imageName, calibration, 0); + A.readImage(modelPath, calibrationPath, macbethPath); + //cv::Mat calibrationMask = loadCalibrationMask(calibrationPath, height, width); + //calibrationBoundingBox = getBoundingBox(calibrationMask); + A.getLightInformation(0); + std::cout << "Got light information\n"; + A.getPixelNormAndAlbedo(1); + std::cout << "Got Normal and Albedo\n"; + + normalMap = A.outputNormalImage(1); + cv::imshow("Normal Map", normalMap); + albedo = A.outputAlbedoImage(1); + cv::imshow("Albedo", albedo); + cv::Mat normalAlbedo = A.outputNormalWithAlbedo(1); + cv::imshow("Normal with Albedo", normalAlbedo); + //cv::Mat heightMap = A.getHeightMap(2, -0.1); + //cv::imshow("Height Map", heightMap); + //cv::imwrite(modelPath + "normal", result); + heightMap = cv::Mat::zeros(albedo.size(), CV_8U); + //cv::waitKey(0); + + //normalMap.convertTo(normalMap, CV_8UC1); + //normalMap = convertImageToNormals(normalMap); + + cv::cvtColor(albedo, albedo, CV_GRAY2BGR); + albedo.convertTo(albedo, CV_8UC3); + } + glm::vec3 position, lightInvDir; glm::mat4 depthProjectionMatrix, depthViewMatrix, depthModelMatrix = glm::mat4(1.0), depthMVP, ModelMatrix = glm::mat4(1.0), MVP, ViewMatrix, depthBiasMVP, ProjectionMatrix; glm::mat4 biasMatrix( @@ -270,215 +271,95 @@ void renderSynthetic(std::string imageName, std::string calibration, double Roug int lightNumber = 0; bool calculateResidual = false, perspectiveProjection, shadowControl; double totalResidual, residualValue; - cv::Mat residualImage, albedo = cv::imread(albedoPath), normalMap = cv::imread(normalPath), heightMap = cv::Mat::zeros(albedo.size(), CV_8U); - std::vector<cv::Mat> textureImages; - normalMap = convertImageToNormals(normalMap); - normalMap.convertTo(normalMap, CV_32FC3); + if (synthetic) { + albedo = cv::imread(albedoPath), normalMap = cv::imread(normalPath), heightMap = cv::Mat::zeros(albedo.size(), CV_8U); + normalMap = convertImageToNormals(normalMap); + normalMap.convertTo(normalMap, CV_32FC3); + } + //cv::Mat lightDirectionsInverted; cv::Mat lightDirections = (cv::Mat_<float>(6,3) << 0.447712, 0.138562, 0.883377, 0.228758, -0.106536, 0.967636, 0.1, 0.0705882, 0.99248, 0.000653595, -0.0718954, 0.997412, -0.139216, -0.12549, 0.982279, -0.494771, 0.115033, 0.861376); - + //cv::invert(lightDirections, lightDirectionsInverted, cv::DECOMP_SVD); + + std::vector<glm::vec3> lightInvDirs; for (int i = 0; i < numberOfLights; i++) lightInvDirs.push_back(glm::vec3(lightDirections.at<float>(i, 0), -lightDirections.at<float>(i, 2), lightDirections.at<float>(i, 1))); - + lightInvDir = glm::vec3(lightDirections.at<float>(0, 0), -lightDirections.at<float>(0, 2), lightDirections.at<float>(0, 1)); - //lightInvDir = glm::vec3(0, 0, 1); initialiseOpenGL(heightMap, normalMap, albedo, lightDirections, width, height, depthProjectionMatrix, depthViewMatrix, position, horizontalAngle, verticalAngle, FoV, lightInvDir, programID, MatrixID, ModelMatrixID, ViewMatrixID, DepthBiasID, lightInvDirID, Texture, TextureID, depthTexture, ShadowMapID, vertexbuffer, uvbuffer, normalbuffer, elementbuffer, indices, depthProgramID, quad_programID, FramebufferName, quad_vertexbuffer, VertexArrayID, RoughnessID, Roughness, MetallicID, Metallic, DistanceID, Distance, LightPowerID, LightPower, numberOfLights, calculateResidual, depthMVP, depthModelMatrix, MVP, ProjectionMatrix, ViewMatrix, ModelMatrix, depthBiasMVP, biasMatrix); - RenderSynthetic(depthProjectionMatrix, depthViewMatrix, width, height, position, horizontalAngle, verticalAngle, FoV, lightInvDir, lightDirections, textureImages, numberOfLights, RoughnessID, RoughnessSynthetic, MetallicID, MetallicSynthetic, DistanceID, Distance, LightPowerID, LightPower, programID, ModelMatrixID, ViewMatrixID, DepthBiasID, lightInvDirID, Texture, TextureID, depthTexture, ShadowMapID, vertexbuffer, uvbuffer, normalbuffer, elementbuffer, indices, MatrixID, modelPath); - - //Roughness = 0.5, Metallic = 0.5; - double Gain = 0.5, Bias = 0.5; + if (synthetic) + RenderSynthetic(depthProjectionMatrix, depthViewMatrix, width, height, position, horizontalAngle, verticalAngle, FoV, lightInvDir, lightDirections, textureImages, numberOfLights, RoughnessID, RoughnessSynthetic, MetallicID, MetallicSynthetic, DistanceID, Distance, LightPowerID, LightPower, programID, ModelMatrixID, ViewMatrixID, DepthBiasID, lightInvDirID, Texture, TextureID, depthTexture, ShadowMapID, vertexbuffer, uvbuffer, normalbuffer, elementbuffer, indices, MatrixID, modelPath); - specularMinimisation(Roughness, Metallic, Gain, Bias, imageName, residualValue, residual, totalResidual, residualImage, depthProjectionMatrix, depthViewMatrix, width, height, numberOfLights, RoughnessID, MetallicID, DistanceID, LightPowerID, programID, ModelMatrixID, ViewMatrixID, DepthBiasID, lightInvDirID, Texture, TextureID, depthTexture, ShadowMapID, vertexbuffer, uvbuffer, normalbuffer, elementbuffer, indices, MatrixID, ModelMatrix, MVP, ViewMatrix, depthBiasMVP, lightInvDirs, textureImages); - - //viewModel(residual, totalResidual, residualImage, calculateResidual, depthProjectionMatrix, depthViewMatrix, width, height, position, horizontalAngle, verticalAngle, FoV, lightInvDir, lightDirections, textureImages, lightNumber, numberOfLights, RoughnessID, Roughness, MetallicID, Metallic, DistanceID, Distance, LightPowerID, LightPower, programID, ModelMatrixID, ViewMatrixID, DepthBiasID, lightInvDirID, Texture, TextureID, depthTexture, ShadowMapID, vertexbuffer, uvbuffer, normalbuffer, elementbuffer, indices, MatrixID, modelPath); - - terminateOpenGL(vertexbuffer, uvbuffer, normalbuffer, elementbuffer, programID, depthProgramID, quad_programID, Texture, FramebufferName, depthTexture, quad_vertexbuffer, VertexArrayID); - - return; -} - -void specularEstimation(std::string imageName, std::string calibration, double Roughness, double Metallic) { - - // 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/"; - //const std::string sourcePath = "/home/thomas/Documents/Minimisation/apps/specular_estimation/src/vboindexer.cpp"; - const std::string imagesPath = "/home/thomas/Documents/"; - const std::string folderPath = "2018-08-31"; - const std::string modelPath = imagesPath + folderPath + "/" + imageName + "/" + imageName + "."; - const std::string calibrationPath = imagesPath + folderPath + "/" + calibration + "/" + calibration + "."; - //const std::string calibrationPath = imagesPath + "2017-12-04" + "/" + calibration + "/" + calibration + "."; - const std::string macbethPath = imagesPath + folderPath + "/macbeth/macbeth."; - const std::string texturePath = modelPath + "texture.png"; - - double Distance = 0.5, LightPower = 0.5; - - /* - std::vector<double> macbethIntensity; + double Gain = 0.5, Bias = 0.5; - for (int i = 0; i < 6; i++) { - std::vector<CvScalar> macbethValues; + if (denseSample) { + std::string outputFileName = imageName + ".txt"; + std::ofstream outputFile(outputFileName, std::ios::app); - std::ostringstream stm; - stm << i; - std::string indexString = stm.str(); - - detectMacbeth(macbethPath + indexString + ".png", macbethValues); - double brightness = 0.2989 * macbethValues[18].val[2] + 0.5870 * macbethValues[18].val[1] + 0.1140 * macbethValues[18].val[0]; - macbethIntensity.push_back(brightness); - //std::cout << "Brightness of white Macbeth square: " << brightness << std::endl; - } - - // 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; - 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); - - // The number of lights is equal to the number of calibration images - int numberOfLights = int(calibrationImages.size()); - - // 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; - cv::Mat rotationMatrix, rotationVector, charucoBoardImage, cameraMatrix, distortionCoefficients, perspectiveTransform, lightDirectionsPerspective = cv::Mat(numberOfLights, 3, CV_32F); - cv::Ptr<cv::aruco::CharucoBoard> charucoBoard; - - charucoCalibration(width, height, charucoBoard, charucoBoardImage, cameraMatrix, distortionCoefficients, imagesPath, folderPath); - - //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 + for (double roughness = 0; roughness <= 1; roughness+=0.01){ + for (double metallic = 0; metallic <= 1; metallic+=0.01){ + double residualValue = 0, sum = 0, gain = 1.0, bias = 0.0; + + for(int i = 0; i < numberOfLights; i++) { - photometricStereo(imageName, calibration, modelPath, imageScale, heightMap, normalMap, texture, lightDirections, lightDirectionsPerspective, textureImages, modelImages, calibrationImages, calibrationBoundingBox, width, height, rvecs, tvecs); - */ + // Render the polygons + renderPolygons(width, height, programID, lightInvDirs[i], MatrixID, ModelMatrixID, ViewMatrixID, DepthBiasID, lightInvDirID, Texture, TextureID, depthTexture, ShadowMapID, vertexbuffer, uvbuffer, normalbuffer, elementbuffer, indices, MVP, ModelMatrix, ViewMatrix, depthBiasMVP, RoughnessID, roughness, MetallicID, metallic, DistanceID, Distance, LightPowerID, LightPower); + + cv::Mat model = readPixels(height, width); + cv::Mat photograph = textureImages[i]; - //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(); + model.convertTo(model, CV_64FC3, gain, bias); + photograph.convertTo(photograph, CV_64FC3); - //const std::string calibrationPath2 = imagesPath + folderPath + "/" + calibration + "/" + calibration + "."; - int numberOfLights = 6; - - std::vector<cv::Mat> textureImages; - for (int i = 0; i < numberOfLights; i++) { - std::ostringstream stm; - stm << i; - std::string indexString = stm.str(); + sum = meanSquaredError(model, photograph); + + // Swap buffers + glfwSwapBuffers(window); + glfwPollEvents(); + } + + residualValue = (sum/numberOfLights); + + //std::cout << "Specular Intensity = " << roughness_ << ", Specular Power = " << metallic_ << ", Residual = " << (sum/numberOfLights_) << ", SSD = " << (sum/numberOfLights_)*(sum/numberOfLights_) << std::endl; + //if (outputFile.is_open()) { + outputFile << roughness << "\t" << metallic << "\t" << residualValue << std::endl; + //outputFile.close(); + //} + } + std::cout << roughness*100 << "\%" << std::endl; + } - cv::Mat model = cv::imread(modelPath + indexString + ".png"); - textureImages.push_back(model); + outputFile.close(); } - int width = textureImages[0].cols; - int height = textureImages[0].rows; - - - - // Load a premade dictionary of ArUco markers - int dictionaryId = 0; - cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); - - // Create a ChArUco board - int xSquares = 9; - int ySquares = 11; - float squareSideLength = 0.04f; - float markerSideLength = 0.02f; - cv::Ptr<cv::aruco::CharucoBoard> charucoBoard = cv::aruco::CharucoBoard::create(xSquares, ySquares, squareSideLength, markerSideLength, dictionary); - - cv::Mat charucoBoardImage = drawCharuco(charucoBoard, height, ((height * xSquares) / ySquares), false, false); - - cv::imwrite(imagesPath + "ChArUco board.png", charucoBoardImage); - - - phoSte::photometryStero A(numberOfLights, modelPath, calibrationPath, macbethPath, imageName, calibration, 0); - A.readImage(modelPath, calibrationPath, macbethPath); - //cv::Mat calibrationMask = loadCalibrationMask(calibrationPath, height, width); - //calibrationBoundingBox = getBoundingBox(calibrationMask); - A.getLightInformation(0); - std::cout << "Got light information\n"; - A.getPixelNormAndAlbedo(1); - std::cout << "Got Normal and Albedo\n"; - - cv::Mat normalMap = A.outputNormalImage(1); - cv::imshow("Normal Map", normalMap); - cv::Mat texture = A.outputAlbedoImage(1); - cv::imshow("Albedo", texture); - cv::Mat normalAlbedo = A.outputNormalWithAlbedo(1); - cv::imshow("Normal with Albedo", normalAlbedo); - //cv::Mat heightMap = A.getHeightMap(2, -0.1); - //cv::imshow("Height Map", heightMap); - //cv::imwrite(modelPath + "normal", result); - cv::Mat heightMap = cv::Mat::zeros(texture.size(), CV_8U); - //cv::waitKey(0); - - //normalMap.convertTo(normalMap, CV_8UC1); - //normalMap = convertImageToNormals(normalMap); + if (!denseSample) + specularMinimisation(Roughness, Metallic, Gain, Bias, imageName, residualValue, residual, totalResidual, residualImage, depthProjectionMatrix, depthViewMatrix, width, height, numberOfLights, RoughnessID, MetallicID, DistanceID, LightPowerID, programID, ModelMatrixID, ViewMatrixID, DepthBiasID, lightInvDirID, Texture, TextureID, depthTexture, ShadowMapID, vertexbuffer, uvbuffer, normalbuffer, elementbuffer, indices, MatrixID, ModelMatrix, MVP, ViewMatrix, depthBiasMVP, lightInvDirs, textureImages); + //viewModel(residual, totalResidual, residualImage, calculateResidual, depthProjectionMatrix, depthViewMatrix, width, height, position, horizontalAngle, verticalAngle, FoV, lightInvDir, lightDirections, textureImages, lightNumber, numberOfLights, RoughnessID, Roughness, MetallicID, Metallic, DistanceID, Distance, LightPowerID, LightPower, programID, ModelMatrixID, ViewMatrixID, DepthBiasID, lightInvDirID, Texture, TextureID, depthTexture, ShadowMapID, vertexbuffer, uvbuffer, normalbuffer, elementbuffer, indices, MatrixID, modelPath); - cv::cvtColor(texture, texture, CV_GRAY2BGR); - texture.convertTo(texture, CV_8UC3); - - //texture.convertTo(texture, CV_GRAY2BGR); - //normalAlbedo.convertTo(normalAlbedo, CV_8UC3); - - //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))); - } - */ - /* - 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"); - std::cout << "1\n"; - B.readImage(); - std::cout << "2\n"; - B.getLightInformation(1, 2); - std::cout << "3\n"; - B.getPixelNormAndAlbedo(3); - std::cout << "4\n"; - cv::Mat applenormal = B.outputNormalImage(3); - cv::imshow("Surface Normals", applenormal); - //cv::imwrite("/home/thomas/Documents/Photometric-Stereo/Assignment_1/Apple/normal.jpg", normal); - //cv::waitKey(0); + terminateOpenGL(vertexbuffer, uvbuffer, normalbuffer, elementbuffer, programID, depthProgramID, quad_programID, Texture, FramebufferName, depthTexture, quad_vertexbuffer, VertexArrayID); - cv::Mat applealbedo = B.outputAlbedoImage(3); - cv::imshow("Albedo", applealbedo); - //cv::waitKey(0); + return; +} - cv::Mat applenormalWithAlbedo = B.outputNormalWithAlbedo(3); - cv::imshow("Albedo with Surface Normals", applenormalWithAlbedo); - //cv::waitKey(0); +void renderSynthetic(std::string imageName, std::string calibration, double Roughness, double Metallic, double RoughnessSynthetic, double MetallicSynthetic) { - cv::Mat appleheights = B.getHeightMap(2, -0.1); - //std::string fileName = "appleDepth.png"; - //cv::imwrite(path + fileName, heightMap); - cv::imshow("Height Map", appleheights); - cv::waitKey(0); - */ + // Define the paths for the model images, calibration images and the albedo + const std::string imagesPath = "/home/thomas/Documents/"; + const std::string folderPath = "2018-09-05"; + 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 albedoPath = modelPath + "albedo.png"; + const std::string normalPath = modelPath + "normal.png"; + double Distance = 0.5, LightPower = 0.5; + int numberOfLights = 6, width = 1092, height = 728; glm::vec3 position, lightInvDir; glm::mat4 depthProjectionMatrix, depthViewMatrix, depthModelMatrix = glm::mat4(1.0), depthMVP, ModelMatrix = glm::mat4(1.0), MVP, ViewMatrix, depthBiasMVP, ProjectionMatrix; @@ -495,27 +376,24 @@ void specularEstimation(std::string imageName, std::string calibration, double R int lightNumber = 0; bool calculateResidual = false, perspectiveProjection, shadowControl; double totalResidual, residualValue; - cv::Mat residualImage; - - //cv::Mat lightDirectionsInverted; - cv::Mat lightDirections = (cv::Mat_<float>(6,3) << 0.447712, 0.138562, 0.883377, 0.228758, -0.106536, 0.967636, 0.1, 0.0705882, 0.99248, 0.000653595, -0.0718954, 0.997412, -0.139216, -0.12549, 0.982279, -0.494771, 0.115033, 0.861376); - //cv::invert(lightDirections, lightDirectionsInverted, cv::DECOMP_SVD); + cv::Mat residualImage, albedo = cv::imread(albedoPath), normalMap = cv::imread(normalPath), heightMap = cv::Mat::zeros(albedo.size(), CV_8U); + std::vector<cv::Mat> textureImages; - /* - std::vector<glm::vec3> lightInvDirs; - lightInvDirs.push_back(glm::vec3(0.447712, 0.138562, 0.883377)); - lightInvDirs.push_back(glm::vec3(0.228758, -0.106536, 0.967636)); - lightInvDirs.push_back(glm::vec3(0.1, 0.0705882, 0.99248)); - lightInvDirs.push_back(glm::vec3(0.000653595, -0.0718954, 0.997412)); - lightInvDirs.push_back(glm::vec3(-0.139216, -0.12549, 0.982279)); - lightInvDirs.push_back(glm::vec3(-0.494771, 0.115033, 0.861376)); - */ + normalMap = convertImageToNormals(normalMap); + normalMap.convertTo(normalMap, CV_32FC3); + cv::Mat lightDirections = (cv::Mat_<float>(6,3) << 0.447712, 0.138562, 0.883377, 0.228758, -0.106536, 0.967636, 0.1, 0.0705882, 0.99248, 0.000653595, -0.0718954, 0.997412, -0.139216, -0.12549, 0.982279, -0.494771, 0.115033, 0.861376); + std::vector<glm::vec3> lightInvDirs; for (int i = 0; i < numberOfLights; i++) lightInvDirs.push_back(glm::vec3(lightDirections.at<float>(i, 0), -lightDirections.at<float>(i, 2), lightDirections.at<float>(i, 1))); + + lightInvDir = glm::vec3(lightDirections.at<float>(0, 0), -lightDirections.at<float>(0, 2), lightDirections.at<float>(0, 1)); + //lightInvDir = glm::vec3(0, 0, 1); + + initialiseOpenGL(heightMap, normalMap, albedo, lightDirections, width, height, depthProjectionMatrix, depthViewMatrix, position, horizontalAngle, verticalAngle, FoV, lightInvDir, programID, MatrixID, ModelMatrixID, ViewMatrixID, DepthBiasID, lightInvDirID, Texture, TextureID, depthTexture, ShadowMapID, vertexbuffer, uvbuffer, normalbuffer, elementbuffer, indices, depthProgramID, quad_programID, FramebufferName, quad_vertexbuffer, VertexArrayID, RoughnessID, Roughness, MetallicID, Metallic, DistanceID, Distance, LightPowerID, LightPower, numberOfLights, calculateResidual, depthMVP, depthModelMatrix, MVP, ProjectionMatrix, ViewMatrix, ModelMatrix, depthBiasMVP, biasMatrix); - initialiseOpenGL(heightMap, normalMap, texture, lightDirections, width, height, depthProjectionMatrix, depthViewMatrix, position, horizontalAngle, verticalAngle, FoV, lightInvDir, programID, MatrixID, ModelMatrixID, ViewMatrixID, DepthBiasID, lightInvDirID, Texture, TextureID, depthTexture, ShadowMapID, vertexbuffer, uvbuffer, normalbuffer, elementbuffer, indices, depthProgramID, quad_programID, FramebufferName, quad_vertexbuffer, VertexArrayID, RoughnessID, Roughness, MetallicID, Metallic, DistanceID, Distance, LightPowerID, LightPower, numberOfLights, calculateResidual, depthMVP, depthModelMatrix, MVP, ProjectionMatrix, ViewMatrix, ModelMatrix, depthBiasMVP, biasMatrix); + RenderSynthetic(depthProjectionMatrix, depthViewMatrix, width, height, position, horizontalAngle, verticalAngle, FoV, lightInvDir, lightDirections, textureImages, numberOfLights, RoughnessID, RoughnessSynthetic, MetallicID, MetallicSynthetic, DistanceID, Distance, LightPowerID, LightPower, programID, ModelMatrixID, ViewMatrixID, DepthBiasID, lightInvDirID, Texture, TextureID, depthTexture, ShadowMapID, vertexbuffer, uvbuffer, normalbuffer, elementbuffer, indices, MatrixID, modelPath); double Gain = 0.5, Bias = 0.5; @@ -525,42 +403,19 @@ void specularEstimation(std::string imageName, std::string calibration, double R terminateOpenGL(vertexbuffer, uvbuffer, normalbuffer, elementbuffer, programID, depthProgramID, quad_programID, Texture, FramebufferName, depthTexture, quad_vertexbuffer, VertexArrayID); - /* - // Initialise the values of specular intensity and power exponent - double Roughness = 0.5, Metallic = 0.5; - - // Convert lightDirections from a cv::Mat to a vector of glm::vec3 - std::vector<glm::vec3> lightInvDirVector; - for (int i = 0; i < numberOfLights; i++) - lightInvDirVector.push_back(glm::vec3(lightDirections.at<float>(i, 1), -lightDirections.at<float>(i, 0), lightDirections.at<float>(i, 2))); - - // Create the OpenGL object - OpenGL Renderer = OpenGL(heightMap, normalMap, texture, textureImages, width, height, modelPath, sourcePath); - - //Renderer.renderPolygons(Roughness, Metallic); - Renderer.computeResiduals(textureImages, numberOfLights, Roughness, Metallic, modelPath, lightDirections, lightInvDirVector); - */ - return; } void denseRealSample(std::string imageName, std::string calibration, double Roughness, double Metallic) { - // 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/"; - //const std::string sourcePath = "/home/thomas/Documents/Minimisation/apps/specular_estimation/src/vboindexer.cpp"; + // Define the paths for the model images, calibration images and the albedo const std::string imagesPath = "/home/thomas/Documents/"; const std::string folderPath = "2018-08-31"; const std::string modelPath = imagesPath + folderPath + "/" + imageName + "/" + imageName + "."; const std::string calibrationPath = imagesPath + folderPath + "/" + calibration + "/" + calibration + "."; - //const std::string calibrationPath = imagesPath + "2017-12-04" + "/" + calibration + "/" + calibration + "."; const std::string macbethPath = imagesPath + folderPath + "/macbeth/macbeth."; - const std::string texturePath = modelPath + "texture.png"; double Distance = 0.5, LightPower = 0.5; - - //const std::string calibrationPath2 = imagesPath + folderPath + "/" + calibration + "/" + calibration + "."; int numberOfLights = 6; std::vector<cv::Mat> textureImages; @@ -573,7 +428,7 @@ void denseRealSample(std::string imageName, std::string calibration, double Roug textureImages.push_back(model); } - int width = textureImages[0].cols; + int width = textureImages[0].cols; int height = textureImages[0].rows; phoSte::photometryStero A(numberOfLights, modelPath, calibrationPath, macbethPath, imageName, calibration, 0); @@ -587,20 +442,20 @@ void denseRealSample(std::string imageName, std::string calibration, double Roug cv::Mat normalMap = A.outputNormalImage(1); cv::imshow("Normal Map", normalMap); - cv::Mat texture = A.outputAlbedoImage(1); - cv::imshow("Albedo", texture); + cv::Mat albedo = A.outputAlbedoImage(1); + cv::imshow("Albedo", albedo); cv::Mat normalAlbedo = A.outputNormalWithAlbedo(1); cv::imshow("Normal with Albedo", normalAlbedo); //cv::Mat heightMap = A.getHeightMap(2, -0.1); //cv::imshow("Height Map", heightMap); //cv::imwrite(modelPath + "normal", result); - cv::Mat heightMap = cv::Mat::zeros(texture.size(), CV_8U); + cv::Mat heightMap = cv::Mat::zeros(albedo.size(), CV_8U); //cv::waitKey(0); - cv::cvtColor(texture, texture, CV_GRAY2BGR); - texture.convertTo(texture, CV_8UC3); + cv::cvtColor(albedo, albedo, CV_GRAY2BGR); + albedo.convertTo(albedo, CV_8UC3); glm::vec3 position, lightInvDir; @@ -628,7 +483,7 @@ void denseRealSample(std::string imageName, std::string calibration, double Roug for (int i = 0; i < numberOfLights; i++) lightInvDirs.push_back(glm::vec3(lightDirections.at<float>(i, 0), -lightDirections.at<float>(i, 2), lightDirections.at<float>(i, 1))); - initialiseOpenGL(heightMap, normalMap, texture, lightDirections, width, height, depthProjectionMatrix, depthViewMatrix, position, horizontalAngle, verticalAngle, FoV, lightInvDir, programID, MatrixID, ModelMatrixID, ViewMatrixID, DepthBiasID, lightInvDirID, Texture, TextureID, depthTexture, ShadowMapID, vertexbuffer, uvbuffer, normalbuffer, elementbuffer, indices, depthProgramID, quad_programID, FramebufferName, quad_vertexbuffer, VertexArrayID, RoughnessID, Roughness, MetallicID, Metallic, DistanceID, Distance, LightPowerID, LightPower, numberOfLights, calculateResidual, depthMVP, depthModelMatrix, MVP, ProjectionMatrix, ViewMatrix, ModelMatrix, depthBiasMVP, biasMatrix); + initialiseOpenGL(heightMap, normalMap, albedo, lightDirections, width, height, depthProjectionMatrix, depthViewMatrix, position, horizontalAngle, verticalAngle, FoV, lightInvDir, programID, MatrixID, ModelMatrixID, ViewMatrixID, DepthBiasID, lightInvDirID, Texture, TextureID, depthTexture, ShadowMapID, vertexbuffer, uvbuffer, normalbuffer, elementbuffer, indices, depthProgramID, quad_programID, FramebufferName, quad_vertexbuffer, VertexArrayID, RoughnessID, Roughness, MetallicID, Metallic, DistanceID, Distance, LightPowerID, LightPower, numberOfLights, calculateResidual, depthMVP, depthModelMatrix, MVP, ProjectionMatrix, ViewMatrix, ModelMatrix, depthBiasMVP, biasMatrix); std::string outputFileName = imageName + ".txt"; std::ofstream outputFile(outputFileName, std::ios::app); @@ -682,27 +537,18 @@ void denseRealSample(std::string imageName, std::string calibration, double Roug void denseSyntheticSample(std::string imageName, std::string calibration, double Roughness, double Metallic) { - // 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/"; - //const std::string sourcePath = "/home/thomas/Documents/Minimisation/apps/specular_estimation/src/vboindexer.cpp"; + // Define the paths for the model images, calibration images and the albedo const std::string imagesPath = "/home/thomas/Documents/"; const std::string folderPath = "2018-09-05"; const std::string modelPath = imagesPath + folderPath + "/" + imageName + "/" + imageName + "."; const std::string calibrationPath = imagesPath + folderPath + "/" + calibration + "/" + calibration + "."; - //const std::string calibrationPath = imagesPath + "2017-12-04" + "/" + calibration + "/" + calibration + "."; const std::string macbethPath = imagesPath + folderPath + "/macbeth/macbeth."; - const std::string texturePath = modelPath + "texture.png"; const std::string albedoPath = modelPath + "albedo.png"; const std::string normalPath = modelPath + "normal.png"; double Distance = 0.5, LightPower = 0.5; - - //const std::string calibrationPath2 = imagesPath + folderPath + "/" + calibration + "/" + calibration + "."; int numberOfLights = 6, width = 1092, height = 728; - - glm::vec3 position, lightInvDir; glm::mat4 depthProjectionMatrix, depthViewMatrix, depthModelMatrix = glm::mat4(1.0), depthMVP, ModelMatrix = glm::mat4(1.0), MVP, ViewMatrix, depthBiasMVP, ProjectionMatrix; glm::mat4 biasMatrix( @@ -717,7 +563,7 @@ void denseSyntheticSample(std::string imageName, std::string calibration, double cv::Vec3d residual; int lightNumber = 0; bool calculateResidual = false, perspectiveProjection, shadowControl; - double totalResidual, residualValue, gain = 1.0, bias = 0; + double totalResidual, residualValue; cv::Mat residualImage, albedo = cv::imread(albedoPath), normalMap = cv::imread(normalPath), heightMap = cv::Mat::zeros(albedo.size(), CV_8U); std::vector<cv::Mat> textureImages;; diff --git a/bin/specular_estimation b/bin/specular_estimation index b584f0ab983b7a153c41281c60643bc9208bf664..2132f32a2b798769fb7bfe1b178d9c8b59b778c7 100755 Binary files a/bin/specular_estimation and b/bin/specular_estimation differ diff --git a/plastic6 0.5 0.5 0.5 0.5.txt b/plastic6 0.5 0.5 0.5 0.5.txt index 710aacc6c29a66c69d0e44a422d993dd1a70ddd6..3d4e26e65d16e061b06fe84f7458008b6a62a4db 100644 --- a/plastic6 0.5 0.5 0.5 0.5.txt +++ b/plastic6 0.5 0.5 0.5 0.5.txt @@ -69,3 +69,374 @@ Roughness Metallic Light Distance Light Intensity Resiudal 0.779893 0 1 0 3057.55 0.779892 0 1 0 3057.56 0.779892 1.49012e-08 1 0 3057.56 +0.779892 -1.49012e-08 1 0 3057.56 +0.779892 0 1 0 3057.56 +0.779892 0 1 0 3057.55 +0.779892 0 1 0 3057.55 +0.779892 0 1 0 3057.56 +1 0 1 0 1838.66 +1 0 1 0 1838.66 +0.999999 0 1 0 1838.65 +1 1.49012e-08 1 0 1838.66 +1 -1.49012e-08 1 0 1838.66 +1 0 1 0 1838.66 +1 0 1 0 1838.65 +1 0 1 0 1838.65 +1 0 1 0 1838.66 +1 0 1 0 1838.66 +1 0 1 0 1838.66 +1 0 1 0 1838.66 +0.999999 0 1 0 1838.65 +1 1.49012e-08 1 0 1838.66 +1 -1.49012e-08 1 0 1838.66 +1 0 1 0 1838.66 +1 0 1 0 1838.65 +1 0 1 0 1838.65 +1 0 1 0 1838.66 +0.874051 0 1 0 1138.07 +0.874052 0 1 0 1138.07 +0.87405 0 1 0 1138.07 +0.874051 1.49012e-08 1 0 1138.07 +0.874051 -1.49012e-08 1 0 1138.07 +0.874051 0 1 0 1138.07 +0.874051 0 1 0 1138.07 +0.874051 0 1 0 1138.07 +0.874051 0 1 0 1138.07 +0.874051 0 1 0 1138.07 +0.874051 0 1 0 1138.07 +0.874052 0 1 0 1138.07 +0.87405 0 1 0 1138.07 +0.874051 1.49012e-08 1 0 1138.07 +0.874051 -1.49012e-08 1 0 1138.07 +0.874051 0 1 0 1138.07 +0.874051 0 1 0 1138.07 +0.874051 0 1 0 1138.07 +0.874051 0 1 0 1138.07 +1 0 1 0 5919.69 +1 0 1 0 5919.68 +0.999999 0 1 0 5919.69 +1 1.49012e-08 1 0 5919.69 +1 -1.49012e-08 1 0 5919.69 +1 0 1 0 5919.68 +1 0 1 0 5919.69 +1 0 1 0 5919.69 +1 0 1 0 5919.69 +0.879178 0 1 0 1120.24 +0.879179 0 1 0 1120.24 +0.879178 0 1 0 1120.24 +0.879178 1.49012e-08 1 0 1120.24 +0.879178 -1.49012e-08 1 0 1120.24 +0.879178 0 1 0 1120.24 +0.879178 0 1 0 1120.24 +0.879178 0 1 0 1120.24 +0.879178 0 1 0 1120.24 +0.879178 0 1 0 1120.24 +0.879178 0 1 0 1120.24 +0.879179 0 1 0 1120.24 +0.879178 0 1 0 1120.24 +0.879178 1.49012e-08 1 0 1120.24 +0.879178 -1.49012e-08 1 0 1120.24 +0.879178 0 1 0 1120.24 +0.879178 0 1 0 1120.24 +0.879178 0 1 0 1120.24 +0.879178 0 1 0 1120.24 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +0.999999 0 1 0 32398.9 +1 1.49012e-08 1 0 32398.9 +1 -1.49012e-08 1 0 32398.9 +1 0 1 0 6912.32 +1 0 1 0 6912.32 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +0.879418 0 1 0 1119.66 +0.879419 0 1 0 1119.66 +0.879417 0 1 0 1119.67 +0.879418 1.49012e-08 1 0 1119.66 +0.879418 -1.49012e-08 1 0 1119.66 +0.879418 0 1 0 1119.66 +0.879418 0 1 0 1119.66 +0.879418 0 1 0 1119.66 +0.879418 0 1 0 1119.66 +0.879418 0 1 0 1119.66 +0.879418 0 1 0 1119.66 +0.879419 0 1 0 1119.66 +0.879417 0 1 0 1119.67 +0.879418 1.49012e-08 1 0 1119.66 +0.879418 -1.49012e-08 1 0 1119.66 +0.879418 0 1 0 1119.66 +0.879418 0 1 0 1119.66 +0.879418 0 1 0 1119.66 +0.879418 0 1 0 1119.66 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +0.999999 0 1 0 32398.9 +1 1.49012e-08 1 0 32398.9 +1 -1.49012e-08 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +0.879597 0 1 0 1119.34 +0.879598 0 1 0 1119.34 +0.879596 0 1 0 1119.34 +0.879597 1.49012e-08 1 0 1119.34 +0.879597 -1.49012e-08 1 0 1119.34 +0.879597 0 1 0 1119.34 +0.879597 0 1 0 1119.34 +0.879597 0 1 0 1119.34 +0.879597 0 1 0 1119.34 +0.879597 0 1 0 1119.34 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +0.999999 0 1 0 32398.9 +1 1.49012e-08 1 0 32398.9 +1 -1.49012e-08 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +0.879597 0 1 0 1119.34 +0.879598 0 1 0 1119.34 +0.879596 0 1 0 1119.34 +0.879597 1.49012e-08 1 0 1119.34 +0.879597 -1.49012e-08 1 0 1119.34 +0.879597 0 1 0 1119.34 +0.879597 0 1 0 1119.34 +0.879597 0 1 0 1119.34 +0.879597 0 1 0 1119.34 +0.879597 0 1 0 1119.34 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +0.999999 0 1 0 32398.9 +1 1.49012e-08 1 0 32398.9 +1 -1.49012e-08 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +0.879597 0 1 0 1119.34 +0.879598 0 1 0 1119.34 +0.879596 0 1 0 1119.34 +0.879597 1.49012e-08 1 0 1119.34 +0.879597 -1.49012e-08 1 0 1119.34 +0.879597 0 1 0 1119.34 +0.879597 0 1 0 1119.34 +0.879597 0 1 0 1119.34 +0.879597 0 1 0 1119.34 +0.879597 0 1 0 1119.34 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +0.999999 0 1 0 32398.9 +1 1.49012e-08 1 0 32398.9 +1 -1.49012e-08 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +0.879596 0 1 0 1119.34 +0.879597 0 1 0 1119.34 +0.879596 0 1 0 1119.34 +0.879596 1.49012e-08 1 0 1119.34 +0.879596 -1.49012e-08 1 0 1119.34 +0.879596 0 1 0 1119.34 +0.879596 0 1 0 1119.34 +0.879596 0 1 0 1119.34 +0.879596 0 1 0 1119.34 +0.879596 0 1 0 1119.34 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +0.999999 0 1 0 32398.9 +1 1.49012e-08 1 0 32398.9 +1 -1.49012e-08 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +1 0 1 0 32398.9 +0.879588 0 1 0 1119.35 +0.879589 0 1 0 1119.35 +0.879587 0 1 0 1119.36 +0.879588 1.49012e-08 1 0 1119.35 +0.879588 -1.49012e-08 1 0 1119.35 +0.879588 0 1 0 1119.35 +0.879588 0 1 0 1119.35 +0.879588 0 1 0 1119.35 +0.879588 0 1 0 1119.35 +0.879588 0 1 0 1119.35 +0.944198 0 1 0 32398.9 +0.944199 0 1 0 32398.9 +0.944197 0 1 0 32398.9 +0.944198 1.49012e-08 1 0 32398.9 +0.944198 -1.49012e-08 1 0 32398.9 +0.944198 0 1 0 32398.9 +0.944198 0 1 0 32398.9 +0.944198 0 1 0 32398.9 +0.944198 0 1 0 32398.9 +0.879483 0 1 0 1119.54 +0.879484 0 1 0 1119.54 +0.879482 0 1 0 1119.55 +0.879483 1.49012e-08 1 0 1119.54 +0.879483 -1.49012e-08 1 0 1119.54 +0.879483 0 1 0 1119.54 +0.879483 0 1 0 1119.54 +0.879483 0 1 0 1119.54 +0.879483 0 1 0 1119.54 +0.879483 0 1 0 1119.54 +0.88099 0 1 0 1116.89 +0.880991 0 1 0 1116.89 +0.880989 0 1 0 1116.9 +0.88099 1.49012e-08 1 0 1116.89 +0.88099 -1.49012e-08 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.880991 0 1 0 1116.89 +0.880989 0 1 0 1116.9 +0.88099 1.49012e-08 1 0 1116.89 +0.88099 -1.49012e-08 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.882477 0 1 0 1186.98 +0.882478 0 1 0 1186.98 +0.882476 0 1 0 1186.98 +0.882477 1.49012e-08 1 0 1186.98 +0.882477 -1.49012e-08 1 0 1186.98 +0.882477 0 1 0 1186.98 +0.882477 0 1 0 1186.98 +0.882477 0 1 0 1186.98 +0.882477 0 1 0 1186.98 +0.88106 0 1 0 1117.11 +0.88106 0 1 0 1117.11 +0.881059 0 1 0 1117.11 +0.88106 1.49012e-08 1 0 1117.11 +0.88106 -1.49012e-08 1 0 1117.11 +0.88106 0 1 0 1117.11 +0.88106 0 1 0 1117.11 +0.88106 0 1 0 1117.11 +0.88106 0 1 0 1117.11 +0.880998 0 1 0 1116.9 +0.880999 0 1 0 1116.9 +0.880997 0 1 0 1116.91 +0.880998 1.49012e-08 1 0 1116.9 +0.880998 -1.49012e-08 1 0 1116.9 +0.880998 0 1 0 1116.91 +0.880998 0 1 0 1116.91 +0.880998 0 1 0 1116.91 +0.880998 0 1 0 1116.91 +0.880992 0 1 0 1116.89 +0.880993 0 1 0 1116.89 +0.880991 0 1 0 1116.89 +0.880992 1.49012e-08 1 0 1116.89 +0.880992 -1.49012e-08 1 0 1116.89 +0.880992 0 1 0 1116.89 +0.880992 0 1 0 1116.89 +0.880992 0 1 0 1116.89 +0.880992 0 1 0 1116.89 +0.880992 0 1 0 1116.89 +0.881737 0 1 0 1134.18 +0.881737 0 1 0 1134.18 +0.881736 0 1 0 1134.18 +0.881737 1.49012e-08 1 0 1134.18 +0.881737 -1.49012e-08 1 0 1134.18 +0.881737 0 1 0 1134.18 +0.881737 0 1 0 1134.18 +0.881737 0 1 0 1134.18 +0.881737 0 1 0 1134.18 +0.881047 0 1 0 1117.04 +0.881048 0 1 0 1117.04 +0.881046 0 1 0 1117.04 +0.881047 1.49012e-08 1 0 1117.04 +0.881047 -1.49012e-08 1 0 1117.04 +0.881047 0 1 0 1117.04 +0.881047 0 1 0 1117.04 +0.881047 0 1 0 1117.04 +0.881047 0 1 0 1117.04 +0.881017 0 1 0 1116.93 +0.881018 0 1 0 1116.93 +0.881016 0 1 0 1116.93 +0.881017 1.49012e-08 1 0 1116.93 +0.881017 -1.49012e-08 1 0 1116.93 +0.881017 0 1 0 1116.93 +0.881017 0 1 0 1116.93 +0.881017 0 1 0 1116.93 +0.881017 0 1 0 1116.93 +0.880993 0 1 0 1116.9 +0.880994 0 1 0 1116.9 +0.880993 0 1 0 1116.9 +0.880993 1.49012e-08 1 0 1116.9 +0.880993 -1.49012e-08 1 0 1116.9 +0.880993 0 1 0 1116.9 +0.880993 0 1 0 1116.9 +0.880993 0 1 0 1116.9 +0.880993 0 1 0 1116.9 +0.880991 0 1 0 1116.89 +0.880992 0 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.880991 1.49012e-08 1 0 1116.89 +0.880991 -1.49012e-08 1 0 1116.89 +0.880991 0 1 0 1116.89 +0.880991 0 1 0 1116.89 +0.880991 0 1 0 1116.89 +0.880991 0 1 0 1116.89 +0.880991 0 1 0 1116.89 +0.881177 0 1 0 1118.14 +0.881178 0 1 0 1118.14 +0.881176 0 1 0 1118.14 +0.881177 1.49012e-08 1 0 1118.14 +0.881177 -1.49012e-08 1 0 1118.14 +0.881177 0 1 0 1118.14 +0.881177 0 1 0 1118.14 +0.881177 0 1 0 1118.14 +0.881177 0 1 0 1118.14 +0.881007 0 1 0 1116.91 +0.881008 0 1 0 1116.91 +0.881006 0 1 0 1116.92 +0.881007 1.49012e-08 1 0 1116.91 +0.881007 -1.49012e-08 1 0 1116.91 +0.881007 0 1 0 1116.91 +0.881007 0 1 0 1116.91 +0.881007 0 1 0 1116.91 +0.881007 0 1 0 1116.91 +0.880999 0 1 0 1116.91 +0.881 0 1 0 1116.9 +0.880998 0 1 0 1116.91 +0.880999 1.49012e-08 1 0 1116.91 +0.880999 -1.49012e-08 1 0 1116.91 +0.880999 0 1 0 1116.91 +0.880999 0 1 0 1116.9 +0.880999 0 1 0 1116.9 +0.880999 0 1 0 1116.91 +0.880995 0 1 0 1116.9 +0.880996 0 1 0 1116.9 +0.880994 0 1 0 1116.9 +0.880995 1.49012e-08 1 0 1116.9 +0.880995 -1.49012e-08 1 0 1116.9 +0.880995 0 1 0 1116.9 +0.880995 0 1 0 1116.9 +0.880995 0 1 0 1116.9 +0.880995 0 1 0 1116.9 +0.880992 0 1 0 1116.9 +0.880993 0 1 0 1116.89 +0.880992 0 1 0 1116.9 +0.880992 1.49012e-08 1 0 1116.9 +0.880992 -1.49012e-08 1 0 1116.9 +0.880992 0 1 0 1116.9 +0.880992 0 1 0 1116.9 +0.880992 0 1 0 1116.9 +0.880992 0 1 0 1116.9 +0.88099 0 1 0 1116.89 +0.880991 0 1 0 1116.89 +0.880989 0 1 0 1116.9 +0.88099 1.49012e-08 1 0 1116.89 +0.88099 -1.49012e-08 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.88099 0 1 0 1116.89 +0.88099 0 1 0 1116.89