private void Update() { if (webcamTexture != null && webcamTexture.didUpdateThisFrame) { // Update new data from webcam device UpdateWebcamBegin(); // Detect & Draw chessboard corners bool detected = FindAndDrawChessboardCorners(webcamGrayMat, webcamModifiedMat); if (detected == true && Input.GetKey(KeyCode.D)) { // If detected, update camera transform accordingly CamExtrinsicParam camParams = GetExtrinsicParameters(); UpdateCameraTransform(camParams); } // Apply modified data to webcam (image with corners detected) UpdateWebcamEnd(); } if (displayTexture != null) { canvasImageDisplay.texture = displayTexture; } }
private CamExtrinsicParam GetExtrinsicParameters() { // Compute camera extrinsic parameters : rotation & translation matrices. Mat rotationMat = new Mat(3, 1, DepthType.Cv64F, 1); Mat translationMat = new Mat(3, 1, DepthType.Cv64F, 1); bool res = CvInvoke.SolvePnP(virtualCorners, imageCorners, intrinsicMatrix, distortionMatrix, rotationMat, translationMat); if (res == false) { Debug.Log("SolvePnP Failed!"); return(null); } // Convert the rotation from 3 axis rotations into a rotation matrix. double[] tempRotationData = new double[3]; Marshal.Copy(rotationMat.DataPointer, tempRotationData, 0, rotationMat.Width * rotationMat.Height); tempRotationData[0] = tempRotationData[0]; tempRotationData[1] = -tempRotationData[1]; tempRotationData[2] = -tempRotationData[2]; GCHandle tempHandle = GCHandle.Alloc(tempRotationData, GCHandleType.Pinned); // Final rotation matrix with Rodrigues function. rotationMat = new Mat(3, 1, DepthType.Cv64F, 1, tempHandle.AddrOfPinnedObject(), sizeof(double)); Mat finalRotationMat = new Mat(3, 3, DepthType.Cv64F, 1); CvInvoke.Rodrigues(rotationMat, finalRotationMat); // Get all data to set Camera transform. double[] rotationData = new double[9]; Marshal.Copy(finalRotationMat.DataPointer, rotationData, 0, finalRotationMat.Width * finalRotationMat.Height); double[] translationData = new double[3]; Marshal.Copy(translationMat.DataPointer, translationData, 0, translationMat.Width * translationMat.Height); // Return data. CamExtrinsicParam ret = new CamExtrinsicParam(); ret.rotationData = rotationData; ret.translationData = translationData; return(ret); }
private void UpdateCameraTransform(CamExtrinsicParam camParams) { double[] extrinsicRotation = camParams.rotationData; double[] extrinsicTranslat = camParams.translationData; // Projection matrix Matrix4x4 projection = new Matrix4x4(); projection.m00 = (float)(2 * intrinsicMatrix[0, 0] / webcamTexture.width); projection.m10 = 0; projection.m20 = 0; projection.m30 = 0; projection.m01 = 0; projection.m11 = (float)(2 * intrinsicMatrix[1, 1] / webcamTexture.height); projection.m21 = 0; projection.m31 = 0; projection.m02 = (float)(1 - 2 * intrinsicMatrix[0, 2] / webcamTexture.width); projection.m12 = (float)(-1 + (2 * intrinsicMatrix[1, 2] + 2) / webcamTexture.height); projection.m22 = (Camera.main.nearClipPlane + Camera.main.farClipPlane) / (Camera.main.nearClipPlane - Camera.main.farClipPlane); projection.m32 = -1; projection.m03 = 0; projection.m13 = 0; projection.m23 = 2 * (Camera.main.nearClipPlane * Camera.main.farClipPlane) / (Camera.main.nearClipPlane - Camera.main.farClipPlane); projection.m33 = 0; Camera.main.projectionMatrix = projection; Camera.main.fieldOfView = Mathf.Atan(1.0f / projection.m11) * 2.0f * Mathf.Rad2Deg; Camera.main.aspect = webcamTexture.width / webcamTexture.height; // Model view matrix Matrix4x4 modelViewMatrix = new Matrix4x4(); modelViewMatrix.m00 = (float)extrinsicRotation[0]; modelViewMatrix.m10 = (float)extrinsicRotation[3]; modelViewMatrix.m20 = (float)extrinsicRotation[6]; modelViewMatrix.m30 = 0; modelViewMatrix.m01 = (float)extrinsicRotation[1]; modelViewMatrix.m11 = (float)extrinsicRotation[4]; modelViewMatrix.m21 = (float)extrinsicRotation[7]; modelViewMatrix.m31 = 0; modelViewMatrix.m02 = (float)extrinsicRotation[2]; modelViewMatrix.m12 = (float)extrinsicRotation[5]; modelViewMatrix.m22 = (float)extrinsicRotation[8]; modelViewMatrix.m32 = 0; modelViewMatrix.m03 = (float)extrinsicTranslat[0]; modelViewMatrix.m13 = (float)extrinsicTranslat[1]; modelViewMatrix.m23 = (float)extrinsicTranslat[2]; modelViewMatrix.m33 = 1; modelViewMatrix = modelViewMatrix.inverse; // Update unity camera transform Camera.main.transform.position = GetPositionFromModelView(modelViewMatrix); Camera.main.transform.rotation = GetRotationFromModelView(modelViewMatrix); }