#if !UNITY_WSA_10_0
using OpenCVForUnity.CoreModule;
using OpenCVForUnity.ImgprocModule;
using OpenCVForUnity.ObjdetectModule;
using OpenCVForUnity.UnityUtils;
using OpenCVForUnity.UnityUtils.Helper;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using Random = UnityEngine.Random;
namespace OpenCVForUnityExample
{
///
/// BarcodeDetector WebCam Example
/// An example of detecting Barcode in a image of WebCamTexture using the BarcodeDetector class.
/// https://github.com/opencv/opencv_contrib/blob/master/modules/barcode/samples/barcode.cpp
///
[RequireComponent(typeof(WebCamTextureToMatHelper))]
public class BarcodeDetectorWebCamExample : MonoBehaviour
{
///
/// The texture.
///
Texture2D texture;
///
/// The BarcodeDetector detector.
///
BarcodeDetector detector;
///
/// The webcam texture to mat helper.
///
WebCamTextureToMatHelper webCamTextureToMatHelper;
///
/// The FPS monitor.
///
FpsMonitor fpsMonitor;
// Use this for initialization
void Start()
{
fpsMonitor = GetComponent();
webCamTextureToMatHelper = gameObject.GetComponent();
detector = new BarcodeDetector();
// When using super resolution.
// Please, download 'sr.*' from https://github.com/WeChatCV/opencv_3rdparty/tree/wechat_qrcode and put them into the StreamingAssets/OpenCVForUnity/barcode directory.
//detector = new BarcodeDetector(Utils.getFilePath("OpenCVForUnity/barcode/sr.prototxt"), Utils.getFilePath("OpenCVForUnity/barcode/sr.caffemodel"));
#if UNITY_ANDROID && !UNITY_EDITOR
// Avoids the front camera low light issue that occurs in only some Android devices (e.g. Google Pixel, Pixel2).
webCamTextureToMatHelper.avoidAndroidFrontCameraLowLightIssue = true;
#endif
webCamTextureToMatHelper.Initialize();
}
///
/// Raises the web cam texture to mat helper initialized event.
///
public void OnWebCamTextureToMatHelperInitialized()
{
Debug.Log("OnWebCamTextureToMatHelperInitialized");
Mat webCamTextureMat = webCamTextureToMatHelper.GetMat();
texture = new Texture2D(webCamTextureMat.cols(), webCamTextureMat.rows(), TextureFormat.RGBA32, false);
Utils.matToTexture2D(webCamTextureMat, texture);
gameObject.GetComponent().material.mainTexture = texture;
gameObject.transform.localScale = new Vector3(webCamTextureMat.cols(), webCamTextureMat.rows(), 1);
Debug.Log("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation);
if (fpsMonitor != null)
{
fpsMonitor.Add("width", webCamTextureMat.width().ToString());
fpsMonitor.Add("height", webCamTextureMat.height().ToString());
fpsMonitor.Add("orientation", Screen.orientation.ToString());
}
float width = webCamTextureMat.width();
float height = webCamTextureMat.height();
float widthScale = (float)Screen.width / width;
float heightScale = (float)Screen.height / height;
if (widthScale < heightScale)
{
Camera.main.orthographicSize = (width * (float)Screen.height / (float)Screen.width) / 2;
}
else
{
Camera.main.orthographicSize = height / 2;
}
// If the WebCam is front facing, flip the Mat horizontally. Required for successful detection of Barcode.
if (webCamTextureToMatHelper.IsFrontFacing() && !webCamTextureToMatHelper.flipHorizontal)
{
webCamTextureToMatHelper.flipHorizontal = true;
}
else if (!webCamTextureToMatHelper.IsFrontFacing() && webCamTextureToMatHelper.flipHorizontal)
{
webCamTextureToMatHelper.flipHorizontal = false;
}
}
///
/// Raises the web cam texture to mat helper disposed event.
///
public void OnWebCamTextureToMatHelperDisposed()
{
Debug.Log("OnWebCamTextureToMatHelperDisposed");
if (texture != null)
{
Texture2D.Destroy(texture);
texture = null;
}
}
///
/// Raises the web cam texture to mat helper error occurred event.
///
/// Error code.
public void OnWebCamTextureToMatHelperErrorOccurred(WebCamTextureToMatHelper.ErrorCode errorCode)
{
Debug.Log("OnWebCamTextureToMatHelperErrorOccurred " + errorCode);
}
// Update is called once per frame
void Update()
{
if (webCamTextureToMatHelper.IsPlaying() && webCamTextureToMatHelper.DidUpdateThisFrame())
{
Mat rgbaMat = webCamTextureToMatHelper.GetMat();
List decoded_info = new List();
List decoded_type = new List();
Mat corners = new Mat();
bool result_detection = detector.detectAndDecodeWithType(rgbaMat, decoded_info, decoded_type, corners);
// draw Barcode contours.
if (result_detection)
DrawBarcodeResults(rgbaMat, corners, decoded_info, decoded_type);
corners.Dispose();
Utils.matToTexture2D(rgbaMat, texture);
}
}
private void DrawBarcodeResults(Mat frame, Mat corners, List decoded_info, List decoded_type)
{
if (!corners.empty())
{
using (Mat corners_32S = new Mat())
{
corners.convertTo(corners_32S, CvType.CV_32SC2);
for (int i = 0; i < corners_32S.rows(); i++)
{
using (Mat cornersMat_row = corners_32S.row(i))
using (MatOfPoint cornersMat = new MatOfPoint(cornersMat_row.reshape(2, 4)))
{
if (decoded_info.Count > i)
{
DrawBarcodeContour(frame, cornersMat, decoded_info[i], decoded_type[i]);
}
else
{
DrawBarcodeContour(frame, cornersMat);
}
}
if (decoded_info.Count > i)
{
if (!string.IsNullOrEmpty(decoded_info[i]))
{
Debug.Log("TYPE: " + decoded_type[i] + " INFO: " + decoded_info[i]);
}
else
{
Debug.Log("can't decode 1D barcode");
}
}
else
{
Debug.Log("decode information is not available (disabled)");
}
}
}
}
else
{
Debug.Log("Barcode is not detected");
}
}
private void DrawBarcodeContour(Mat color_image, MatOfPoint corners, string decoded_info = "", string decoded_type = "")
{
if (!corners.empty())
{
bool decodable = decoded_type != "";
double show_radius = (color_image.rows() > color_image.cols()) ? (2.813 * color_image.rows()) / color_image.cols() : (2.813 * color_image.cols()) / color_image.rows();
double contour_radius = show_radius * 0.4;
List barcode_contours = new List();
barcode_contours.Add(corners);
Imgproc.drawContours(color_image, barcode_contours, 0, decodable ? new Scalar(0, 255, 0, 255) : new Scalar(255, 0, 0, 255), Mathf.RoundToInt((float)contour_radius));
int[] p = new int[8];
corners.get(0, 0, p);
Imgproc.putText(color_image, decoded_info, new Point(p[0] + 5, p[1] - 25), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
Imgproc.putText(color_image, decoded_type, new Point(p[0] + 5, p[1] - 5), Imgproc.FONT_HERSHEY_SIMPLEX, 0.7, new Scalar(255, 255, 255, 255), 2, Imgproc.LINE_AA, false);
for (int i = 0; i < 8; i = i + 2)
{
Scalar color = new Scalar(Random.Range(0, 255), Random.Range(0, 255), Random.Range(0, 255), 255);
Imgproc.circle(color_image, new Point(p[i], p[i + 1]), Mathf.RoundToInt((float)contour_radius), color, -1);
}
}
}
///
/// Raises the destroy event.
///
void OnDestroy()
{
webCamTextureToMatHelper.Dispose();
if (detector != null)
detector.Dispose();
}
///
/// Raises the back button click event.
///
public void OnBackButtonClick()
{
SceneManager.LoadScene("OpenCVForUnityExample");
}
///
/// Raises the play button click event.
///
public void OnPlayButtonClick()
{
webCamTextureToMatHelper.Play();
}
///
/// Raises the pause button click event.
///
public void OnPauseButtonClick()
{
webCamTextureToMatHelper.Pause();
}
///
/// Raises the stop button click event.
///
public void OnStopButtonClick()
{
webCamTextureToMatHelper.Stop();
}
///
/// Raises the change camera button click event.
///
public void OnChangeCameraButtonClick()
{
webCamTextureToMatHelper.requestedIsFrontFacing = !webCamTextureToMatHelper.requestedIsFrontFacing;
}
}
}
#endif