Example #1
0
        /// <summary>
        /// Parses the camera setup from a directory containing an "images" folder with an image dataset from the Stanford Light Field Archive, and saves the parsed setup in this directory.
        /// </summary>
        public void ParseCameraSetup()
        {
            // Inform of process start.
            Debug.Log(GeneralToolkit.FormatScriptMessage(this.GetType(), "Started parsing camera setup for an image dataset from the Stanford Light Field Archive located at: " + dataHandler.colorDirectory + "."));
            // Get the files in the "images" folder.
            FileInfo[] fileInfos = GeneralToolkit.GetFilesByExtension(dataHandler.colorDirectory, ".png");
            // Determine the pixel resolution of the images.
            Texture2D tempTex = new Texture2D(1, 1);

            GeneralToolkit.LoadTexture(fileInfos[0].FullName, ref tempTex);
            Vector2Int pixelResolution = new Vector2Int(tempTex.width, tempTex.height);

            DestroyImmediate(tempTex);
            // Prepare repositioning around center if it is selected.
            Vector3 meanPos = Vector3.zero;

            // Reset the camera models to fit the color count.
            _cameraSetup.ResetCameraModels();
            _cameraSetup.cameraModels = new CameraModel[dataHandler.sourceColorCount];
            // Iteratively add each camera model to the setup.
            for (int iter = 0; iter < dataHandler.sourceColorCount; iter++)
            {
                CameraModel cameraModel = _cameraSetup.AddCameraModel(iter);
                // Store the image's pixel resolution in the camera model.
                cameraModel.pixelResolution = pixelResolution;
                // Store the image's name in the camera model.
                FileInfo fileInfo = fileInfos[iter];
                cameraModel.SetCameraReferenceIndexAndImageName(cameraModel.cameraReferenceIndex, fileInfo.Name);
                // Store the image's position in the model.
                string[] split     = fileInfo.Name.Split('_');
                float    positionY = -GeneralToolkit.ParseFloat(split[split.Length - 3]);
                float    positionX = GeneralToolkit.ParseFloat(split[split.Length - 2]);
                Vector3  pos       = scaleFactor * new Vector3(positionX, positionY, 0);
                cameraModel.transform.position = pos;
                meanPos += pos;
            }
            // If it is selected, reposition the camera setup around its center position.
            if (repositionAroundCenter)
            {
                meanPos /= dataHandler.sourceColorCount;
                for (int iter = 0; iter < dataHandler.sourceColorCount; iter++)
                {
                    CameraModel cameraModel = _cameraSetup.cameraModels[iter];
                    cameraModel.transform.position = cameraModel.transform.position - meanPos;
                }
            }
            // Temporarily move the color images to a safe location.
            string tempDirectoryPath = Path.Combine(GeneralToolkit.GetDirectoryBefore(dataHandler.dataDirectory), "temp");

            GeneralToolkit.Move(PathType.Directory, dataHandler.colorDirectory, tempDirectoryPath);
            // Save the camera setup information (this would also have cleared the "images" folder if it was still there).
            Acquisition.Acquisition.SaveAcquisitionInformation(dataHandler, cameraSetup);
            // Move the color images back into their original location.
            GeneralToolkit.Delete(dataHandler.colorDirectory);
            GeneralToolkit.Move(PathType.Directory, tempDirectoryPath, dataHandler.colorDirectory);
            // Update the camera models of the setup object.
            _cameraSetup.FindCameraModels();
            // Inform of end of process.
            Debug.Log(GeneralToolkit.FormatScriptMessage(this.GetType(), "Finished parsing camera setup. Result can be previewed in the Scene view."));
        }
        /// <summary>
        /// Reads images information from a COLMAP "images.txt" file, and saves it into the referenced array.
        /// Note that the array contains a camera element for each image. Array elements will be initialized here.
        /// </summary>
        /// <param name="cameraSetup"></param> The camera setup to which to output the list of parsed camera models.
        /// <param name="workspace"></param> The workspace from which to work.
        public static void ReadImagesInformation(CameraSetup cameraSetup, string workspace)
        {
            List <Vector3>    positionList = new List <Vector3>();
            List <Quaternion> rotationList = new List <Quaternion>();
            List <string>     fileNameList = new List <string>();
            List <int>        cameraIDList = new List <int>();

            // Read COLMAP's images file.
            using (StreamReader reader = File.OpenText(GetImagesFile(workspace)))
            {
                bool   isOdd = false;
                string line;
                // Read the file line-by-line to the end.
                while ((line = reader.ReadLine()) != null)
                {
                    // Skip the lines from the header, that start with #.
                    if (!line.StartsWith("#"))
                    {
                        // If the line is odd, skip it, and indicate that the next line will be even.
                        if (isOdd)
                        {
                            isOdd = false;
                        }
                        // If the line is even, parse it, and indicate that the next line will be odd.
                        else
                        {
                            string[] split = line.Split(' ');
                            // COLMAP's images should have 10 parameters.
                            if (split.Length > 9)
                            {
                                // Parse position and rotation, and convert them to Unity's coordinate system.
                                Quaternion rotation = new Quaternion(GeneralToolkit.ParseFloat(split[2]), GeneralToolkit.ParseFloat(split[3]), GeneralToolkit.ParseFloat(split[4]), GeneralToolkit.ParseFloat(split[1]));
                                Vector3    position = new Vector3(GeneralToolkit.ParseFloat(split[5]), GeneralToolkit.ParseFloat(split[6]), GeneralToolkit.ParseFloat(split[7]));
                                ConvertCoordinatesCOLMAPToUnity(ref position, ref rotation);
                                // Add all the parameters to the dedicated lists.
                                positionList.Add(position);
                                rotationList.Add(rotation);
                                fileNameList.Add(split[9]);
                                cameraIDList.Add(GeneralToolkit.ParseInt(split[8]));
                                // Indicate that the next line will be odd.
                                isOdd = true;
                            }
                        }
                    }
                }
                reader.Close();
            }
            // Use these lists to create and fill the output array of camera models.
            cameraSetup.cameraModels = new CameraModel[positionList.Count];
            for (int iter = 0; iter < positionList.Count; iter++)
            {
                CameraModel cameraModel = cameraSetup.AddCameraModel(iter);
                cameraModel.SetCameraReferenceIndexAndImageName(cameraIDList[iter], fileNameList[iter]);
                cameraModel.transform.localPosition = positionList[iter];
                cameraModel.transform.localRotation = rotationList[iter];
            }
        }
 /// <summary>
 /// Reads the stored additional information.
 /// </summary>
 /// <param name="cameraSetup"></param> The camera setup to modify with the parsed information.
 public void ReadCOLIBRIVRAdditionalInformation(CameraSetup cameraSetup)
 {
     string[] lines = File.ReadAllLines(additionalInfoFile);
     foreach (string line in lines)
     {
         if (!line.StartsWith("#"))
         {
             string[] split = line.Split(' ');
             if (split.Length > 2)
             {
                 Vector3 newInitialViewingPosition = new Vector3(GeneralToolkit.ParseFloat(split[0]), GeneralToolkit.ParseFloat(split[1]), GeneralToolkit.ParseFloat(split[2]));
                 cameraSetup.SetAdditionalParameters(newInitialViewingPosition);
             }
         }
     }
 }
        /// <summary>
        /// Reads the stored additional information.
        /// </summary>
        /// <param name="cameraSetup"></param> The camera setup to modify with the parsed information.
        public void ReadCOLIBRIVRAdditionalInformation(CameraSetup cameraSetup)
        {
            string[] lines = File.ReadAllLines(additionalInfoFile);
            for (int i = 0; i < lines.Length; ++i)
            {
                if (lines[i].Contains("INITIAL_VIEWING_POSITION"))
                {
                    string[] split = lines[++i].Split(' ');
                    if (split.Length == 3)
                    {
                        Vector3 newInitialViewingPosition = new Vector3(GeneralToolkit.ParseFloat(split[0]), GeneralToolkit.ParseFloat(split[1]), GeneralToolkit.ParseFloat(split[2]));
                        cameraSetup.SetAdditionalParameters(newInitialViewingPosition);
                    }
                    continue;
                }

                if (lines[i].Contains("DISTANCE_RANGE"))
                {
                    while (i + 1 < lines.Length && !lines[i + 1].StartsWith("#"))
                    {
                        string[] split = lines[++i].Split(' ');
                        if (split.Length == 3)
                        {
                            int     cameraReferenceIndex = GeneralToolkit.ParseInt(split[0]);
                            Vector2 newDistanceRange     = new Vector2(GeneralToolkit.ParseFloat(split[1]), GeneralToolkit.ParseFloat(split[2]));
                            // Find the referenced camera and set its distance range
                            foreach (CameraModel camera in cameraSetup.cameraModels)
                            {
                                if (camera.cameraReferenceIndex == cameraReferenceIndex)
                                {
                                    camera.distanceRange = newDistanceRange;
                                }
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Parses camera parameters for a COLMAP camera of the SIMPLE_PINHOLE or PINHOLE type.
        /// </summary>
        /// <param name="split"></param> The split string from which to parse information.
        /// <returns></returns> A camera model containing the parsed parameters.
        private static CameraModel ParsePinhole(string[] split, bool isSimple)
        {
            // Parse basic parameters for a perspective camera.
            CameraModel cameraModel = BasicParse(split, false);
            // Parse focal length based on whether this is a SIMPLE_PINHOLE or PINHOLE camera model.
            Vector2 focalLength = Vector2.zero;

            if (isSimple)
            {
                focalLength = GeneralToolkit.ParseFloat(split[4]) * Vector2.one;
            }
            else
            {
                focalLength = new Vector2(GeneralToolkit.ParseFloat(split[4]), GeneralToolkit.ParseFloat(split[5]));
            }
            // Compute field of view based on the focal length.
            float fieldOfViewX = Camera.FocalLengthToFieldOfView(focalLength.x, cameraModel.pixelResolution.x);
            float fieldOfViewY = Camera.FocalLengthToFieldOfView(focalLength.y, cameraModel.pixelResolution.y);

            cameraModel.fieldOfView = new Vector2(fieldOfViewX, fieldOfViewY);
            // Return the camera model.
            return(cameraModel);
        }