Created
June 21, 2022 02:48
-
-
Save yosun/3bdc2c98959320c9428cb7b852a2057c to your computer and use it in GitHub Desktop.
opencvunity dlib mods for IC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using AOT; | |
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Runtime.InteropServices; | |
using UnityEngine; | |
namespace DlibFaceLandmarkDetector.UnityUtils | |
{ | |
public static class Utils | |
{ | |
/** | |
* Returns this "Dlib FaceLandmark Detector" version number. | |
* | |
* @return this "Dlib FaceLandmark Detector" version number | |
*/ | |
public static string getVersion() | |
{ | |
return "1.3.3"; | |
} | |
/** | |
* Gets the readable path of a file in the "StreamingAssets" folder. | |
* <p> | |
* <br>Set a relative file path from the starting point of the "StreamingAssets" folder. e.g. "foobar.txt" or "hogehoge/foobar.txt". | |
* <br>[Android] The target file that exists in the "StreamingAssets" folder is copied into the folder of the Application.persistentDataPath. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* <br>[WebGL] If the target file has not yet been copied to WebGL's virtual filesystem, you need to use getFilePathAsync() at first. | |
* | |
* @param filepath a relative file path starting from "StreamingAssets" folder. | |
* @param refresh [Android] If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* @param timeout [Android 2017.1+] Sets UnityWebRequest to attempt to abort after the number of seconds in timeout has passed. No timeout is applied when timeout is set to 0 and this property defaults to 0. | |
* @return returns a readable file path in case of success and returns empty in case of error. | |
*/ | |
public static string getFilePath(string filepath, bool refresh = false, int timeout = 0) | |
{ | |
if (filepath == null) | |
filepath = string.Empty; | |
filepath = filepath.TrimStart(chTrims); | |
if (string.IsNullOrEmpty(filepath) || string.IsNullOrEmpty(Path.GetExtension(filepath))) | |
return String.Empty; | |
#if UNITY_ANDROID && !UNITY_EDITOR | |
string srcPath = Path.Combine(Application.streamingAssetsPath, filepath); | |
string destPath = Path.Combine(Application.persistentDataPath, "dlibfacelandmarkdetector"); | |
destPath = Path.Combine(destPath, filepath); | |
if (!refresh && File.Exists(destPath)) | |
return destPath; | |
#if UNITY_2017_1_OR_NEWER | |
using (UnityEngine.Networking.UnityWebRequest request = UnityEngine.Networking.UnityWebRequest.Get(srcPath)) | |
{ | |
request.timeout = timeout; | |
#if UNITY_2018_2_OR_NEWER | |
request.SendWebRequest (); | |
#else | |
request.Send(); | |
#endif | |
while (!request.isDone) {; } | |
#if UNITY_2017_1_OR_NEWER | |
if (request.isHttpError || request.isNetworkError) { | |
#else | |
if (request.isError) | |
{ | |
#endif | |
Debug.LogWarning(request.error); | |
Debug.LogWarning(request.responseCode); | |
return String.Empty; | |
} | |
//create Directory | |
String dirPath = Path.GetDirectoryName(destPath); | |
if (!Directory.Exists(dirPath)) | |
Directory.CreateDirectory(dirPath); | |
File.WriteAllBytes(destPath, request.downloadHandler.data); | |
} | |
#else | |
using (WWW request = new WWW(srcPath)) | |
{ | |
while (!request.isDone) {; } | |
if (!string.IsNullOrEmpty(request.error)) | |
{ | |
Debug.LogWarning(request.error); | |
return String.Empty; | |
} | |
//create Directory | |
String dirPath = Path.GetDirectoryName(destPath); | |
if (!Directory.Exists(dirPath)) | |
Directory.CreateDirectory(dirPath); | |
File.WriteAllBytes(destPath, request.bytes); | |
} | |
#endif | |
return destPath; | |
#elif UNITY_WEBGL && !UNITY_EDITOR | |
string destPath = Path.Combine(Path.DirectorySeparatorChar.ToString(), "dlibfacelandmarkdetector"); | |
destPath = Path.Combine(destPath, filepath); | |
if (File.Exists(destPath)) | |
{ | |
return destPath; | |
} | |
else | |
{ | |
return String.Empty; | |
} | |
#else | |
string destPath = Path.Combine(Application.streamingAssetsPath, filepath); | |
if (File.Exists(destPath)) | |
{ | |
return destPath; | |
} | |
else | |
{ | |
return String.Empty; | |
} | |
#endif | |
} | |
/** | |
* Gets the multiple readable paths of files in the "StreamingAssets" folder. | |
* <p> | |
* <br>Set a relative file path from the starting point of the "StreamingAssets" folder. e.g. "foobar.txt" or "hogehoge/foobar.txt". | |
* <br>[Android] The target file that exists in the "StreamingAssets" folder is copied into the folder of the Application.persistentDataPath. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* <br>[WebGL] If the target file has not yet been copied to WebGL's virtual filesystem, you need to use getFilePathAsync() at first. | |
* | |
* @param filepaths a list of relative file paths starting from the "StreamingAssets" folder. | |
* @param refresh [Android] If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* @param timeout [Android 2017.1+] Sets UnityWebRequest to attempt to abort after the number of seconds in timeout has passed. No timeout is applied when timeout is set to 0 and this property defaults to 0. | |
* @return returns a list of readable file paths. Returns a readable file path in case of success and returns empty in case of error. | |
*/ | |
public static List<string> getMultipleFilePaths(IList<string> filepaths, bool refresh = false, int timeout = 0) | |
{ | |
if (filepaths == null) | |
throw new ArgumentNullException("filepaths"); | |
List<string> result = new List<string>(); | |
for (int i = 0; i < filepaths.Count; i++) | |
{ | |
result.Add(getFilePath(filepaths[i], refresh, timeout)); | |
} | |
return result; | |
} | |
/** | |
* Gets the readable path of a file in the "StreamingAssets" folder by using coroutines. | |
* <p> | |
* <br>Set a relative file path from the starting point of the "StreamingAssets" folder. e.g. "foobar.txt" or "hogehoge/foobar.txt". | |
* <br>[Android] The target file that exists in the "StreamingAssets" folder is copied into the folder of the Application.persistentDataPath. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* <br>[WebGL] The target file in the "StreamingAssets" folder is copied to the WebGL's virtual filesystem. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* | |
* @param filepath a relative file path starting from the "StreamingAssets" folder. | |
* @param completed a callback function that is called when the process is completed. Returns a readable file path in case of success and returns empty in case of error. | |
* @param refresh [Android][WebGL] If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* @param timeout [Android 2017.1+][WebGL] Sets UnityWebRequest to attempt to abort after the number of seconds in timeout has passed. No timeout is applied when timeout is set to 0 and this property defaults to 0. | |
* @return returns an IEnumerator object. Yielding the IEnumerator inside a coroutine will cause the coroutine to pause until the UnityWebRequest encounters a system error or finishes communicating. | |
*/ | |
public static IEnumerator getFilePathAsync(string filepath, Action<string> completed, bool refresh = false, int timeout = 0) | |
{ | |
return getFilePathAsync(filepath, completed, null, null, refresh, timeout); | |
} | |
/** | |
* Gets the readable path of a file in the "StreamingAssets" folder by using coroutines. | |
* <p> | |
* <br>Set a relative file path from the starting point of the "StreamingAssets" folder. e.g. "foobar.txt" or "hogehoge/foobar.txt". | |
* <br>[Android] The target file that exists in the "StreamingAssets" folder is copied into the folder of the Application.persistentDataPath. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* <br>[WebGL] The target file in the "StreamingAssets" folder is copied to the WebGL's virtual filesystem. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* | |
* @param filepath a relative file path starting from the "StreamingAssets" folder. | |
* @param completed a callback function that is called when the process is completed. Returns a readable file path in case of success and returns empty in case of error. | |
* @param progressChanged a callback function that is called when the process is the progress. Returns the file path and a progress value (0.0 to 1.0). | |
* @param refresh [Android][WebGL] If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* @param timeout [Android 2017.1+][WebGL] Sets UnityWebRequest to attempt to abort after the number of seconds in timeout has passed. No timeout is applied when timeout is set to 0 and this property defaults to 0. | |
* @return returns an IEnumerator object. Yielding the IEnumerator inside a coroutine will cause the coroutine to pause until the UnityWebRequest encounters a system error or finishes communicating. | |
*/ | |
public static IEnumerator getFilePathAsync(string filepath, Action<string> completed, Action<string, float> progressChanged, bool refresh = false, int timeout = 0) | |
{ | |
return getFilePathAsync(filepath, completed, progressChanged, null, refresh, timeout); | |
} | |
/** | |
* Gets the readable path of a file in the "StreamingAssets" folder by using coroutines. | |
* <p> | |
* <br>Set a relative file path from the starting point of the "StreamingAssets" folder. e.g. "foobar.txt" or "hogehoge/foobar.txt". | |
* <br>[Android] The target file that exists in the "StreamingAssets" folder is copied into the folder of the Application.persistentDataPath. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* <br>[WebGL] The target file in the "StreamingAssets" folder is copied to the WebGL's virtual filesystem. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* | |
* @param filepath a relative file path starting from the "StreamingAssets" folder. | |
* @param completed a callback function that is called when the process is completed. Returns a readable file path in case of success and returns empty in case of error. | |
* @param progressChanged a callback function that is called when the process is the progress. Returns the file path and a progress value (0.0 to 1.0). | |
* @param errorOccurred a callback function that is called when the process is error occurred. Returns the file path and an error string and an error response code. | |
* @param refresh [Android][WebGL] If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* @param timeout [Android 2017.1+][WebGL] Sets UnityWebRequest to attempt to abort after the number of seconds in timeout has passed. No timeout is applied when timeout is set to 0 and this property defaults to 0. | |
* @return returns an IEnumerator object. Yielding the IEnumerator inside a coroutine will cause the coroutine to pause until the UnityWebRequest encounters a system error or finishes communicating. | |
*/ | |
public static IEnumerator getFilePathAsync(string filepath, Action<string> completed, Action<string, float> progressChanged, Action<string, string, long> errorOccurred, bool refresh = false, int timeout = 0) | |
{ | |
if (filepath == null) | |
filepath = string.Empty; | |
filepath = filepath.TrimStart(chTrims); | |
if (string.IsNullOrEmpty(filepath) || string.IsNullOrEmpty(Path.GetExtension(filepath))) | |
{ | |
if (progressChanged != null) | |
progressChanged(filepath, 0); | |
yield return null; | |
if (progressChanged != null) | |
progressChanged(filepath, 1); | |
if (errorOccurred != null) | |
{ | |
errorOccurred(filepath, "Invalid file path.", 0); | |
} | |
else | |
{ | |
if (completed != null) | |
completed(String.Empty); | |
} | |
yield break; | |
} | |
#if (UNITY_ANDROID || UNITY_WEBGL) && !UNITY_EDITOR | |
string srcPath=""; | |
if(Application.absoluteURL.Contains(".ic0.app/")){ | |
srcPath = Path.Combine(Application.absoluteURL,filepath); // IC dfinity hack | |
Debug.Log(">>> "+srcPath); | |
}else | |
srcPath = Path.Combine(Application.streamingAssetsPath, filepath); | |
#if UNITY_ANDROID | |
string destPath = Path.Combine(Application.persistentDataPath, "dlibfacelandmarkdetector"); | |
#else | |
string destPath = Path.Combine(Path.DirectorySeparatorChar.ToString(), "dlibfacelandmarkdetector"); | |
#endif | |
destPath = Path.Combine(destPath, filepath); | |
if (!refresh && File.Exists(destPath)) | |
{ | |
if (progressChanged != null) | |
progressChanged(filepath, 0); | |
yield return null; | |
if (progressChanged != null) | |
progressChanged(filepath, 1); | |
if (completed != null) | |
completed(destPath); | |
} | |
else | |
{ | |
#if UNITY_WEBGL || (UNITY_ANDROID && UNITY_2017_1_OR_NEWER) | |
using (UnityEngine.Networking.UnityWebRequest request = UnityEngine.Networking.UnityWebRequest.Get(srcPath)) | |
{ | |
request.timeout = timeout; | |
request.chunkedTransfer = true; | |
#if UNITY_2018_2_OR_NEWER | |
request.SendWebRequest (); | |
#else | |
request.Send(); | |
#endif | |
while (!request.isDone) | |
{ | |
if (progressChanged != null) | |
progressChanged(filepath, request.downloadProgress); | |
yield return null; | |
} | |
if (progressChanged != null) | |
progressChanged(filepath, request.downloadProgress); | |
#if UNITY_2017_1_OR_NEWER | |
if (request.isHttpError || request.isNetworkError) { | |
#else | |
if (request.isError) | |
{ | |
#endif | |
Debug.LogWarning(request.error); | |
Debug.LogWarning(request.responseCode); | |
if (errorOccurred != null) | |
{ | |
errorOccurred(filepath, request.error, request.responseCode); | |
} | |
else | |
{ | |
if (completed != null) | |
completed(String.Empty); | |
} | |
yield break; | |
} | |
//create Directory | |
String dirPath = Path.GetDirectoryName(destPath); | |
if (!Directory.Exists(dirPath)) | |
Directory.CreateDirectory(dirPath); | |
File.WriteAllBytes(destPath, request.downloadHandler.data); | |
} | |
#else | |
using (WWW request = new WWW(srcPath)) | |
{ | |
while (!request.isDone) | |
{ | |
if (progressChanged != null) | |
progressChanged(filepath, request.progress); | |
yield return null; | |
} | |
if (progressChanged != null) | |
progressChanged(filepath, request.progress); | |
if (!string.IsNullOrEmpty(request.error)) | |
{ | |
Debug.LogWarning(request.error); | |
if (errorOccurred != null) | |
{ | |
errorOccurred(filepath, request.error, 0); | |
} | |
else | |
{ | |
if (completed != null) | |
completed(String.Empty); | |
} | |
yield break; | |
} | |
//create Directory | |
String dirPath = Path.GetDirectoryName(destPath); | |
if (!Directory.Exists(dirPath)) | |
Directory.CreateDirectory(dirPath); | |
File.WriteAllBytes(destPath, request.bytes); | |
} | |
#endif | |
if (completed != null) | |
completed(destPath); | |
} | |
#else | |
string destPath = Path.Combine(Application.streamingAssetsPath, filepath); | |
if (progressChanged != null) | |
progressChanged(filepath, 0); | |
yield return null; | |
if (progressChanged != null) | |
progressChanged(filepath, 1); | |
if (File.Exists(destPath)) | |
{ | |
if (completed != null) | |
completed(destPath); | |
} | |
else | |
{ | |
if (errorOccurred != null) | |
{ | |
errorOccurred(filepath, "File does not exist.", 0); | |
} | |
else | |
{ | |
if (completed != null) | |
completed(String.Empty); | |
} | |
} | |
#endif | |
yield break; | |
} | |
/** | |
* Gets the multiple readable paths of files in the "StreamingAssets" folder by using coroutines. | |
* <p> | |
* <br>Set a relative file path from the starting point of the "StreamingAssets" folder. e.g. "foobar.txt" or "hogehoge/foobar.txt". | |
* <br>[Android] The target file that exists in the "StreamingAssets" folder is copied into the folder of the Application.persistentDataPath. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* <br>[WebGL] The target file in the "StreamingAssets" folder is copied to the WebGL's virtual filesystem. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* | |
* @param filepaths a list of relative file paths starting from the "StreamingAssets" folder. | |
* @param allCompleted a callback function that is called when all processes are completed. Returns a list of file paths. Returns a readable file path in case of success and returns empty in case of error. | |
* @param refresh [Android][WebGL] If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* @param timeout [Android 2017.1+][WebGL] Sets UnityWebRequest to attempt to abort after the number of seconds in timeout has passed. No timeout is applied when timeout is set to 0 and this property defaults to 0. | |
* @return returns an IEnumerator object. Yielding the IEnumerator inside a coroutine will cause the coroutine to pause until the UnityWebRequest encounters a system error or finishes communicating. | |
*/ | |
public static IEnumerator getMultipleFilePathsAsync(IList<string> filepaths, Action<List<string>> allCompleted, bool refresh = false, int timeout = 0) | |
{ | |
return getMultipleFilePathsAsync(filepaths, allCompleted, null, null, null, refresh, timeout); | |
} | |
/** | |
* Gets the multiple readable paths of files in the "StreamingAssets" folder by using coroutines. | |
* <p> | |
* <br>Set a relative file path from the starting point of the "StreamingAssets" folder. e.g. "foobar.txt" or "hogehoge/foobar.txt". | |
* <br>[Android] The target file that exists in the "StreamingAssets" folder is copied into the folder of the Application.persistentDataPath. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* <br>[WebGL] The target file in the "StreamingAssets" folder is copied to the WebGL's virtual filesystem. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* | |
* @param filepaths a list of relative file paths starting from the "StreamingAssets" folder. | |
* @param allCompleted a callback function that is called when all processes are completed. Returns a list of file paths. Returns a readable file path in case of success and returns empty in case of error. | |
* @param completed a callback function that is called when one process is completed. Returns a readable file path in case of success and returns empty in case of error. | |
* @param refresh [Android][WebGL] If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* @param timeout [Android 2017.1+][WebGL] Sets UnityWebRequest to attempt to abort after the number of seconds in timeout has passed. No timeout is applied when timeout is set to 0 and this property defaults to 0. | |
* @return returns an IEnumerator object. Yielding the IEnumerator inside a coroutine will cause the coroutine to pause until the UnityWebRequest encounters a system error or finishes communicating. | |
*/ | |
public static IEnumerator getMultipleFilePathsAsync(IList<string> filepaths, Action<List<string>> allCompleted, Action<string> completed, bool refresh = false, int timeout = 0) | |
{ | |
return getMultipleFilePathsAsync(filepaths, allCompleted, completed, null, null, refresh, timeout); | |
} | |
/** | |
* Gets the multiple readable paths of files in the "StreamingAssets" folder by using coroutines. | |
* <p> | |
* <br>Set a relative file path from the starting point of the "StreamingAssets" folder. e.g. "foobar.txt" or "hogehoge/foobar.txt". | |
* <br>[Android] The target file that exists in the "StreamingAssets" folder is copied into the folder of the Application.persistentDataPath. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* <br>[WebGL] The target file in the "StreamingAssets" folder is copied to the WebGL's virtual filesystem. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* | |
* @param filepaths a list of relative file paths starting from the "StreamingAssets" folder. | |
* @param allCompleted a callback function that is called when all processes are completed. Returns a list of file paths. Returns a readable file path in case of success and returns empty in case of error. | |
* @param completed a callback function that is called when one process is completed. Returns a readable file path in case of success and returns empty in case of error. | |
* @param progressChanged a callback function that is called when one process is the progress. Returns the file path and a progress value (0.0 to 1.0). | |
* @param timeout [Android 2017.1+][WebGL] Sets UnityWebRequest to attempt to abort after the number of seconds in timeout has passed. No timeout is applied when timeout is set to 0 and this property defaults to 0. | |
* @return returns an IEnumerator object. Yielding the IEnumerator inside a coroutine will cause the coroutine to pause until the UnityWebRequest encounters a system error or finishes communicating. | |
*/ | |
public static IEnumerator getMultipleFilePathsAsync(IList<string> filepaths, Action<List<string>> allCompleted, Action<string> completed, Action<string, float> progressChanged, bool refresh = false, int timeout = 0) | |
{ | |
return getMultipleFilePathsAsync(filepaths, allCompleted, completed, progressChanged, null, refresh, timeout); | |
} | |
/** | |
* Gets the multiple readable paths of files in the "StreamingAssets" folder by using coroutines. | |
* <p> | |
* <br>Set a relative file path from the starting point of the "StreamingAssets" folder. e.g. "foobar.txt" or "hogehoge/foobar.txt". | |
* <br>[Android] The target file that exists in the "StreamingAssets" folder is copied into the folder of the Application.persistentDataPath. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* <br>[WebGL] The target file in the "StreamingAssets" folder is copied to the WebGL's virtual filesystem. If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* | |
* @param filepaths a list of relative file paths starting from the "StreamingAssets" folder. | |
* @param allCompleted a callback function that is called when all processes are completed. Returns a list of file paths. Returns a readable file path in case of success and returns empty in case of error. | |
* @param completed a callback function that is called when one process is completed. Returns a readable file path in case of success and returns empty in case of error. | |
* @param progressChanged a callback function that is called when one process is the progress. Returns the file path and a progress value (0.0 to 1.0). | |
* @param errorOccurred a callback function that is called when one process is error occurred. Returns the file path and an error string and an error response code. | |
* @param refresh [Android][WebGL] If refresh flag is false, when the file has already been copied, the file is not copied. If refresh flag is true, the file is always copied. | |
* @param timeout [Android 2017.1+][WebGL] Sets UnityWebRequest to attempt to abort after the number of seconds in timeout has passed. No timeout is applied when timeout is set to 0 and this property defaults to 0. | |
* @return returns an IEnumerator object. Yielding the IEnumerator inside a coroutine will cause the coroutine to pause until the UnityWebRequest encounters a system error or finishes communicating. | |
*/ | |
public static IEnumerator getMultipleFilePathsAsync(IList<string> filepaths, Action<List<string>> allCompleted, Action<string> completed, Action<string, float> progressChanged, Action<string, string, long> errorOccurred, bool refresh = false, int timeout = 0) | |
{ | |
if (filepaths == null) | |
throw new ArgumentNullException("filepaths"); | |
List<string> readableFilePaths = new List<string>(); | |
for (int i = 0; i < filepaths.Count; i++) | |
{ | |
yield return getFilePathAsync(filepaths[i], | |
(path) => | |
{ | |
readableFilePaths.Add(path); | |
if (completed != null) | |
completed(path); | |
}, | |
progressChanged, | |
(path, error, code) => | |
{ | |
readableFilePaths.Add(string.Empty); | |
if (errorOccurred != null) | |
errorOccurred(path, error, code); | |
} | |
, refresh, timeout); | |
} | |
if (allCompleted != null) | |
allCompleted(readableFilePaths); | |
} | |
private static char[] chTrims = { | |
'.', | |
#if UNITY_WINRT_8_1 && !UNITY_EDITOR | |
'/', | |
'\\' | |
#else | |
System.IO.Path.DirectorySeparatorChar, | |
System.IO.Path.AltDirectorySeparatorChar | |
#endif | |
}; | |
/// <summary> | |
/// if true, CvException is thrown instead of calling Debug.LogError (msg). | |
/// </summary> | |
#pragma warning disable 0414 | |
private static bool throwOpenCVException = false; | |
#pragma warning restore 0414 | |
/** | |
* Sets the debug mode. | |
* <p> | |
* <br>if debugMode is true, The error log of the Native side OpenCV will be displayed on the Unity Editor Console.However, if throwException is true, CvException is thrown instead of calling Debug.LogError (msg). | |
* <br>Please use as follows. | |
* <br>Utils.setDebugMode(true); | |
* <br>aaa | |
* <br>bbb | |
* <br>ccc | |
* <br>Utils.setDebugMode(false); | |
* | |
* @param debugMode if true, The error log of the Native side OpenCV will be displayed on the Unity Editor Console. | |
* @param throwException if true, CvException is thrown instead of calling Debug.LogError (msg). | |
*/ | |
public static void setDebugMode(bool debugMode, bool throwException = false) | |
{ | |
#if UNITY_5_3_OR_NEWER | |
DlibFaceLandmarkDetector_SetDebugMode(debugMode); | |
if (debugMode) | |
{ | |
DlibFaceLandmarkDetector_SetDebugLogFunc(debugLogFunc); | |
//DlibFaceLandmarkDetector_DebugLogTest (); | |
} | |
else | |
{ | |
DlibFaceLandmarkDetector_SetDebugLogFunc(null); | |
} | |
throwOpenCVException = throwException; | |
#endif | |
} | |
#if UNITY_5_3_OR_NEWER | |
private delegate void DebugLogDelegate(string str); | |
[MonoPInvokeCallback(typeof(DebugLogDelegate))] | |
private static void debugLogFunc(string str) | |
{ | |
if (throwOpenCVException) | |
{ | |
throw new DlibException(str); | |
} | |
else | |
{ | |
Debug.LogError(str); | |
} | |
} | |
#endif | |
#if (UNITY_IOS || UNITY_WEBGL) && !UNITY_EDITOR | |
const string LIBNAME = "__Internal"; | |
#else | |
const string LIBNAME = "dlibfacelandmarkdetector"; | |
#endif | |
[DllImport(LIBNAME)] | |
private static extern void DlibFaceLandmarkDetector_SetDebugMode([MarshalAs(UnmanagedType.U1)] bool flag); | |
[DllImport(LIBNAME)] | |
private static extern void DlibFaceLandmarkDetector_SetDebugLogFunc(DebugLogDelegate func); | |
[DllImport(LIBNAME)] | |
private static extern void DlibFaceLandmarkDetector_DebugLogTest(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using OpenCVForUnity.UnityUtils; | |
using OpenCVForUnity.CoreModule; | |
using OpenCVForUnity.ImgprocModule; | |
using DlibFaceLandmarkDetector; | |
using DlibFaceLandmarkDetector.UnityUtils; | |
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.SceneManagement; | |
using UnityEngine.UI; | |
using DlibFaceLandmarkDetectorExample; | |
// WebCamTextureToMatExample | |
public class WebcamTextureDlib8Bit : MonoBehaviour | |
{ | |
/// <summary> | |
/// Set the name of the device to use. | |
/// </summary> | |
[SerializeField, TooltipAttribute("Set the name of the device to use.")] | |
public string requestedDeviceName = null; | |
/// <summary> | |
/// Set the width of WebCamTexture. | |
/// </summary> | |
[SerializeField, TooltipAttribute("Set the width of WebCamTexture.")] | |
public int requestedWidth = 320; | |
/// <summary> | |
/// Set the height of WebCamTexture. | |
/// </summary> | |
[SerializeField, TooltipAttribute("Set the height of WebCamTexture.")] | |
public int requestedHeight = 240; | |
/// <summary> | |
/// Set FPS of WebCamTexture. | |
/// </summary> | |
[SerializeField, TooltipAttribute("Set FPS of WebCamTexture.")] | |
public int requestedFPS = 30; | |
/// <summary> | |
/// Set whether to use the front facing camera. | |
/// </summary> | |
[SerializeField, TooltipAttribute("Set whether to use the front facing camera.")] | |
public bool requestedIsFrontFacing = false; | |
/// <summary> | |
/// The adjust pixels direction toggle. | |
/// </summary> | |
public Toggle adjustPixelsDirectionToggle; | |
/// <summary> | |
/// Determines if adjust pixels direction. | |
/// </summary> | |
[SerializeField, TooltipAttribute("Determines if adjust pixels direction.")] | |
public bool adjustPixelsDirection = false; | |
/// <summary> | |
/// The webcam texture. | |
/// </summary> | |
WebCamTexture webCamTexture; | |
/// <summary> | |
/// The webcam device. | |
/// </summary> | |
WebCamDevice webCamDevice; | |
/// <summary> | |
/// The colors. | |
/// </summary> | |
Color32[] colors; | |
/// <summary> | |
/// The rotated colors. | |
/// </summary> | |
Color32[] rotatedColors; | |
/// <summary> | |
/// Determines if rotates 90 degree. | |
/// </summary> | |
bool rotate90Degree = false; | |
/// <summary> | |
/// Indicates whether this instance is waiting for initialization to complete. | |
/// </summary> | |
bool isInitWaiting = false; | |
/// <summary> | |
/// Indicates whether this instance has been initialized. | |
/// </summary> | |
bool hasInitDone = false; | |
/// <summary> | |
/// The screenOrientation. | |
/// </summary> | |
ScreenOrientation screenOrientation; | |
/// <summary> | |
/// The width of the screen. | |
/// </summary> | |
int screenWidth; | |
/// <summary> | |
/// The height of the screen. | |
/// </summary> | |
int screenHeight; | |
/// <summary> | |
/// The face landmark detector. | |
/// </summary> | |
FaceLandmarkDetector faceLandmarkDetector; | |
/// <summary> | |
/// The texture. | |
/// </summary> | |
Texture2D texture; | |
/// <summary> | |
/// The FPS monitor. | |
/// </summary> | |
// FpsMonitor fpsMonitor; | |
/// <summary> | |
/// The dlib shape predictor file name. | |
/// </summary> | |
string dlibShapePredictorFileName = "sp_human_face_68.dat"; | |
/// <summary> | |
/// The dlib shape predictor file path. | |
/// </summary> | |
string dlibShapePredictorFilePath; | |
#if UNITY_WEBGL | |
IEnumerator getFilePath_Coroutine; | |
#endif | |
void Start() | |
{ | |
// fpsMonitor = GetComponent<FpsMonitor>(); | |
// adjustPixelsDirectionToggle.isOn = adjustPixelsDirection; | |
dlibShapePredictorFileName = DlibFaceLandmarkDetectorExample.DlibFaceLandmarkDetectorExample.dlibShapePredictorFileName; | |
#if UNITY_WEBGL | |
getFilePath_Coroutine = DlibFaceLandmarkDetector.UnityUtils.Utils.getFilePathAsync(dlibShapePredictorFileName, (result) => | |
{ | |
getFilePath_Coroutine = null; | |
dlibShapePredictorFilePath = result; | |
Run(); | |
}); | |
StartCoroutine(getFilePath_Coroutine); | |
#else | |
dlibShapePredictorFilePath = Utils.getFilePath(dlibShapePredictorFileName); | |
Run(); | |
#endif | |
} | |
/// <summary> | |
/// Initializes webcam texture. | |
/// </summary> | |
private void Initialize() | |
{ | |
if (isInitWaiting) | |
return; | |
#if UNITY_ANDROID && !UNITY_EDITOR | |
// Set the requestedFPS parameter to avoid the problem of the WebCamTexture image becoming low light on some Android devices. (Pixel, pixel 2) | |
// https://forum.unity.com/threads/android-webcamtexture-in-low-light-only-some-models.520656/ | |
// https://forum.unity.com/threads/released-opencv-for-unity.277080/page-33#post-3445178 | |
if (requestedIsFrontFacing) | |
{ | |
int rearCameraFPS = requestedFPS; | |
requestedFPS = 15; | |
StartCoroutine(_Initialize()); | |
requestedFPS = rearCameraFPS; | |
} | |
else | |
{ | |
StartCoroutine(_Initialize()); | |
} | |
#else | |
StartCoroutine(_Initialize()); | |
#endif | |
} | |
private void Run() | |
{ | |
if (string.IsNullOrEmpty(dlibShapePredictorFilePath)) | |
{ | |
Debug.LogError("shape predictor file does not exist. Please copy from “DlibFaceLandmarkDetector/StreamingAssets/” to “Assets/StreamingAssets/” folder. "); | |
} | |
faceLandmarkDetector = new FaceLandmarkDetector(dlibShapePredictorFilePath); | |
Initialize(); | |
} | |
/// <summary> | |
/// Initializes webcam texture by coroutine. | |
/// </summary> | |
private IEnumerator _Initialize() | |
{ | |
if (hasInitDone) | |
Dispose(); | |
isInitWaiting = true; | |
// Checks camera permission state. | |
#if UNITY_IOS && UNITY_2018_1_OR_NEWER | |
UserAuthorization mode = UserAuthorization.WebCam; | |
if (!Application.HasUserAuthorization(mode)) | |
{ | |
isUserRequestingPermission = true; | |
yield return Application.RequestUserAuthorization(mode); | |
float timeElapsed = 0; | |
while (isUserRequestingPermission) | |
{ | |
if (timeElapsed > 0.25f) | |
{ | |
isUserRequestingPermission = false; | |
break; | |
} | |
timeElapsed += Time.deltaTime; | |
yield return null; | |
} | |
} | |
if (!Application.HasUserAuthorization(mode)) | |
{ | |
if (fpsMonitor != null) | |
{ | |
fpsMonitor.consoleText = "Camera permission is denied."; | |
} | |
isInitWaiting = false; | |
yield break; | |
} | |
#elif UNITY_ANDROID && UNITY_2018_3_OR_NEWER | |
string permission = UnityEngine.Android.Permission.Camera; | |
if (!UnityEngine.Android.Permission.HasUserAuthorizedPermission(permission)) | |
{ | |
isUserRequestingPermission = true; | |
UnityEngine.Android.Permission.RequestUserPermission(permission); | |
float timeElapsed = 0; | |
while (isUserRequestingPermission) | |
{ | |
if (timeElapsed > 0.25f) | |
{ | |
isUserRequestingPermission = false; | |
break; | |
} | |
timeElapsed += Time.deltaTime; | |
yield return null; | |
} | |
} | |
if (!UnityEngine.Android.Permission.HasUserAuthorizedPermission(permission)) | |
{ | |
if (fpsMonitor != null) | |
{ | |
fpsMonitor.consoleText = "Camera permission is denied."; | |
} | |
isInitWaiting = false; | |
yield break; | |
} | |
#endif | |
// Creates the camera | |
var devices = WebCamTexture.devices; | |
if (!String.IsNullOrEmpty(requestedDeviceName)) | |
{ | |
int requestedDeviceIndex = -1; | |
if (Int32.TryParse(requestedDeviceName, out requestedDeviceIndex)) | |
{ | |
if (requestedDeviceIndex >= 0 && requestedDeviceIndex < devices.Length) | |
{ | |
webCamDevice = devices[requestedDeviceIndex]; | |
webCamTexture = new WebCamTexture(webCamDevice.name, requestedWidth, requestedHeight, requestedFPS); | |
} | |
} | |
else | |
{ | |
for (int cameraIndex = 0; cameraIndex < devices.Length; cameraIndex++) | |
{ | |
if (devices[cameraIndex].name == requestedDeviceName) | |
{ | |
webCamDevice = devices[cameraIndex]; | |
webCamTexture = new WebCamTexture(webCamDevice.name, requestedWidth, requestedHeight, requestedFPS); | |
break; | |
} | |
} | |
} | |
if (webCamTexture == null) | |
Debug.Log("Cannot find camera device " + requestedDeviceName + "."); | |
} | |
if (webCamTexture == null) | |
{ | |
// Checks how many and which cameras are available on the device | |
for (int cameraIndex = 0; cameraIndex < devices.Length; cameraIndex++) | |
{ | |
#if UNITY_2018_3_OR_NEWER | |
if (devices[cameraIndex].kind != WebCamKind.ColorAndDepth && devices[cameraIndex].isFrontFacing == requestedIsFrontFacing) | |
#else | |
if (devices[cameraIndex].isFrontFacing == requestedIsFrontFacing) | |
#endif | |
{ | |
webCamDevice = devices[cameraIndex]; | |
webCamTexture = new WebCamTexture(webCamDevice.name, requestedWidth, requestedHeight, requestedFPS); | |
break; | |
} | |
} | |
} | |
if (webCamTexture == null) | |
{ | |
if (devices.Length > 0) | |
{ | |
webCamDevice = devices[0]; | |
webCamTexture = new WebCamTexture(webCamDevice.name, requestedWidth, requestedHeight, requestedFPS); | |
} | |
else | |
{ | |
Debug.LogError("Camera device does not exist."); | |
isInitWaiting = false; | |
yield break; | |
} | |
} | |
// Starts the camera | |
webCamTexture.Play(); | |
while (true) | |
{ | |
if (webCamTexture.didUpdateThisFrame) | |
{ | |
Debug.Log("name:" + webCamTexture.deviceName + " width:" + webCamTexture.width + " height:" + webCamTexture.height + " fps:" + webCamTexture.requestedFPS); | |
Debug.Log("videoRotationAngle:" + webCamTexture.videoRotationAngle + " videoVerticallyMirrored:" + webCamTexture.videoVerticallyMirrored + " isFrongFacing:" + webCamDevice.isFrontFacing); | |
screenOrientation = Screen.orientation; | |
screenWidth = Screen.width; | |
screenHeight = Screen.height; | |
isInitWaiting = false; | |
hasInitDone = true; | |
OnInited(); | |
break; | |
} | |
else | |
{ | |
yield return 0; | |
} | |
} | |
} | |
/// <summary> | |
/// Releases all resource. | |
/// </summary> | |
private void Dispose() | |
{ | |
rotate90Degree = false; | |
isInitWaiting = false; | |
hasInitDone = false; | |
if (webCamTexture != null) | |
{ | |
webCamTexture.Stop(); | |
WebCamTexture.Destroy(webCamTexture); | |
webCamTexture = null; | |
} | |
if (texture != null) | |
{ | |
Texture2D.Destroy(texture); | |
texture = null; | |
} | |
} | |
/// <summary> | |
/// Raises the webcam texture initialized event. | |
/// </summary> | |
private void OnInited() | |
{ | |
if (colors == null || colors.Length != webCamTexture.width * webCamTexture.height) | |
{ | |
colors = new Color32[webCamTexture.width * webCamTexture.height]; | |
rotatedColors = new Color32[webCamTexture.width * webCamTexture.height]; | |
} | |
if (adjustPixelsDirection) | |
{ | |
#if !UNITY_EDITOR && !(UNITY_STANDALONE || UNITY_WEBGL) | |
if (Screen.orientation == ScreenOrientation.Portrait || Screen.orientation == ScreenOrientation.PortraitUpsideDown) | |
{ | |
rotate90Degree = true; | |
} | |
else | |
{ | |
rotate90Degree = false; | |
} | |
#endif | |
} | |
if (rotate90Degree) | |
{ | |
texture = new Texture2D(webCamTexture.height, webCamTexture.width, TextureFormat.RGBA32, false); | |
} | |
else | |
{ | |
texture = new Texture2D(webCamTexture.width, webCamTexture.height, TextureFormat.RGBA32, false); | |
} | |
gameObject.GetComponent<Renderer>().material.mainTexture = texture; | |
gameObject.transform.localScale = new Vector3(texture.width, texture.height, 1); | |
Debug.Log("Screen.width " + Screen.width + " Screen.height " + Screen.height + " Screen.orientation " + Screen.orientation); | |
float width = texture.width; | |
float height = texture.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; | |
}*/ | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
if (adjustPixelsDirection) | |
{ | |
// Catch the orientation change of the screen. | |
if (screenOrientation != Screen.orientation && (screenWidth != Screen.width || screenHeight != Screen.height)) | |
{ | |
Initialize(); | |
} | |
else | |
{ | |
screenWidth = Screen.width; | |
screenHeight = Screen.height; | |
} | |
} | |
if (hasInitDone && webCamTexture.isPlaying && webCamTexture.didUpdateThisFrame) | |
{ | |
Color32[] colors = GetColors(); | |
Color32[] colorsBlank = new Color32[colors.Length]; | |
if (colors != null) | |
{ | |
faceLandmarkDetector.SetImage<Color32>(colors, texture.width, texture.height, 4, true); | |
//detect face rects | |
List<UnityEngine.Rect> detectResult = faceLandmarkDetector.Detect(); | |
foreach (var rect in detectResult) | |
{ | |
//Debug.Log ("face : " + rect); | |
//detect landmark points | |
faceLandmarkDetector.DetectLandmark(rect); | |
//draw landmark points | |
if (!debugMode) | |
faceLandmarkDetector.DrawDetectLandmarkResult<Color32>(colorsBlank, texture.width, texture.height, 4, true, 0, 255, 0, 255); | |
else | |
faceLandmarkDetector.DrawDetectLandmarkResult<Color32>(colors, texture.width, texture.height, 4, true, 0, 255, 0, 255); | |
} | |
//draw face rect | |
// faceLandmarkDetector.DrawDetectResult<Color32>(colors, texture.width, texture.height, 4, true, 255, 0, 0, 255, 2); | |
//Utils.Color | |
if (!debugMode) | |
{ | |
texture.SetPixels32(colorsBlank); | |
texture.Apply(false); | |
// pixelate | |
Mat matpixelate = new Mat(texture.height,texture.width,CvType.CV_8UC1); | |
OpenCVForUnity.UnityUtils.Utils.texture2DToMat(texture,matpixelate,false,0); | |
matpixelate = Pixelate(matpixelate, 128, 128); | |
OpenCVForUnity.UnityUtils.Utils.matToTexture2D(matpixelate, texture, false, 0); | |
} | |
else | |
texture.SetPixels32(colors); | |
texture.Apply(false); | |
} | |
} | |
} | |
public bool debugMode = false; | |
#if (UNITY_IOS && UNITY_2018_1_OR_NEWER) || (UNITY_ANDROID && UNITY_2018_3_OR_NEWER) | |
bool isUserRequestingPermission; | |
IEnumerator OnApplicationFocus(bool hasFocus) | |
{ | |
yield return null; | |
if (isUserRequestingPermission && hasFocus) | |
isUserRequestingPermission = false; | |
} | |
#endif | |
/// <summary> | |
/// Gets the current WebCameraTexture frame that converted to the correct direction. | |
/// </summary> | |
private Color32[] GetColors() | |
{ | |
webCamTexture.GetPixels32(colors); | |
if (adjustPixelsDirection) | |
{ | |
//Adjust an array of color pixels according to screen orientation and WebCamDevice parameter. | |
if (rotate90Degree) | |
{ | |
Rotate90CW(colors, rotatedColors, webCamTexture.width, webCamTexture.height); | |
FlipColors(rotatedColors, webCamTexture.width, webCamTexture.height); | |
return rotatedColors; | |
} | |
else | |
{ | |
FlipColors(colors, webCamTexture.width, webCamTexture.height); | |
return colors; | |
} | |
} | |
return colors; | |
} | |
/// <summary> | |
/// Raises the destroy event. | |
/// </summary> | |
void OnDestroy() | |
{ | |
Dispose(); | |
if (faceLandmarkDetector != null) | |
faceLandmarkDetector.Dispose(); | |
#if UNITY_WEBGL | |
if (getFilePath_Coroutine != null) | |
{ | |
StopCoroutine(getFilePath_Coroutine); | |
((IDisposable)getFilePath_Coroutine).Dispose(); | |
} | |
#endif | |
} | |
/// <summary> | |
/// Flips vertical. | |
/// </summary> | |
/// <param name="src">Src colors.</param> | |
/// <param name="dst">Dst colors.</param> | |
/// <param name="width">Width.</param> | |
/// <param name="height">Height.</param> | |
void FlipVertical(Color32[] src, Color32[] dst, int width, int height) | |
{ | |
for (var i = 0; i < height / 2; i++) | |
{ | |
var y = i * width; | |
var x = (height - i - 1) * width; | |
for (var j = 0; j < width; j++) | |
{ | |
int s = y + j; | |
int t = x + j; | |
Color32 c = src[s]; | |
dst[s] = src[t]; | |
dst[t] = c; | |
} | |
} | |
} | |
/// <summary> | |
/// Flips horizontal. | |
/// </summary> | |
/// <param name="src">Src colors.</param> | |
/// <param name="dst">Dst colors.</param> | |
/// <param name="width">Width.</param> | |
/// <param name="height">Height.</param> | |
void FlipHorizontal(Color32[] src, Color32[] dst, int width, int height) | |
{ | |
for (int i = 0; i < height; i++) | |
{ | |
int y = i * width; | |
int x = y + width - 1; | |
for (var j = 0; j < width / 2; j++) | |
{ | |
int s = y + j; | |
int t = x - j; | |
Color32 c = src[s]; | |
dst[s] = src[t]; | |
dst[t] = c; | |
} | |
} | |
} | |
/// <summary> | |
/// Rotates 180 degrees. | |
/// </summary> | |
/// <param name="src">Src colors.</param> | |
/// <param name="dst">Dst colors.</param> | |
/// <param name="width">Width.</param> | |
/// <param name="height">Height.</param> | |
void Rotate180(Color32[] src, Color32[] dst, int height, int width) | |
{ | |
int i = src.Length; | |
for (int x = 0; x < i / 2; x++) | |
{ | |
Color32 t = src[x]; | |
dst[x] = src[i - x - 1]; | |
dst[i - x - 1] = t; | |
} | |
} | |
/// <summary> | |
/// Rotates 90 degrees (CLOCKWISE). | |
/// </summary> | |
/// <param name="src">Src colors.</param> | |
/// <param name="dst">Dst colors.</param> | |
/// <param name="width">Width.</param> | |
/// <param name="height">Height.</param> | |
void Rotate90CW(Color32[] src, Color32[] dst, int height, int width) | |
{ | |
int i = 0; | |
for (int x = height - 1; x >= 0; x--) | |
{ | |
for (int y = 0; y < width; y++) | |
{ | |
dst[i] = src[x + y * height]; | |
i++; | |
} | |
} | |
} | |
/// <summary> | |
/// Rotates 90 degrees (COUNTERCLOCKWISE). | |
/// </summary> | |
/// <param name="src">Src colors.</param> | |
/// <param name="dst">Dst colors.</param> | |
/// <param name="height">Height.</param> | |
/// <param name="width">Width.</param> | |
void Rotate90CCW(Color32[] src, Color32[] dst, int width, int height) | |
{ | |
int i = 0; | |
for (int x = 0; x < width; x++) | |
{ | |
for (int y = height - 1; y >= 0; y--) | |
{ | |
dst[i] = src[x + y * width]; | |
i++; | |
} | |
} | |
} | |
/// <summary> | |
/// Flips the colors. | |
/// </summary> | |
/// <param name="colors">Colors.</param> | |
/// <param name="width">Width.</param> | |
/// <param name="height">Height.</param> | |
void FlipColors(Color32[] colors, int width, int height) | |
{ | |
int flipCode = int.MinValue; | |
if (webCamDevice.isFrontFacing) | |
{ | |
if (webCamTexture.videoRotationAngle == 0) | |
{ | |
flipCode = 1; | |
} | |
else if (webCamTexture.videoRotationAngle == 90) | |
{ | |
flipCode = 1; | |
} | |
if (webCamTexture.videoRotationAngle == 180) | |
{ | |
flipCode = 0; | |
} | |
else if (webCamTexture.videoRotationAngle == 270) | |
{ | |
flipCode = 0; | |
} | |
} | |
else | |
{ | |
if (webCamTexture.videoRotationAngle == 180) | |
{ | |
flipCode = -1; | |
} | |
else if (webCamTexture.videoRotationAngle == 270) | |
{ | |
flipCode = -1; | |
} | |
} | |
if (flipCode > int.MinValue) | |
{ | |
if (rotate90Degree) | |
{ | |
if (flipCode == 0) | |
{ | |
FlipVertical(colors, colors, height, width); | |
} | |
else if (flipCode == 1) | |
{ | |
FlipHorizontal(colors, colors, height, width); | |
} | |
else if (flipCode < 0) | |
{ | |
Rotate180(colors, colors, height, width); | |
} | |
} | |
else | |
{ | |
if (flipCode == 0) | |
{ | |
FlipVertical(colors, colors, width, height); | |
} | |
else if (flipCode == 1) | |
{ | |
FlipHorizontal(colors, colors, width, height); | |
} | |
else if (flipCode < 0) | |
{ | |
Rotate180(colors, colors, height, width); | |
} | |
} | |
} | |
} | |
Mat Pixelate(Mat img, int w, int h) { | |
// return img; | |
//height, width = img.shape[:2] | |
Mat img2 = new Mat( img.rows() ,img.cols() , CvType.CV_8UC1); | |
// Resize input to "pixelated" size | |
Imgproc.resize(img, img2, new Size(w,h), w, h, 1); | |
// temp = cv2.resize(img, (w, h), interpolation = cv2.INTER_LINEAR) | |
// Initialize output image | |
Mat img3 = new Mat(img.rows(), img.cols(), CvType.CV_8UC1); | |
Imgproc.resize(img2, img3, new Size(img.width(),img.height()), w, h, 0); | |
// return cv2.resize(temp, (width, height), interpolation = cv2.INTER_NEAREST) | |
return img3; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment