Exemplo n.º 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>
        /// Parses the basic parameters of any COLMAP camera model.
        /// </summary>
        /// <param name="split"></param> The split string from which to parse information.
        /// <param name="isOmnidirectional"></param> True if the camera model is omnidirectional, false otherwise.
        /// <returns></returns> A camera model containing the parsed parameters.
        private static CameraModel BasicParse(string[] split, bool isOmnidirectional)
        {
            CameraModel cameraModel = CameraModel.CreateCameraModel();

            // The camera's projection type is not handled by COLMAP, and has to be specified.
            cameraModel.isOmnidirectional = isOmnidirectional;
            // The camera's index is given by the first parameter in the .txt file.
            cameraModel.SetCameraReferenceIndexAndImageName(GeneralToolkit.ParseInt(split[0]), cameraModel.imageName);
            // The camera's pixel resolution is given by the second and third parameters in the .txt file.
            cameraModel.pixelResolution = new Vector2Int(GeneralToolkit.ParseInt(split[2]), GeneralToolkit.ParseInt(split[3]));
            // Return the camera model.
            return(cameraModel);
        }