using Emgu.CV; using Emgu.CV.CvEnum; using Emgu.CV.Structure; using System.Drawing; using System; using System.IO; using System.Reflection; using System.Collections.Generic; using WingAIDiagnosisService.Manage; namespace WingAIDiagnosisService.Carotid.Utilities { /// /// 识别颈动脉类型,左颈还是右颈 /// public class RecognizeCarotidType : IDisposable { private const string MFDllName = "mf.dll"; private string[] _fileNameLeft; private string[] _fileNameRight; private Image[] _imagesLeft; private Image[] _imagesRight; static RecognizeCarotidType() { var x64Folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Emgu.CV", "win-x64"); if (Environment.OSVersion.Platform == PlatformID.Win32NT) { var mfDll = Path.Combine(x64Folder, MFDllName); if (!File.Exists(mfDll)) { var systemMfDll = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), MFDllName); //If system32 don't exist mf environment. if (!File.Exists(systemMfDll)) { var folderName = GetDirectoryFolderName(Environment.OSVersion.Version); if (!string.IsNullOrWhiteSpace(folderName)) { var directoryInfo = new DirectoryInfo(Path.Combine(x64Folder, folderName)); var fileInfos = directoryInfo.GetFiles(); for (int i = 0; i < fileInfos.Length; ++i) { File.Copy(fileInfos[i].FullName, Path.Combine(x64Folder, fileInfos[i].Name), true); } } } } } if (Environment.Is64BitProcess) { Emgu.Util.Toolbox.SetDllDirectory(x64Folder); } else { Emgu.Util.Toolbox.SetDllDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Emgu.CV", "win-x86")); } } private static string GetDirectoryFolderName(Version version) { if (version.Major == 6) { if (version.Minor == 1) { return "6.1"; } if (version.Minor == 2) { return "6.2"; } } return string.Empty; } public bool Initialization() { try { var classType = GetType(); var resourceNamespace = classType.Namespace?.Replace("Utilities", "Images"); var assembly = classType.Assembly; if (assembly == null || string.IsNullOrWhiteSpace(resourceNamespace)) { return false; } //所有资源 var allResourceName = assembly.GetManifestResourceNames(); _fileNameLeft = GetLeftSamplePath(allResourceName, resourceNamespace); _imagesLeft = new Image[_fileNameLeft.Length]; for (var i = 0; i < _fileNameLeft.Length; ++i) { _imagesLeft[i] = GetImageFromResource(_fileNameLeft[i], assembly); } _fileNameRight = GetRightSamplePath(allResourceName, resourceNamespace); _imagesRight = new Image[_fileNameRight.Length]; for (var i = 0; i < _fileNameRight.Length; ++i) { _imagesRight[i] = GetImageFromResource(_fileNameRight[i], assembly); } return true; } catch (Exception e) { return false; } } private string[] GetLeftSamplePath(string[] allFilePath, string rootPath) { string leftFloder = rootPath + ".left"; string leftFloder1 = rootPath + ".left1"; var nameList = new List(); for (var i = 0; i < allFilePath.Length; ++i) { if (allFilePath[i].Contains(leftFloder) || allFilePath[i].Contains(leftFloder1)) { nameList.Add(allFilePath[i]); } } return nameList.ToArray(); } private string[] GetRightSamplePath(string[] allFilePath, string rootPath) { string leftFloder = rootPath + ".right"; string leftFloder1 = rootPath + ".right1"; var nameList = new List(); for (var i = 0; i < allFilePath.Length; ++i) { if (allFilePath[i].Contains(leftFloder) || allFilePath[i].Contains(leftFloder1)) { nameList.Add(allFilePath[i]); } } return nameList.ToArray(); } private Image GetImageFromResource(string fileName, Assembly assembly) { using Stream stream = assembly.GetManifestResourceStream(fileName); byte[] imageBuffer = new byte[stream.Length]; stream.Read(imageBuffer, 0, imageBuffer.Length); //转成彩色图像 using var img = new Mat(); CvInvoke.Imdecode(imageBuffer, ImreadModes.Color, img); return img.ToImage(); } public CarotidScanType RecognizeType(Image imageBgr) { using Image image = imageBgr.Copy(new Rectangle(0, 0, imageBgr.Width / 2, imageBgr.Height / 2)); double maxLeft = 0; for (var i = 0; i < _imagesLeft.Length; ++i) { var confidence = MatchImage(_imagesLeft[i], image); if (confidence > maxLeft) { maxLeft = confidence; } } double maxRight = 0; for (var i = 0; i < _imagesRight.Length; ++i) { var confidence = MatchImage(_imagesRight[i], image); if (confidence > maxRight) { maxRight = confidence; } } if (maxRight > 0.7 || maxLeft > 0.7) { if (maxRight > maxLeft) { return CarotidScanType.CarotidRight; } } return CarotidScanType.CarotidLeft; } private double MatchImage(Image imageSmall, Image imageLarge) { using Mat MatchResult = new Mat();//匹配结果 //判断子图是否在原图中 CvInvoke.MatchTemplate(imageLarge, imageSmall, MatchResult, TemplateMatchingType.CcorrNormed); Point max_loc = new Point(); Point min_loc = new Point(); double max = 0, min = 0; CvInvoke.MinMaxLoc(MatchResult, ref min, ref max, ref min_loc, ref max_loc);//获得极值信息 return max; } public void Dispose() { if (_fileNameLeft != null && _imagesLeft != null) { for (var i = 0; i < _fileNameLeft.Length; ++i) { _fileNameLeft[i] = null; _imagesLeft[i]?.Dispose(); } } if (_fileNameRight != null && _imagesRight != null) { for (var i = 0; i < _fileNameRight.Length; ++i) { _fileNameRight[i] = null; _imagesRight[i]?.Dispose(); } } _fileNameLeft = null; _fileNameRight = null; _imagesLeft = null; _imagesRight = null; } } }