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