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;
}
}