using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ImageRelativePos : MonoBehaviour {
public GameObject backImage;
public GameObject foreImage;
public GameObject cube;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
if (foreImage.GetComponent<DefaultTrackableEventHandler>().imageTargetIsFound && backImage.GetComponent<DefaultTrackableEventHandler>().imageTargetIsFound)
{
Matrix4x4 Road2World = GetExtrinsic(backImage.transform);
Matrix4x4 Wood2World = GetExtrinsic(foreImage.transform);
//獲得wood到road的轉換矩陣
Matrix4x4 Wood2Road = Road2World.inverse*Wood2World;
// Matrix4x4 Road2World=GetExtrinsic()
Vector4 vy = Wood2Road.GetColumn(1);
Vector4 vz = Wood2Road.GetColumn(2);
Quaternion newQ = Quaternion.LookRotation(new Vector3(vz.x, vz.y, vz.z), new Vector3(vy.x, vy.y, vy.z));
cube.transform.position = new Vector3(Wood2Road.m03, Wood2Road.m13, Wood2Road.m23);
cube.transform.rotation = newQ;
//獲取road到世界座標系的轉換
}
}
Matrix4x4 GetExtrinsic(Transform trans)
{
Matrix4x4 rot = new Matrix4x4();
rot.SetTRS(trans.position, trans.rotation, new Vector3(1, 1, 1));
return rot;
}
}
原圖片:
消除前景後的圖片:
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.UnityUtils;
using OpenCVForUnity.ImgprocModule;
using System.Collections;
using UnityEngine;
public class Foreground : MonoBehaviour
{
public GameObject backImage;
public GameObject foreImage;
public Mat imageMat;
private MeshRenderer renderer;
Texture2D imgTexture;
Texture2D texture2d;
float relativeAngle;
Vector2 tr;
Vector2 tl;
Vector2 bl;
Vector2 br;
float tr_x;
float tr_y;
float offsetPixel_x = 0;
float offsetPixel_y = 0;
int foreImageSize = 1024 / 3;
OpenCVForUnity.CoreModule.Rect rectCrop;
Mat srcRectMat = new Mat(4, 1, CvType.CV_32FC2);
Mat dstRectMat = new Mat(4, 1, CvType.CV_32FC2);
Mat croppedImage;
Mat outputMat0;
void Start()
{
imgTexture = Resources.Load("background") as Texture2D;
renderer = this.GetComponent<MeshRenderer>();
imageMat = new Mat(imgTexture.height, imgTexture.width, CvType.CV_8UC4);
Utils.texture2DToMat(imgTexture, imageMat);
// croppedImage = new Mat(1024/ 3, 1024 / 3, CvType.CV_8UC4);
texture2d = new Texture2D(foreImageSize, foreImageSize, TextureFormat.RGBA32, false);
renderer.material.mainTexture = texture2d;
outputMat0 = imageMat.clone();
rectCrop = new OpenCVForUnity.CoreModule.Rect(0, 0, foreImageSize, foreImageSize);
}
void OnGUI()
{
if (foreImage.GetComponent<DefaultTrackableEventHandler>().imageTargetIsFound && backImage.GetComponent<DefaultTrackableEventHandler>().imageTargetIsFound)
{
//獲得wood到road的轉換矩陣
Matrix4x4 Wood2Road = GetExtrinsic(backImage.transform).inverse * GetExtrinsic(foreImage.transform);
// cube.transform.position = new Vector3(Wood2Road.m03, Wood2Road.m13, Wood2Road.m23);
// cube.transform.rotation = newQ;
//其次獲得小碼圖像中心相對於大碼圖像中心的圖像座標,X向右,Z向上
// relativePosition = (new Vector3(Wood2Road.m03, Wood2Road.m13, Wood2Road.m23)) * 1024 / 0.3f;
offsetPixel_x = Wood2Road.m03 * 1024 / 0.3f;
offsetPixel_y = Wood2Road.m23 * 1024 / 0.3f;
//由於是左手座標系,此處的旋轉角度要取負值
Quaternion newQ = Quaternion.LookRotation(new Vector3(Wood2Road.m02, Wood2Road.m12, Wood2Road.m22), new Vector3(Wood2Road.m01, Wood2Road.m11, Wood2Road.m21));
relativeAngle = newQ.eulerAngles.y;
//先獲得右上角相對於圖像中心的座標,其餘各頂點的座標通過加正負號獲得
tr_x = 170 * Mathf.Cos(relativeAngle * Mathf.PI / 180) + 170 * Mathf.Sin(relativeAngle * Mathf.PI / 180);
tr_y = -170 * Mathf.Sin(relativeAngle * Mathf.PI / 180) + 170 * Mathf.Cos(relativeAngle * Mathf.PI / 180);
//獲得各頂點相對於大碼中心的圖像座標
// tr = new Vector2(relativePosition.x + tr_x, relativePosition.z + tr_y);
// tl = new Vector2(relativePosition.x - tr_y, relativePosition.z + tr_x);
// bl = new Vector2(relativePosition.x - tr_x, relativePosition.z - tr_y);
// br = new Vector2(relativePosition.x + tr_y, relativePosition.z - tr_x);
//將大碼的座標系從中心的X向右,Z向上,轉換成標準圖像座標系
tr.x = 512 + offsetPixel_x + tr_x;
tl.x = 512 + offsetPixel_x - tr_y;
bl.x = 512 + offsetPixel_x - tr_x;
br.x = 512 + offsetPixel_x + tr_y;
tr.y = 512 - offsetPixel_y - tr_y;
tl.y = 512 - offsetPixel_y - tr_x;
bl.y = 512 - offsetPixel_y + tr_y;
br.y = 512 - offsetPixel_y + tr_x;
srcRectMat.put(0, 0, bl.x, bl.y, br.x, br.y, tr.x, tr.y, tl.x, tl.y);
dstRectMat.put(0, 0, foreImageSize - 1, 0, 0, 0, 0, foreImageSize - 1, foreImageSize - 1, foreImageSize - 1);
Mat perspectiveTransform = Imgproc.getPerspectiveTransform(srcRectMat, dstRectMat);
//獲取放射變換後的全部圖像,隨後從中摳圖
Imgproc.warpPerspective(imageMat, outputMat0, perspectiveTransform, outputMat0.size());
croppedImage = new Mat(outputMat0, rectCrop);
//OpenCVForUnity.CoreModule.Rect rectCrop2 = new OpenCVForUnity.CoreModule.Rect(1024/3,1024/3, 1024 / 3, 1024 / 3); // 調試小心,超出取值範圍,unity會奔潰
// Mat croppedImage2 = new Mat(imageMat, rectCrop2);
Utils.matToTexture2D(croppedImage, texture2d);
}
}
Matrix4x4 rot = new Matrix4x4();
Matrix4x4 GetExtrinsic(Transform trans)
{
rot.SetTRS(trans.position, trans.rotation, new Vector3(1, 1, 1));
return rot;
}
}