public static bool TryLoadFromFile(string fileName, out Intrinsics intrinsics) { intrinsics = null; if (!Directory.Exists(TrackingToolsConstants.intrinsicsDirectoryPath)) { Debug.LogError(logPrepend + "Directory missing.\n" + TrackingToolsConstants.intrinsicsDirectoryPath); return(false); } string filePath = TrackingToolsConstants.intrinsicsDirectoryPath + "/" + fileName; if (!fileName.EndsWith(".json")) { filePath += ".json"; } if (!File.Exists(filePath)) { Debug.LogError(logPrepend + "File missing.\n" + filePath); return(false); } intrinsics = JsonUtility.FromJson <Intrinsics>(File.ReadAllText(filePath)); return(true); }
void Awake() { Intrinsics intrinsics; if (!Intrinsics.TryLoadFromFile(_intrinsicsFileName, out intrinsics)) { return; } Camera cam = GetComponent <Camera>(); intrinsics.ApplyToCamera(cam); }
public IntrinsicsCalibrator(int imageWidth, int imageHeight) { const int regularSampleCount = 4; _intrinsics = new Intrinsics(); _patternImageSamples = new List <Mat>(regularSampleCount); _patternRealSamples = new List <Mat>(regularSampleCount); _distortionCoeffsMat = new MatOfDouble(); _rotationSamples = new List <Mat>(regularSampleCount); _translationSamples = new List <Mat>(regularSampleCount); _sensorMat = Mat.eye(3, 3, CvType.CV_64FC1); _textureSize = new Size(imageWidth, imageHeight); }
void Awake() { if (!Intrinsics.TryLoadFromFile(_intrinsicsFileName, out _intrinsics)) { Debug.LogError("Intrinsics file '" + _intrinsicsFileName + "' not found.\n"); enabled = false; return; } _undistortMap1 = new Mat(); _undistortMap2 = new Mat(); _extrinsicsCalibrator = new CameraExtrinsicsCalibrator(); TrackingToolsHelper.RenderPattern(_chessPatternSize, TrackingToolsHelper.PatternType.Chessboard, 1024, ref _chessPatternTexture, ref _patternRenderMaterial); // Prepare UI. _aspectFitter = _processedCameraImage.GetComponent <AspectRatioFitter>(); if (!_aspectFitter) { _aspectFitter = _processedCameraImage.gameObject.AddComponent <AspectRatioFitter>(); } _aspectFitter.aspectMode = AspectRatioFitter.AspectMode.FitInParent; _previewMaterial = new Material(Shader.Find(TrackingToolsConstants.previewShaderName)); _processedCameraImage.material = _previewMaterial; _processedCameraImage.color = Color.white; _arImage = new GameObject("ARImage").AddComponent <RawImage>(); _arImage.transform.SetParent(_processedCameraImage.transform); _arImage.rectTransform.FitParent(); _arImage.gameObject.SetActive(false); _mainCamera.backgroundColor = Color.clear; _chessPatternTransform = GameObject.CreatePrimitive(PrimitiveType.Quad).transform; _chessPatternTransform.name = "Chessboard"; _chessPatternTransform.localScale = new Vector3((_chessPatternSize.x - 1) * _chessTileSize * 0.001f, (_chessPatternSize.y - 1) * _chessTileSize * 0.001f, 0); Shader unlitTextureShader = Shader.Find("Unlit/Texture"); Material chessboardMaterial = new Material(unlitTextureShader); chessboardMaterial.mainTexture = _chessPatternTexture; _chessPatternTransform.GetComponent <Renderer>().material = chessboardMaterial; _precisionDotsContainerObject = TrackingToolsHelper.CreatePrecisionTestDots(_chessPatternTransform, _testPrecisionDotsLayer, _chessPatternSize, _chessTileSize / 1000f); // Update world points. TrackingToolsHelper.UpdateWorldSpacePatternPoints(_chessPatternSize, _chessPatternTransform.localToWorldMatrix, TrackingToolsHelper.PatternType.Chessboard, Vector2.zero, ref _chessCornersWorldMat); }
/// <summary> /// Update the extrinsics of projector relative to camera. /// </summary> /// <param name="cameraIntrinsics"></param> /// <param name="projectorIntrinsics"></param> /// <param name="textureSize"></param> public void Update(Intrinsics cameraIntrinsics, Intrinsics projectorIntrinsics, Size textureSize) { int w = (int)textureSize.width; int h = (int)textureSize.height; cameraIntrinsics.ToOpenCV(ref _cameraSensorMat, w, h); projectorIntrinsics.ToOpenCV(ref _projectorSensorMat, w, h); // In order to match OpenCV's pixel space (zero at top-left) and Unity's camera space (up is positive), we flip the sensor matrix. _cameraSensorMat.WriteValue(-_cameraSensorMat.ReadValue(1, 1), 1, 1); // fy _cameraSensorMat.WriteValue(textureSize.height - _cameraSensorMat.ReadValue(1, 2), 1, 2); // cy _projectorSensorMat.WriteValue(-_projectorSensorMat.ReadValue(1, 1), 1, 1); // fy _projectorSensorMat.WriteValue(textureSize.height - _projectorSensorMat.ReadValue(1, 2), 1, 2); // cy int flag = 0; // Don't recompute and change intrinsics parameters. flag |= Calib3d.CALIB_FIX_INTRINSIC; // Don't recompute distortions, ignore them. We assume the incoming points have already bee undistorted. flag |= Calib3d.CALIB_FIX_TANGENT_DIST | Calib3d.CALIB_FIX_K1 | Calib3d.CALIB_FIX_K2 | Calib3d.CALIB_FIX_K3 | Calib3d.CALIB_FIX_K4 | Calib3d.CALIB_FIX_K5; // Compute! Calib3d.stereoCalibrate ( _patternWorldSamples, _cameraPatternImageSamples, _projectorPatternImageSamples, _cameraSensorMat, _noDistCoeffs, _projectorSensorMat, _noDistCoeffs, textureSize, _rotation3x3Mat, _translationVecMat, _essentialMat, _fundamentalMat, flag ); _extrinsics.UpdateFromOpenCvStereoCalibrate(_rotation3x3Mat, _translationVecMat); }
void Awake() { // Create UI. if (!_containerUI) { _containerUI = new GameObject("CameraPoser").AddComponent <RectTransform>(); _containerUI.transform.SetParent(_canvas.transform); } CanvasGroup wrapperGroup = _containerUI.GetComponent <CanvasGroup>(); if (!wrapperGroup) { wrapperGroup = _containerUI.gameObject.AddComponent <CanvasGroup>(); } wrapperGroup.alpha = _alpha; Image backgroundImage = new GameObject("Background").AddComponent <Image>(); backgroundImage.transform.SetParent(_containerUI.transform); _rawImageUI = new GameObject("CameraImage").AddComponent <RawImage>(); _rawImageUI.transform.SetParent(_containerUI.transform); _rawImageUI.uvRect = _flipTexture ? new UnityEngine.Rect(0, 1, 1, -1) : new UnityEngine.Rect(0, 0, 1, 1); _rawImageRect = _rawImageUI.GetComponent <RectTransform>(); _uiMaterial = new Material(Shader.Find("Hidden/SingleChannelTexture")); _rawImageUI.material = _uiMaterial; _aspectFitterUI = _rawImageUI.gameObject.AddComponent <AspectRatioFitter>(); _aspectFitterUI.aspectMode = AspectRatioFitter.AspectMode.HeightControlsWidth; backgroundImage.color = Color.black; ExpandRectTransform(_containerUI); ExpandRectTransform(backgroundImage.GetComponent <RectTransform>()); ExpandRectTransform(_rawImageRect); _userPointRects = new RectTransform[pointCount]; _userPointImages = new Image[pointCount]; for (int p = 0; p < pointCount; p++) { GameObject pointObject = new GameObject("Point" + p); pointObject.transform.SetParent(_rawImageRect); Image pointImage = pointObject.AddComponent <Image>(); pointImage.color = Color.cyan; RectTransform pointRect = pointObject.GetComponent <RectTransform>(); pointRect.sizeDelta = Vector2.one * 5; SetAnchoredPosition(pointRect, defaultPointPositions[p]); pointRect.anchoredPosition = Vector3.zero; Text pointLabel = new GameObject("Label").AddComponent <Text>(); pointLabel.text = p.ToString(); pointLabel.transform.SetParent(pointRect); pointLabel.rectTransform.anchoredPosition = Vector2.zero; pointLabel.rectTransform.sizeDelta = new Vector2(_fontSize, _fontSize) * 2; pointLabel.font = _font; pointLabel.fontSize = _fontSize; _userPointRects[p] = pointRect; _userPointImages[p] = pointImage; } // Hide. //if( !_interactable ) _containerUI.transform.gameObject.SetActive( false ); // Prepare OpenCV. _noDistCoeffs = new MatOfDouble(new double[] { 0, 0, 0, 0 }); _rVec = new Mat(); _tVec = new Mat(); _anchorPointsImage = new Point[pointCount]; _anchorPointsWorld = new Point3[pointCount]; _anchorPointsImageMat = new MatOfPoint2f(); _anchorPointsWorldMat = new MatOfPoint3f(); _anchorPointsImageMat.alloc(pointCount); _anchorPointsWorldMat.alloc(pointCount); for (int p = 0; p < pointCount; p++) { _anchorPointsImage[p] = new Point(); _anchorPointsWorld[p] = new Point3(); } // Load files. if (Intrinsics.TryLoadFromFile(_intrinsicsFileName, out _intrinsics)) { enabled = false; return; } LoadCircleAnchorPoints(); // Update variables. if (!Application.isEditor) { OnValidate(); } }
void Awake() { Application.targetFrameRate = 30; // Check resources. if (_operationMode == OperationMode.ManualSamlping && !_manualSampleButton) { Debug.LogError(logPrepend + "Missing sample button. You must provide a sample button when OperationMode is " + OperationMode.ManualSamlping); enabled = false; return; } // Load files. if (!Intrinsics.TryLoadFromFile(_cameraIntrinsicsFileName, out _cameraIntrinsics)) { enabled = false; return; } // Find shaders. Shader unlitColorShader = Shader.Find("Unlit/Color"); Shader unlitTextureShader = Shader.Find("Unlit/Texture"); Shader unlitTintedTextureShader = Shader.Find("Unlit/TintedInvertibleTexture"); _sb = new StringBuilder(); // Operation mode dependent things. _stableSampleCountThreshold = _operationMode == OperationMode.ManualSamlping ? stableFrameCountThresholdForManualSampling : stableFrameCountThresholdForTimedSampling; if (_manualSampleButton) { _manualSampleButton.gameObject.SetActive(_operationMode == OperationMode.ManualSamlping); _manualSampleButton.interactable = false; } // Prepare OpenCV. _cameraExtrinsicsCalibrator = new CameraExtrinsicsCalibrator(); _projectorExtrinsicsCalibrator = new ProjectorFromCameraExtrinsicsCalibrator(); _noDistCoeffs = new MatOfDouble(new double[] { 0, 0, 0, 0 }); _circlePointsProjectorRenderImageMat = new MatOfPoint2f(); _circlePointsRealModelMat = new MatOfPoint3f(); _circlePointsDetectedWorldMat = new MatOfPoint3f(); _undistortMap1 = new Mat(); _undistortMap2 = new Mat(); // Create patterns. TrackingToolsHelper.RenderPattern(_chessPatternSize, TrackingToolsHelper.PatternType.Chessboard, 1024, ref _chessPatternTexture, ref _patternRenderMaterial); // Layers. int uiLayer = LayerMask.NameToLayer("UI"); int mainCameraLayerMask = LayerMask.GetMask("Default"); int projectorLayer = LayerMask.NameToLayer("TransparentFX"); int projectorLayerMask = LayerMask.GetMask("TransparentFX"); // Objects. _calibrationBoardTransform = new GameObject("CalibrationBoard").transform; // Create and prepare UI. _cameraAspectFitter = _processedCameraImage.GetComponent <AspectRatioFitter>(); if (!_cameraAspectFitter) { _cameraAspectFitter = _processedCameraImage.gameObject.AddComponent <AspectRatioFitter>(); } _cameraAspectFitter.aspectMode = AspectRatioFitter.AspectMode.FitInParent; _previewMaterial = new Material(Shader.Find(TrackingToolsConstants.previewShaderName)); _processedCameraImage.gameObject.layer = uiLayer; _processedCameraImage.material = _previewMaterial; _processedCameraImage.color = Color.white; _arImage = new GameObject("ARImage").AddComponent <RawImage>(); _arImage.transform.SetParent(_processedCameraImage.transform); _arImage.transform.SetAsFirstSibling(); _arImage.raycastTarget = false; _arImage.rectTransform.FitParent(); _arImage.gameObject.layer = uiLayer; _mainCamera.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity); _mainCamera.cullingMask = mainCameraLayerMask; _projectorCamera.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity); _projectorCamera.cullingMask = projectorLayerMask; _projectorCamera.usePhysicalProperties = false; _chessPatternTransform = GameObject.CreatePrimitive(PrimitiveType.Quad).transform; _chessPatternTransform.SetParent(_calibrationBoardTransform); _chessPatternTransform.name = "Chessboard"; Material chessboardMaterial = new Material(unlitTextureShader); chessboardMaterial.mainTexture = _chessPatternTexture; _chessPatternTransform.GetComponent <Renderer>().material = chessboardMaterial; float chessTileSizeMeters = _chessTileSize * 0.001f; _chessPatternTransform.localScale = new Vector3((_chessPatternSize.x - 1) * chessTileSizeMeters, (_chessPatternSize.y - 1) * chessTileSizeMeters, 0); TrackingToolsHelper.UpdateWorldSpacePatternPoints(_chessPatternSize, _chessPatternTransform.localToWorldMatrix, TrackingToolsHelper.PatternType.Chessboard, Vector2.zero, ref _chessCornersWorldMat); _circlePatternTransform = GameObject.CreatePrimitive(PrimitiveType.Quad).transform; _circlePatternTransform.name = "Circlesboard"; _circlePatternBoardMaterial = new Material(unlitTintedTextureShader); _circlePatternTransform.GetComponent <Renderer>().material = _circlePatternBoardMaterial; _circlePatternTransform.position = Vector3.forward; _circlePatternTransform.gameObject.layer = projectorLayer; _precisionDotsContainerObject = TrackingToolsHelper.CreatePrecisionTestDots(_calibrationBoardTransform, projectorLayer, _chessPatternSize, chessTileSizeMeters); _precisionDotsContainerObject.SetActive(false); _projectorSampleMeterTransform = GameObject.CreatePrimitive(PrimitiveType.Quad).transform; _projectorSampleMeterTransform.gameObject.layer = projectorLayer; _projectorSampleMeterTransform.name = "ProjectorSampleMeter"; _projectorSampleMeterTransform.localScale = new Vector3(_chessPatternTransform.localScale.x, TrackingToolsConstants.precisionTestDotSize, 0); _projectorSampleMeterTransform.SetParent(_calibrationBoardTransform); float dotOffsetY = ((_chessPatternSize.y - 4) * 0.5f + 1) * chessTileSizeMeters; _projectorSampleMeterTransform.localPosition = new Vector3(0, -dotOffsetY - chessTileSizeMeters); Material sampleMeterMaterial = new Material(unlitColorShader); _projectorSampleMeterTransform.GetComponent <Renderer>().sharedMaterial = sampleMeterMaterial; _projectorSampleMeterTransform.gameObject.SetActive(false); _intrinsicsErrorText.gameObject.SetActive(false); _extrinsicsErrorText.gameObject.SetActive(false); _saveButton.gameObject.SetActive(false); _undoSampleButton.gameObject.SetActive(false); _screenBorderMaterial = new Material(unlitColorShader); _circlePatternToWorldPrevFrame = Matrix4x4.identity; _previewFlasher = new MaterialPropFlasher(_previewMaterial, "_Whiteout", TrackingToolsConstants.flashDuration); UpdateSampleCounterUI(); // Subscribe. _circlePatternScaleSlider.onValueChanged.AddListener(( float v ) => _manualCirclePatternTransformationRequested = true); //OnCirclePatternScaleSliderChanged ); _circlePatternOffsetXSlider.onValueChanged.AddListener(( float v ) => _manualCirclePatternTransformationRequested = true); _circlePatternOffsetYSlider.onValueChanged.AddListener(( float v ) => _manualCirclePatternTransformationRequested = true); _saveButton.onClick.AddListener(SaveToFiles); _undoSampleButton.onClick.AddListener(UndoSample); if (_manualSampleButton) { _manualSampleButton.onClick.AddListener(() => _sampleManuallyRequested = true);; } }
public bool UpdateExtrinsics(MatOfPoint3f patternPointsWorldMat, MatOfPoint2f patternPointsImageMat, Intrinsics intrinsics, int imageWidth, int imageHeight) { intrinsics.ToOpenCV(ref _sensorMatrix, imageWidth, imageHeight); // In order to match OpenCV's pixel space (zero at top-left) and Unity's camera space (up is positive), we flip the sensor matrix. _sensorMatrix.WriteValue(-_sensorMatrix.ReadValue(1, 1), 1, 1); // fy _sensorMatrix.WriteValue(imageHeight - _sensorMatrix.ReadValue(1, 2), 1, 2); // cy // Find pattern pose, relative to camera (at zero position) using solvePnP. _isValid = Calib3d.solvePnP(patternPointsWorldMat, patternPointsImageMat, _sensorMatrix, _noDistCoeffs, _rotationVecMat, _translationVecMat); if (_isValid) { _extrinsics.UpdateFromOpenCvSolvePnp(_rotationVecMat, _translationVecMat); } return(_isValid); }