https://github.com/google-ar/arcore-unity-sdk/releases/tag/v1.8.0 ③Unity2017.4.15f1 or later https://unity3d.com/jp/unity/qa/lts-releases?version=2017.4 ④Android SDK https://developer.android.com/studio ※Please finish setting up Android build on Unity before hand.
changed just by replacing texture file if a material to use texture was applied to3D model. 【Next Step】 Create texture from inner area of square frame. Writing C# script to replace texture automaticaly.
public RawImage viewL, viewR; UnityEngine.Rect capRect; Texture2D capTexture; Texture2D colTexture; Texture2D binTexture; void Start () { int w = Screen.width; int h = Screen.height; //Definition of capture region as (0,0) to (w,h) capRect = new UnityEngine.Rect(0, 0, w, h); //Creating texture image of the size of capRect capTexture = new Texture2D(w, h, TextureFormat.RGB24, false); } width height (0,0)
int w = Screen.width; int h = Screen.height; //Setting up position/size of ROI int sx = (int)(w * 0.2); //Start of X int sy = (int)(h * 0.3); //Start of Y w = (int)(w * 0.6); //Width of ROI h = (int)(h * 0.4); //Height of ROi //キャプチャする領域を保持したRectを作成 capRect = new UnityEngine.Rect(0, 0, w, h); capTexture = new Texture2D(w, h, TextureFormat.RGB24, false); } capRect = new UnityEngine.Rect(sx, sy, w, h); Replace!
//Mat:Format of image for OpenCV //bgr is for color image、bin is for binarized image Mat bgr, bin; void Start () { int w = Screen.width; int h = Screen.height; int sx = (int)(w * 0.2); int sy = (int)(h * 0.3); w = (int)(w * 0.6); h = (int)(h * 0.4); capRect = new UnityEngine.Rect(sx, sy, w, h); capTexture = new Texture2D(w, h, TextureFormat.RGB24, false); }
to Mat bgr = OpenCvSharp.Unity.TextureToMat(capTexture); //Conversion Color Image to Gray Scale Image bin = bgr.CvtColor(ColorConversionCodes.BGR2GRAY); //Binarization of image with Otsu’s method. bin = bin.Threshold(100, 255, ThresholdTypes.Otsu); Cv2.BitwiseNot(bin, bin); } Color Image Gray Scale Binary Inverse
return new WaitForEndOfFrame(); CreateImage(); ShowImage(); //Releasing Memories allocated for two Mats bgr.Release(); bin.Release(); canvas.SetActive(true); }
return new WaitForEndOfFrame(); CreateImage(); Point[] corners; //4 corners of square will be memorized FindRect(out corners); //Square Frame Detection ShowImage(); //画像の表示 bgr.Release(); bin.Release(); canvas.SetActive(true); } void FindRect(out Point[] corners) { /*Code will be described from next page.*/ }
and hierarchy Point[][] contours; HierarchyIndex[] h; //Contour detection bin.FindContours(out contours, out h, RetrievalModes.External, ContourApproximationModes.ApproxSimple); //Finding the contour of which has the most wide area. double maxArea = 0; for(int i = 0; i < contours.Length; i++) { double area = Cv2.ContourArea(contours[i]); if (area > maxArea) { maxArea = area; corners = contours[i]; } }
is omitted in this slide.*/ double maxArea = 0; for (int i = 0; i < contours.Length; i++) { double area = Cv2.ContourArea(contours[i]); if (area > maxArea) { maxArea = area; corners = contours[i]; } } //Write a contour line of max area in bgr. if (corners != null) { bgr.DrawContours( new Point[][] { corners }, 0, Scalar.Red, 5); } }
omitted in this slide.*/ if (corners != null) { bgr.DrawContours( new Point[][] { corners }, 0, Scalar.Red, 5); //Draw circle on the position of corner point. for(int i = 0; i < corners.Length; i++) { bgr.Circle(corners[i], 20, Scalar.Blue, 5); } } }
CreateImage(); Point[] corners; FindRect(out corners); TransformImage(corners); //Deform distorted square. ShowImage(); //画像の表示 bgr.Release(); bin.Release(); canvas.SetActive(true); } void TransformImage(Point[] corners) { /*Code will be described from the next page.*/ }
null) return; //Sorting SortCorners(corners); Point2f[] input = { corners[0], corners[1], corners[2], corners[3] }; Point2f[] square = { new Point2f(0, 0), new Point2f(0, 255), new Point2f(255, 255), new Point2f(255, 0) }; Mat transform = Cv2.GetPerspectiveTransform(input, square); Cv2.WarpPerspective(bgr,bgr,transform, new Size(256, 256)); } void SortCorners(Point[] corners) { /*Code of sorting is described in the next page.*/ }
{ if (corners == null) return; SortCorners(corners); Point2f[] input = { corners[0], corners[1], corners[2], corners[3] }; Point2f[] square = { new Point2f(0, 0), new Point2f(0, 255), new Point2f(255, 255), new Point2f(255, 0) }; Mat transform = Cv2.GetPerspectiveTransform(input, square); Cv2.WarpPerspective(bgr,bgr,transform, new Size(256, 256)); int s = (int)(256*0.05);//Line width of frame is 5% of square int w = (int)(256*0.9);//Width of clipping area is 90% of square OpenCvSharp.Rect innerRect = new OpenCvSharp.Rect(s, s, w, w); bgr = bgr[innerRect]; }