using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Shapes;
using System.Windows.Input;
using System.Drawing;
using System.Data.SQLite;
using Newtonsoft.Json;
using System.Security.Cryptography;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using System.Drawing.Imaging;
using System.Windows.Threading;
using Microsoft.Win32;
using AI.Common.Interface;
using RawImageShowUtilsLib;
using AIModuleResultShowUtilsLib;
using System.Xml.Linq;
using AI.Common.Implements;
using static System.Windows.Forms.AxHost;
using System.Security.Policy;
using System.Windows.Media;
using System.ComponentModel;
using System.Windows.Forms;
namespace AILesionDescriptionGTGenerator
{
///
/// Canvas上绘制的目标有几种类型
///
public enum EnumCanvasItemType
{
Drawing,
Choosed,
Existed,
}
///
/// 线的种类
///
public enum EnumCanvasLineType
{
Horizontal,
Vertical,
}
///
/// 鼠标状态
///
public enum EnumMouseOperType
{
None,
DrawingContour,
DrawingHorizonLines,
DrawingVerticalLines,
DrawingPoint,
}
public enum EnumDesShapeValue
{
///
/// 椭圆形
///
Oval,
///
/// 类圆形
///
Round,
///
/// 不规则形
///
Irregular,
}
///
/// 方向描述可能的结果值
///
public enum EnumDesOrientationValue
{
///
/// 平行
///
Parallel,
///
/// 非平行
///
NonParallel,
}
///
/// 内部回声描述可能的结果
///
public enum EnumDesEchoPatternValue
{
///
/// 无回声
///
Anechoic,
///
/// 低回声
///
Hypoechoic,
///
/// 等回声
///
Isoechoic,
///
/// 高回声
///
Hyperechoic,
///
/// 混合回声
///
Complex,
///
/// 强回声
///
Strongechoic,
}
///
/// 病灶边界描述可能的结果
///
public enum EnumDesLesionBoundaryValue
{
///
/// 清晰
///
AbruptInterface,
///
/// 模糊
///
EchogenicHalo,
}
///
/// 病灶边缘描述的可能结果
///
public enum EnumDesMarginValue
{
///
/// 光整
///
Circumscribed,
///
/// 不光整
///
NonCircumscribed,
}
///
/// 病灶信息
///
public class LesionInfo
{
///
/// 病灶轮廓
///
public List Contour { get; set; } = new List();
///
/// 病灶形状
///
public EnumDesShapeValue Shape { get; set; } = EnumDesShapeValue.Oval;
///
/// 方向
///
public EnumDesOrientationValue Orientation { get; set; } = EnumDesOrientationValue.Parallel;
///
/// 回声类型
///
public EnumDesEchoPatternValue EchoPattern { get; set; } = EnumDesEchoPatternValue.Hypoechoic;
///
/// 边界清晰不清晰
///
public EnumDesLesionBoundaryValue Boundary { get; set; } = EnumDesLesionBoundaryValue.AbruptInterface;
///
/// 边缘光整不光整
///
public EnumDesMarginValue Margin { get; set; } = EnumDesMarginValue.Circumscribed;
///
/// 横径起点
///
public Point2D HorizontalPoint1 { get; set; } = new Point2D();
///
/// 横径终点
///
public Point2D HorizontalPoint2 { get; set; } = new Point2D();
///
/// 纵径起点
///
public Point2D VerticalPoint1 { get; set; } = new Point2D();
///
/// 纵径终点
///
public Point2D VerticalPoint2 { get; set; } = new Point2D();
///
/// 内容完整
///
public bool IsCompleted
{
get
{
return Contour.Count > 0 && HorizontalPoint1 != HorizontalPoint2 &&
VerticalPoint1 != VerticalPoint2;
}
}
}
///
/// 病灶描述GT图像信息
///
public class LesionDesGTImgInfo
{
public string ImageId { get; set; }
///
/// 病灶分级
///
public List Label { get; set; }
///
/// 该图上所有病灶的标准描述
///
public List Lesions { get; set; }
}
///
/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
#region private variables
private readonly string _dataFolder = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(System.IO.Path.GetDirectoryName(
AppDomain.CurrentDomain.BaseDirectory)),"LesionDescriptionGTDatas");
private readonly string _dbPath;
private readonly string _imageDataFolder;
private readonly string _dbModelPath;
private List _allImages = new List();
private volatile int _imgIndex = 0;
private List _lesions = new List();
private volatile int _lesionIndex = 0;
private volatile bool _modified = false;
private BitmapImage _origimg = null;
private BitmapImage _drawimg = null;
// 鼠标动作
private volatile EnumMouseOperType _mouseOper = EnumMouseOperType.None;
private volatile bool _mouseLeftBtnPressed = false;
// 鼠标绘制的起始位置(画横轴,纵轴时需要)
private System.Windows.Point _mouseStartPos;
// 绘制中的所有轮廓点的集合
private List _drawingPoints = new List();
private volatile bool _canAutoFinish = false;
//private DataBase _creatBd = new DataBase();
private Bitmap _image = null;
private BitmapImage _dstImgWin = null;
private LesionDesGTImgInfo _modelResult = new LesionDesGTImgInfo(); //模型检测出的病灶结果
private volatile bool _showModelResult = false;
private volatile int _lesionOriModelIndex = 0;//左侧界面病灶ID
private List _lesionsLabels = new List();
//private List _lesionsModelLabels = new List();
private volatile int _lesionLabelIndex = 0;
private volatile bool _showDrawingResult = false;
private volatile int _num = 0;
private IModule _module;
private string _currentPath;
private InferenceConfig _inferConfig = new InferenceConfig();
private string _netDir = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks");
private volatile string _processId = string.Empty;
private volatile string _caseId = string.Empty;
private volatile string _dataId = string.Empty;
private volatile bool _readingVideo;
private volatile int _frameIndex;
IDetectedObject[] _newModelResult;
//回声
private int _Anechoic_Anechoic_num = 0; //无回声 判为 无回声 的数目
private int _Anechoic_Hypoechoic_num = 0; //无回声 判为 低回声 的数目
private int _Anechoic_Isoechoic_num = 0; //无回声 判为 等回声 的数目
private int _Anechoic_Hyperechoic_num = 0; //无回声 判为 高回声 的数目
private int _Anechoic_Complex_num = 0; //无回声 判为 Complex 的数目
private int _Hyperechoic_Hyperechoic_num = 0; //高回声 判为 高回声
private int _Hyperechoic_Anechoic_num = 0;
private int _Hyperechoic_Isoechoic_num = 0;
private int _Hyperechoic_Hypoechoic_num = 0;
private int _Hyperechoic_Complex_num = 0;
private int _Isoechoic_Isoechoic_num = 0; //等回声 判为 等回声
private int _Isoechoic_Anechoic_num = 0;
private int _Isoechoic_Hyperechoic_num = 0;
private int _Isoechoic_Hypoechoic_num = 0;
private int _Isoechoic_Complex_num = 0;
private int _Hypoechoic_Hypoechoic_num = 0; //低回声 判为 低回声
private int _Hypoechoic_Anechoic_num = 0;
private int _Hypoechoic_Hyperechoic_num = 0;
private int _Hypoechoic_Isoechoic_num = 0;
private int _Hypoechoic_Complex_num = 0;
private int _Complex_Complex_num = 0; //极低回声 判为 极低回声
private int _Complex_Anechoic_num = 0;
private int _Complex_Hyperechoic_num = 0;
private int _Complex_Isoechoic_num = 0;
private int _Complex_Hypoechoic_num = 0;
//形状
private int _Oval_Oval_num = 0; //椭圆形 判为 椭圆形
private int _Oval_Round_num = 0; //椭圆形 判为 类圆形
private int _Oval_Irregular_num = 0; //椭圆形 判为 不规则形
private int _Round_Round_num = 0; //类圆形 判为 类圆形
private int _Round_Oval_num = 0; //类圆形 判为 椭圆形
private int _Round_Irregular_num = 0; //类圆形 判为 不规则形
private int _Irregular_Irregular_num = 0; //不规则形 判为 不规则形
private int _Irregular_Oval_num = 0; //不规则形 判为 椭圆形
private int _Irregular_Round_num = 0; //不规则形 判为 类圆形
//边缘
private int _Circumscribed_Circumscribed_num = 0; //光整 判为 不光整
private int _Circumscribed_NonCircumscribed_num = 0;
private int _NonCircumscribed_NonCircumscribed_num = 0; //不光整 判为 光整
private int _NonCircumscribed_Circumscribed_num = 0;
//边界
private int _AbruptInterface_AbruptInterface_num; //清晰--清晰
private int _AbruptInterface_EchogenicHalo_num; //清晰--模糊
private int _EchogenicHalo_EchogenicHalo_num; //模糊--模糊
private int _EchogenicHalo_AbruptInterface_num; //模糊--清晰
//方向
private int _Parallel_Parallel_num; //平行--平行
private int _Parallel_NonParallel_num; //平行--非平行
private int _NonParallel_NonParallel_num; //非平行--非平行
private int _NonParallel_Parallel_num; //非平行--平行
#endregion
#region 用户界面响应
public MainWindow()
{
InitializeComponent();
InitializeComboBoxLesionsLabel();
_dbPath = System.IO.Path.Combine(_dataFolder, "lesion_des_gt_datas.db");
_imageDataFolder = System.IO.Path.Combine(_dataFolder, "Images");
_currentPath = System.Environment.CurrentDirectory;
_module = new AI.Vaid.Modules.BreastLesionDetect.BreastLesionDetect(_netDir, _inferConfig, EnumDeviceType.CPU);
bool existDb = CreateDataBase();
if(existDb)
{
AddNewImages(_imageDataFolder);
}
UserControlLesionSelected.NotifyLesionInfoEventArgs += OnLesionInfoSelectorEventOccur;
ReadDataBase();
DrawImage.Source = _drawimg;
OrigImage.Source = _origimg;
DetectImage(_image);
}
///
/// 点击 "前一幅图"
///
///
///
private void OnBtnPreviousImageClicked(object sender, RoutedEventArgs e)
{
// 查看当前图的ROI是否已经绘制完毕
if (_lesions.Count > 0)
{
if (_lesions.Count != _lesionsLabels.Count)
{
System.Windows.MessageBox.Show("请先将当前图像的描述添加完整,或删除不需要的描述后再查看新的图像");
return;
}
foreach (var lesion in _lesions)
{
if (!lesion.IsCompleted)
{
System.Windows.MessageBox.Show("请先将当前图像的描述添加完整,或删除不需要的描述后再查看新的图像");
return;
}
}
for (int i = 0; i < _lesionsLabels.Count; i++)//add
{
//if (_lesionsLabels[i] < 1)
//{
// string str = "请先将当前图像的描述的第:" + i.ToString() + "个病灶等级添加完整";
// MessageBox.Show(str);
// return;
//}
}
}
// 保存当前图的结果
if (_modified)
{
SetLesions(_allImages[_imgIndex].ImageId, _lesions);
SetLesionsLabels(_allImages[_imgIndex].ImageId, _lesionsLabels);
}
// 如果已经OK,则更新记录
if (_imgIndex <= 0)
{
System.Windows.MessageBox.Show("已是第一个");
return;
}
_imgIndex = _imgIndex - 1;
_dstImgWin = null;
_modelResult = null;
_modelResult = new LesionDesGTImgInfo();
CurrentImgIndexUpdated();
_drawingPoints.Clear();//
_lesionOriModelIndex = 0;
DetectImage(_image);
}
///
/// 点击 "后一幅图"
///
///
///
private void OnBtnNextImageClicked(object sender, RoutedEventArgs e)
{
// 查看当前图像的ROI是否已经绘制完毕
if (_lesions.Count > 0)
{
if (_lesions.Count != _lesionsLabels.Count)
{
System.Windows.MessageBox.Show("请先将当前图像的描述添加完整,或删除不需要的描述后再查看新的图像");
return;
}
foreach (var lesion in _lesions)
{
if (!lesion.IsCompleted)
{
System.Windows.MessageBox.Show("请先将当前图像的描述添加完整,或删除不需要的描述后再查看新的图像");
return;
}
}
for(int i =0; i < _lesionsLabels.Count; i++)//add
{
//if (_lesionsLabels[i] <1)
//{
// string str = "请先将当前图像的描述的第:" + i.ToString() + "个病灶等级添加完整";
// MessageBox.Show(str);
// return;
//}
}
}
// 保存当前图的结果
if (_modified)
{
SetLesions(_allImages[_imgIndex].ImageId, _lesions);
SetLesionsLabels(_allImages[_imgIndex].ImageId, _lesionsLabels);
}
// 如果已经OK,则更新记录
if (_imgIndex >= _allImages.Count - 1)
{
System.Windows.MessageBox.Show("已是最后一个");
return;
}
_imgIndex = _imgIndex + 1;
_dstImgWin = null;
_modelResult = null;
_modelResult = new LesionDesGTImgInfo();
CurrentImgIndexUpdated();
_drawingPoints.Clear();//
_lesionOriModelIndex = 0;
DetectImage(_image);
}
///
/// 选中的病灶改变
///
///
///
private void OnLesionSelectionChanged(object sender, SelectionChangedEventArgs e)
{
_lesionIndex = ComboBoxLesions.SelectedIndex;
//_lesionIndex = 0;//add ???
LesionsUpdated();
}
///
/// 删除选中的病灶
///
///
///
private void OnBtnDeleteSelROIClicked(object sender, RoutedEventArgs e)
{
if (_lesionIndex < 0)
{
System.Windows.MessageBox.Show("请先选择一个待删除的病灶");
return;
}
// 先清空画布上旧的显示内容
for (int ni = 0; ni < _lesions.Count; ni++)
{
RemoveContourInCanvas(ni.ToString());
RemoveLineInCanvas(EnumCanvasLineType.Horizontal, ni.ToString());
RemoveLineInCanvas(EnumCanvasLineType.Vertical, ni.ToString());
}
_lesions.RemoveAt(_lesionIndex);
_lesionsLabels.RemoveAt(_lesionIndex);
_modified = true;
if (_lesionIndex >= _lesions.Count)
{
if (_lesions.Count > 0)
{
_lesionIndex = 0;
}
else
{
_lesionIndex = -1;
}
}
_drawingPoints.Clear();
LesionsUpdated();
}
///
/// 新增病灶
///
///
///
private void OnBtnAddNewROIClicked(object sender, RoutedEventArgs e)
{
if (!UserControlLesionSelected.IsEmpty)
{
if (!UserControlLesionSelected.Lesion.IsCompleted)
{
System.Windows.MessageBox.Show("请先将现有病灶的描述添加完整后再增加新的病灶");
return;
}
if(_lesionLabelIndex < 1)
{
System.Windows.MessageBox.Show("请先将当前病灶等级添加完整");
return;
}
}
_lesionIndex = _lesions.Count;
_lesions.Add(new LesionInfo());
_lesionsLabels.Add(-1);
_modified = true;
_drawingPoints.Clear();
LesionsUpdated();
}
///
/// 画布尺寸改变
///
///
///
private void Canvas_SizeChanged(object sender, SizeChangedEventArgs e)
{
MyCanvasDraw.Width = GridDrawImg.ActualWidth;
MyCanvasDraw.Height = GridDrawImg.ActualHeight;
ImageUpdated();
UpdateLesionsInCanvas();
UpdateLesionsIndex();
}
///
/// 鼠标左键按下
///
///
///
private void Canvas_MouseLeftBtnDown(object sender, MouseButtonEventArgs e)
{
System.Windows.Point mousePosInCanvas = e.GetPosition((IInputElement)sender);
_mouseStartPos = mousePosInCanvas;
//////////////////
if (_drawingPoints.Count <= 0)
{
_drawingPoints = new List();
}
else
{
}
//var dd = _mouseOper;
if (_mouseOper == EnumMouseOperType.DrawingPoint)
{
_drawingPoints.Add(mousePosInCanvas);
}
else if(_mouseOper == EnumMouseOperType.None)
{
_canAutoFinish = false;
//_drawingPoints.Add(mousePosInCanvas);
}
else
{
_canAutoFinish = false;
_drawingPoints.Add(mousePosInCanvas);
}
//_drawingPoints = new List();
//_canAutoFinish = false;
//_drawingPoints.Add(mousePosInCanvas);
_mouseLeftBtnPressed = true;
}
///
/// 鼠标左键弹起
///
///
///
private void Canvas_MouseLeftBtnUp(object sender, MouseButtonEventArgs e)
{
_mouseLeftBtnPressed = false;
System.Windows.Point mousePosInCanvas = e.GetPosition((IInputElement)sender);
Point2D mousePosInOrigImg = GetPosInOrigImage(mousePosInCanvas);
Point2D startPosInOrigImg = GetPosInOrigImage(_mouseStartPos);
switch (_mouseOper)
{
case EnumMouseOperType.DrawingContour:
// 如果现在绘制的轮廓还未结束,就直接连接起点终点,将现在绘制的轮廓线,转换成图像坐标,发送给LesionInfoSelector,_mouseOper重置成空
if (_drawingPoints[_drawingPoints.Count - 1] != _drawingPoints[0])
{
_drawingPoints.Add(_drawingPoints[0]);
}
List contourInOrigImg = new List();
foreach (var point in _drawingPoints)
{
contourInOrigImg.Add(GetPosInOrigImage(point));
}
_drawingPoints = new List();
_mouseOper = EnumMouseOperType.None;
RemoveContourInCanvas("drawing");
UserControlLesionSelected.SetContour(contourInOrigImg);
//_canAutoFinish = false;
break;
case EnumMouseOperType.DrawingPoint:
//if (_drawingPoints[_drawingPoints.Count - 1] != _drawingPoints[0])
{
//_drawingPoints.Add(_drawingPoints[0]);
DrawContourInCanvas(_drawingPoints, EnumCanvasItemType.Drawing, "drawingPt");
// 如果已经很靠近起始点,就自动结束
if (PointDistance(_drawingPoints[_drawingPoints.Count - 1], _drawingPoints[0]) < 5)
{
if (_canAutoFinish)
{
_drawingPoints.Add(_drawingPoints[0]);
List contourInOrigImgPt = new List();
foreach (var point in _drawingPoints)
{
contourInOrigImgPt.Add(GetPosInOrigImage(point));
}
_drawingPoints = new List();
_mouseOper = EnumMouseOperType.None;
RemoveContourInCanvas("drawingPt");
UserControlLesionSelected.SetContour(contourInOrigImgPt);
//_canAutoFinish = false;
}
}
else
{
if (!_canAutoFinish)
{
_canAutoFinish = true;
}
}
}
break;
case EnumMouseOperType.DrawingHorizonLines:
// 将当前绘制的横径起点终点,转换成图像坐标,发送给LesionInfoSelector,_mouseOper重置成空
_mouseOper = EnumMouseOperType.None;
RemoveLineInCanvas(EnumCanvasLineType.Horizontal,"drawing");
UserControlLesionSelected.SetHorizontalAxis(startPosInOrigImg, mousePosInOrigImg);
break;
case EnumMouseOperType.DrawingVerticalLines:
// 将当前绘制的纵径起点终点,转换成图像坐标,发送给LesionInfoSelector,_mouseOper重置成空
_mouseOper = EnumMouseOperType.None;
RemoveLineInCanvas(EnumCanvasLineType.Vertical, "drawing");
UserControlLesionSelected.SetVerticalAxis(startPosInOrigImg, mousePosInOrigImg);
break;
}
}
///
/// 鼠标移动
///
///
///
private void Canvas_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
// 显示鼠标位置
System.Windows.Point mousePosInCanvas = e.GetPosition((IInputElement)sender);
Point2D mousePosInOrigImg = GetPosInOrigImage(mousePosInCanvas);
TextBlockMousePosition.Text = mousePosInOrigImg.X.ToString() + "," + mousePosInOrigImg.Y.ToString();
// 判断鼠标当前状态
if (e.LeftButton == MouseButtonState.Pressed)
{
switch (_mouseOper)
{
case EnumMouseOperType.DrawingContour:
_drawingPoints.Add(mousePosInCanvas);
// 如果该图选中病灶已经有描述了,先清除Canvas上显示的,以免影响标注
if(_lesions[_lesionIndex].Contour.Count > 0)
{
RemoveContourInCanvas(_lesionIndex.ToString());
}
// 更新显示正在绘制的轮廓线
DrawContourInCanvas(_drawingPoints, EnumCanvasItemType.Drawing, "drawing");
// 如果已经很靠近起始点,就自动结束
if (PointDistance(_drawingPoints[_drawingPoints.Count - 1], _drawingPoints[0]) < 5)
{
if (_canAutoFinish)
{
_drawingPoints.Add(_drawingPoints[0]);
List contourInOrigImg = new List();
foreach (var point in _drawingPoints)
{
contourInOrigImg.Add(GetPosInOrigImage(point));
}
_drawingPoints = new List();
_mouseOper = EnumMouseOperType.None;
RemoveContourInCanvas("drawing");
UserControlLesionSelected.SetContour(contourInOrigImg);
}
}
else
{
if (!_canAutoFinish)
{
_canAutoFinish = true;
}
}
break;
case EnumMouseOperType.DrawingPoint:
//_drawingPoints.Add(mousePosInCanvas);
//DrawContourInCanvas(_drawingPoints, EnumCanvasItemType.Drawing, "drawing");
break;
case EnumMouseOperType.DrawingHorizonLines:
// 如果该图选中病灶已经有横轴了,先清除Canvas上显示的,以免影响标注
RemoveLineInCanvas(EnumCanvasLineType.Horizontal, _lesionIndex.ToString());
// 更新显示正在绘制的横轴
DrawLineInCanvas(_mouseStartPos, mousePosInCanvas, EnumCanvasLineType.Horizontal, EnumCanvasItemType.Drawing, "drawing");
break;
case EnumMouseOperType.DrawingVerticalLines:
// 如果该图选中病灶已经有纵轴了,先清除Canvas上显示的,以免影响标注
RemoveLineInCanvas(EnumCanvasLineType.Vertical, _lesionIndex.ToString());
// 更新显示正在绘制的纵轴
DrawLineInCanvas(_mouseStartPos, mousePosInCanvas, EnumCanvasLineType.Vertical, EnumCanvasItemType.Drawing, "drawing");
break;
}
}
else
{
if (_mouseLeftBtnPressed)
{
Canvas_MouseLeftBtnUp(MyCanvasDraw, new MouseButtonEventArgs(e.MouseDevice, e.Timestamp, MouseButton.Left));
}
}
}
#endregion
#region public funcs
///
/// 设置该图像的病灶
///
///
///
public void SetLesions(string imgId, List lesions)
{
try
{
SQLiteConnection dbCon = new SQLiteConnection("Data Source=" + _dbPath);
dbCon.Open();
SQLiteCommand dbCmd;
dbCmd = dbCon.CreateCommand();
string strLesions = JsonConvert.SerializeObject(lesions);
dbCmd.CommandText = "update LesionDesGTDatas set Lesions='" + strLesions + "' where ImageId='" + imgId + "'";
dbCmd.ExecuteNonQuery();
dbCmd.Dispose();
SQLiteDataReader dbreader;
dbCmd = dbCon.CreateCommand();
dbCmd.CommandText = "select * from LastModification";
dbreader = dbCmd.ExecuteReader();
if (dbreader.HasRows)
{
dbreader.Close();
dbCmd.Dispose();
// 更新
dbCmd = dbCon.CreateCommand();
dbCmd.CommandText = "update LastModification set ImageId='" + imgId + "'";
dbCmd.ExecuteNonQuery();
dbCmd.Dispose();
}
else
{
// 新增
dbCmd = dbCon.CreateCommand();
dbCmd.CommandText = "insert into LastModification(ImageId) select '" + imgId + "'";
dbCmd.ExecuteNonQuery();
dbCmd.Dispose();
}
dbCon.Close();
dbCon.Dispose();
}
catch (Exception excep)
{
System.Windows.MessageBox.Show("保存结果时出错!" + excep);
}
}
///
/// 保存label
///
///
///
public void SetLesionsLabels(string imgId, List lesionsLabels)
{
try
{
SQLiteConnection dbCon = new SQLiteConnection("Data Source=" + _dbPath);
dbCon.Open();
SQLiteCommand dbCmd;
dbCmd = dbCon.CreateCommand();
string strLesionsLabel = JsonConvert.SerializeObject(lesionsLabels);
dbCmd.CommandText = "update LesionDesGTDatas set Label='" + strLesionsLabel + "' where ImageId='" + imgId + "'";
dbCmd.ExecuteNonQuery();
dbCmd.Dispose();
SQLiteDataReader dbreader;
dbCmd = dbCon.CreateCommand();
dbCmd.CommandText = "select * from LastModification";
dbreader = dbCmd.ExecuteReader();
if (dbreader.HasRows)
{
dbreader.Close();
dbCmd.Dispose();
// 更新
dbCmd = dbCon.CreateCommand();
dbCmd.CommandText = "update LastModification set ImageId='" + imgId + "'";
dbCmd.ExecuteNonQuery();
dbCmd.Dispose();
}
else
{
// 新增
dbCmd = dbCon.CreateCommand();
dbCmd.CommandText = "insert into LastModification(ImageId) select '" + imgId + "'";
dbCmd.ExecuteNonQuery();
dbCmd.Dispose();
}
dbCon.Close();
dbCon.Dispose();
}
catch (Exception excep)
{
System.Windows.MessageBox.Show("保存病灶分级时出错!" + excep);
}
}
#endregion
#region private funcs
private string ComputeHashCode(byte[] input)
{
MD5 md5 = MD5.Create();
byte[] hash = md5.ComputeHash(input);
StringBuilder sb = new StringBuilder();
foreach (var b in hash)
{
sb.Append(b.ToString("x2"));
}
string hashstr = sb.ToString();
sb.Clear();
return hashstr;
}
///
/// 读入数据库
///
private void ReadDataBase()
{
try
{
if (!File.Exists(_dbPath))
{
System.Windows.MessageBox.Show("未找到存放待标注数据的文件:" + _dbPath);
return;
}
SQLiteConnection dbCon = new SQLiteConnection("Data Source=" + _dbPath);
dbCon.Open();
SQLiteCommand dbCmd;
dbCmd = dbCon.CreateCommand();
dbCmd.CommandText = "select * from LesionDesGTDatas";
SQLiteDataReader dbReader;
dbReader = dbCmd.ExecuteReader();
if (!dbReader.HasRows)
{
dbReader.Close();
dbCmd.Dispose();
dbCon.Close();
dbCon.Dispose();
System.Windows.MessageBox.Show("待标注的数据为空.");
return;
}
int index = 0;
while (dbReader.Read())
{
string imgId = ((string)dbReader[0]).TrimEnd();
string strLesions = ((string)dbReader[1]).TrimEnd();
List lesions = JsonConvert.DeserializeObject>(strLesions);
string strLesionsLabels = ((string)dbReader[2]).TrimEnd();
List lesionsLabels = JsonConvert.DeserializeObject>(strLesionsLabels);
index += 1;
_allImages.Add(new LesionDesGTImgInfo { ImageId = imgId, Lesions = lesions , Label = lesionsLabels });
}
dbReader.Close();
dbCmd.Dispose();
dbCmd = dbCon.CreateCommand();
dbCmd.CommandText = "select * from LastModification";
dbReader = dbCmd.ExecuteReader();
if (!dbReader.HasRows)
{
_imgIndex = 0;
}
else
{
dbReader.Read();
string imgId = ((string)dbReader[0]).TrimEnd();
int imgIndex = _allImages.FindIndex(x => x.ImageId == imgId);
if (imgIndex == -1)
{
_imgIndex = 0;
}
else
{
_imgIndex = imgIndex;
}
}
dbReader.Close();
dbCmd.Dispose();
dbCon.Close();
dbCon.Dispose();
if (_allImages.Count > 0)
{
CurrentImgIndexUpdated();
}
}
catch (Exception excep)
{
System.Windows.MessageBox.Show("读入数据库时出错:" + excep);
}
}
///
/// 更新画布上显示的图像
///
private void ImageUpdated()
{
if (null == _drawimg)
{
return;
}
if (null == _origimg)
{
return;
}
// 计算缩放比例
double ratioW = GridDrawImg.ActualWidth / _drawimg.Width;
double ratioH = GridDrawImg.ActualHeight / _drawimg.Height;
double ratio = ratioW < ratioH ? ratioW : ratioH;
DrawImgScaleTramsform.CenterX = 0;
DrawImgScaleTramsform.CenterY = 0;
DrawImgScaleTramsform.ScaleX = ratio;
DrawImgScaleTramsform.ScaleY = ratio;
OrigImgScaleTramsform.CenterX = 0;
OrigImgScaleTramsform.CenterY = 0;
OrigImgScaleTramsform.ScaleX = ratio;
OrigImgScaleTramsform.ScaleY = ratio;
// 使图像居中,需要平移
double translateX = 0;
double translateY = 0;
if (Math.Abs(ratio - ratioW) < 0.0001)
{
translateY = 0.5 * (ratioH - ratio) * _drawimg.Height;
}
else
{
translateX = 0.5 * (ratioW - ratio) * _drawimg.Width;
}
// 更新画布尺寸,使其刚好只覆盖图像区域
MyCanvasDraw.Width = ratio * _drawimg.Width;
MyCanvasDraw.Height = ratio * _drawimg.Height;
Canvas.SetLeft(MyCanvasDraw, translateX);
Canvas.SetTop(MyCanvasDraw, translateY);
MyCanvasDraw.ClipToBounds = true;
MyCanvas.Width = ratio * _drawimg.Width;
MyCanvas.Height = ratio * _drawimg.Height;
Canvas.SetLeft(MyCanvas, translateX);
Canvas.SetTop(MyCanvas, translateY);
DrawImage.Source = _drawimg;
OrigImage.Source = _origimg;
if (_dstImgWin == null || CheckModelResult.IsChecked.Value == false)
{
OrigImage.Source = _origimg;
}
else
{
OrigImage.Source = _dstImgWin;
}
//if(_dstImgWin != null)
//{
// DrawImage.Source = _dstImgWin;
//}
}
///
/// 更新显示已有的轮廓
///
private void UpdateLesionsInCanvas()
{
if (_drawimg == null)
{
return;
}
RemoveContourInCanvas("drawing");
RemoveLineInCanvas(EnumCanvasLineType.Horizontal, "drawing");
RemoveLineInCanvas(EnumCanvasLineType.Vertical, "drawing");
// 显示新的病灶
if (_showDrawingResult)
{
for (int ni = 0; ni < _lesions.Count; ni++)
{
// 显示病灶轮廓, 注意,所有点需转到Canvas坐标系下
List contour = _lesions[ni].Contour;
if (contour.Count > 0)
{
List contourInCanvas = new List();
for (int nj = 0; nj < contour.Count; nj++)
{
contourInCanvas.Add(GetPosInCanvas(contour[nj]));
}
if (ni == _lesionIndex)
{
DrawContourInCanvas(contourInCanvas, EnumCanvasItemType.Choosed, ni.ToString());
}
else
{
DrawContourInCanvas(contourInCanvas, EnumCanvasItemType.Existed, ni.ToString());
}
}
// 显示病灶横轴,注意,所有点需转到Canvas坐标系下
Point2D hP1 = _lesions[ni].HorizontalPoint1;
Point2D hP2 = _lesions[ni].HorizontalPoint2;
if (hP1 != null && hP2 != null)
{
System.Windows.Point hP1InCanvas = GetPosInCanvas(hP1);
System.Windows.Point hP2InCanvas = GetPosInCanvas(hP2);
if (ni == _lesionIndex)
{
DrawLineInCanvas(hP1InCanvas, hP2InCanvas, EnumCanvasLineType.Horizontal, EnumCanvasItemType.Choosed, ni.ToString());
}
else
{
DrawLineInCanvas(hP1InCanvas, hP2InCanvas, EnumCanvasLineType.Horizontal, EnumCanvasItemType.Existed, ni.ToString());
}
}
// 显示病灶纵轴,注意所有点需转到Canvas坐标系下
Point2D vP1 = _lesions[ni].VerticalPoint1;
Point2D vP2 = _lesions[ni].VerticalPoint2;
if (vP1 != null && vP2 != null)
{
System.Windows.Point vP1InCanvas = GetPosInCanvas(vP1);
System.Windows.Point vP2InCanvas = GetPosInCanvas(vP2);
if (ni == _lesionIndex)
{
DrawLineInCanvas(vP1InCanvas, vP2InCanvas, EnumCanvasLineType.Vertical, EnumCanvasItemType.Choosed, ni.ToString());
}
else
{
DrawLineInCanvas(vP1InCanvas, vP2InCanvas, EnumCanvasLineType.Vertical, EnumCanvasItemType.Existed, ni.ToString());
}
}
}
}
}
///
/// 更新显示已有的病灶分级
///
private void UpdateLesionsIndex()
{
ComboBoxLesionsLabel.SelectedIndex = -1;
for (int ni = 0; ni < _lesionsLabels.Count; ni++)
{
if (ni == _lesionIndex)
{
ComboBoxLesionsLabel.SelectedIndex = _lesionsLabels[ni];
}
else
{
//ComboBoxLesionsLabel.SelectedIndex = -1;
}
}
//ComboBoxLesionsLabel.SelectedIndex = _lesionsLabels[_lesionIndex];
}
///
/// 绘制轮廓
///
///
///
///
private void DrawContourInCanvas(List contour, EnumCanvasItemType type, string name)
{
if (_drawimg == null)
{
return;
}
RemoveContourInCanvas(name);
Polyline contourLines = new Polyline
{
StrokeThickness = 1,
Stroke = GetContourBrushColor(type),
Points = new System.Windows.Media.PointCollection(contour)
};
MyCanvasDraw.Children.Add(contourLines);
MyCanvasDraw.RegisterName("Contour_" + name, contourLines);
}
///
/// 清除已绘制的轮廓
///
///
private void RemoveContourInCanvas(string name)
{
string contourName = "Contour_" + name;
if (MyCanvasDraw.FindName(contourName) is Polyline contourExists)
{
MyCanvasDraw.Children.Remove(contourExists);
MyCanvasDraw.UnregisterName(contourName);
}
}
///
/// 画线
///
///
///
///
///
///
private void DrawLineInCanvas(System.Windows.Point startPos, System.Windows.Point endPos, EnumCanvasLineType lineType,
EnumCanvasItemType type, string name)
{
if (_drawimg == null)
{
return;
}
RemoveLineInCanvas(lineType, name);
System.Windows.Shapes.Line line = new System.Windows.Shapes.Line
{
X1 = startPos.X,
Y1 = startPos.Y,
X2 = endPos.X,
Y2 = endPos.Y,
StrokeThickness = 1,
Stroke = GetLineBrushColor(type, lineType)
};
MyCanvasDraw.Children.Add(line);
string lineName;
if (lineType == EnumCanvasLineType.Horizontal)
{
lineName = "Line_H_" + name;
}
else
{
lineName = "Line_V_" + name;
}
MyCanvasDraw.RegisterName(lineName, line);
}
///
/// 移除已画的线
///
///
///
private void RemoveLineInCanvas(EnumCanvasLineType lineType, string name)
{
string lineName;
if (lineType == EnumCanvasLineType.Horizontal)
{
lineName = "Line_H_" + name;
}
else
{
lineName = "Line_V_" + name;
}
if (MyCanvasDraw.FindName(lineName) is System.Windows.Shapes.Line lineExists)
{
MyCanvasDraw.Children.Remove(lineExists);
MyCanvasDraw.UnregisterName(lineName);
}
}
///
/// 设置横轴纵轴线的颜色
///
///
///
///
private System.Windows.Media.Brush GetLineBrushColor(EnumCanvasItemType itemType, EnumCanvasLineType lineType)
{
switch (itemType)
{
case EnumCanvasItemType.Drawing:
if (lineType == EnumCanvasLineType.Horizontal)
{
return System.Windows.Media.Brushes.DarkGreen;
}
else
{
return System.Windows.Media.Brushes.DarkBlue;
}
case EnumCanvasItemType.Existed:
if (lineType == EnumCanvasLineType.Horizontal)
{
return System.Windows.Media.Brushes.LightGreen;
}
else
{
return System.Windows.Media.Brushes.LightBlue;
}
default:
if (lineType == EnumCanvasLineType.Horizontal)
{
return System.Windows.Media.Brushes.Green;
}
else
{
return System.Windows.Media.Brushes.Blue;
}
}
}
///
/// 设置轮廓线的颜色
///
///
///
private System.Windows.Media.Brush GetContourBrushColor(EnumCanvasItemType itemType)
{
switch (itemType)
{
case EnumCanvasItemType.Drawing:
return System.Windows.Media.Brushes.OrangeRed;
case EnumCanvasItemType.Existed:
return System.Windows.Media.Brushes.LightYellow;
default:
return System.Windows.Media.Brushes.Orange;
}
}
///
/// 更新该图上的病灶
///
private void LesionsUpdated()
{
ComboBoxLesions.SelectionChanged -= OnLesionSelectionChanged;
ComboBoxLesions.Items.Clear();
for (int ni = 0; ni < _lesions.Count; ni++)
{
ComboBoxLesions.Items.Add("病灶 " + ni.ToString());
}
if (ComboBoxLesions.SelectedIndex != _lesionIndex)
{
ComboBoxLesions.SelectedIndex = _lesionIndex;
}
if (_lesionIndex < 0)
{
UserControlLesionSelected.SetLesionEmpty();
}
else
{
UserControlLesionSelected.SetLesion(_lesions[_lesionIndex]);
}
ComboBoxLesions.SelectionChanged += OnLesionSelectionChanged;
UpdateLesionsInCanvas();
UpdateLesionsIndex();
}
///
/// 要加载的图像序号发生了改变
///
private void CurrentImgIndexUpdated()
{
if (_imgIndex < 0 || _imgIndex >= _allImages.Count /*- 1*/)
{
throw new ArgumentOutOfRangeException("待更新的图像序号超出范围.");
}
TextBlockCurrentIndex.Text = _imgIndex.ToString();
LesionDesGTImgInfo imgInfo = _allImages[_imgIndex];
string imgPath = System.IO.Path.Combine(_imageDataFolder, imgInfo.ImageId + ".jpg");
//string imgPath = imgInfo.ImageId;
if (!File.Exists(imgPath))
{
throw new FileNotFoundException("找不到文件:" + imgPath);
}
_image = new Bitmap(imgPath);
_drawimg = RawImageShowUtils.BitmapToBitmapImage(_image);
_origimg = RawImageShowUtils.BitmapToBitmapImage(_image);
//image.Dispose();
ImageUpdated();
// 先清除所有已有显示
for (int ni = 0; ni < _lesions.Count; ni++)
{
RemoveContourInCanvas(ni.ToString());
RemoveLineInCanvas(EnumCanvasLineType.Horizontal, ni.ToString());
RemoveLineInCanvas(EnumCanvasLineType.Vertical, ni.ToString());
}
int num = _drawingPoints.Count;
if (num > 0)
{
// 更新显示正在绘制的轮廓线
RemoveContourInCanvasForDrawPts("drawingPt");
}
// 再更新
_lesions = imgInfo.Lesions;
_lesionsLabels = imgInfo.Label;
_modified = false;
if (_lesions.Count <= 0)
{
_lesionIndex = -1;
ComboBoxLesionsLabel.SelectedIndex = -1;
}
else
{
_lesionIndex = 0;
ComboBoxLesionsLabel.SelectedIndex = _lesionsLabels[_lesionIndex];
}
LesionsUpdated();
}
///
/// 收到LesionInfoSelector发来的事件
///
///
///
private void OnLesionInfoSelectorEventOccur(object sender, LesionInfoEventArgs e)
{
switch (e.EventType)
{
case EnumLesionInfoEventType.LesionInfoUpdated:
_modified = true;
if (_lesions.Count <= 0 && _lesionIndex < 0)
{
_lesions.Add(UserControlLesionSelected.Lesion);
_lesionIndex = 0;
_lesionsLabels.Add(-1);
}
else
{
_lesions[_lesionIndex] = UserControlLesionSelected.Lesion;
//_lesionsLabels.Add(-1);
}
LesionsUpdated();
break;
case EnumLesionInfoEventType.DrawContour:
_mouseOper = EnumMouseOperType.DrawingContour;
break;
case EnumLesionInfoEventType.DrawHorizontal:
_mouseOper = EnumMouseOperType.DrawingHorizonLines;
break;
case EnumLesionInfoEventType.DrawVertical:
_mouseOper = EnumMouseOperType.DrawingVerticalLines;
break;
case EnumLesionInfoEventType.DrawPoint:
_mouseOper = EnumMouseOperType.DrawingPoint;
break;
}
}
///
/// 将Canvas上的点转换到图像坐标系下
///
///
///
private Point2D GetPosInOrigImage(System.Windows.Point posInCanvas)
{
if (_drawimg != null)
{
int x = Convert.ToInt32(posInCanvas.X / MyCanvasDraw.Width * _drawimg.Width);
int y = Convert.ToInt32(posInCanvas.Y / MyCanvasDraw.Height * _drawimg.Height);
return new Point2D(x, y);
}
else
{
return new Point2D(0, 0);
}
}
///
/// 将图像上的点转换到Canvas坐标系下
///
///
///
private System.Windows.Point GetPosInCanvas(Point2D posInOrigImg)
{
if (_drawimg != null)
{
int x = Convert.ToInt32(posInOrigImg.X / _drawimg.Width * MyCanvasDraw.Width);
int y = Convert.ToInt32(posInOrigImg.Y / _drawimg.Height * MyCanvasDraw.Height);
return new System.Windows.Point(x, y);
}
else
{
return new System.Windows.Point(0, 0);
}
}
///
/// 计算两点之间的距离
///
///
///
///
private double PointDistance(System.Windows.Point point1, System.Windows.Point point2)
{
return Math.Sqrt(Math.Pow(point1.X - point2.X, 2) + Math.Pow(point1.Y - point2.Y, 2));
}
#endregion
#region 创建标准描述数据库相关的函数
///
/// 创建数据库
///
private bool CreateDataBase()
{
if (File.Exists(_dbPath))
{
//throw new Exception("数据库已存在,请检查.");
return false ;
}
// 创建数据库文件
SQLiteConnection dbCon = new SQLiteConnection("Data Source=" + _dbPath);
dbCon.Open();
SQLiteCommand dbCmd;
dbCmd = dbCon.CreateCommand();
dbCmd.CommandText = "create table if not exists LesionDesGTDatas(ImageId varchar(16),Lesions varchar(16),Label varchar(16))";
dbCmd.ExecuteNonQuery();
dbCmd.Dispose();
dbCmd = dbCon.CreateCommand();
dbCmd.CommandText = "create table if not exists LastModification(ImageId varchar(16))";
dbCmd.ExecuteNonQuery();
dbCmd.Dispose();
dbCon.Close();
dbCon.Dispose();
return true;
}
///
/// 添加新的图像到数据集里
///
///
private void AddNewImages(string origImageFolder)
{
// 如果文件夹不存在,则创建
if (!Directory.Exists(_imageDataFolder))
{
Directory.CreateDirectory(_imageDataFolder);
}
// 已有多少图片
SQLiteConnection dbCon = new SQLiteConnection("Data Source=" + _dbPath);
dbCon.Open();
SQLiteCommand dbCmd;
SQLiteDataReader dbReader;
// 遍历该文件夹下所有图片
DirectoryInfo origImgDir = new DirectoryInfo(origImageFolder);
FileInfo[] files = origImgDir.GetFiles();
foreach (var file in files)
{
Bitmap image = new Bitmap(file.FullName);
RawImage rawImg = RawImageShowUtils.BitmapToRawImage(image);
//string hashCode = ComputeHashCode(rawImg.DataBuffer);
string temp;
int idx = file.FullName.LastIndexOf("\\");
temp = file.FullName.Substring(idx);
string[] strs1 = temp.Split('\\');
temp = strs1[1];
string[] strs2 = System.Text.RegularExpressions.Regex.Split(temp, ".jpg", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
string ImgId = strs2[0];
string hashCode = ImgId;
image.Dispose();
rawImg.Dispose();
// 查找该图片是否已经存在
dbCmd = dbCon.CreateCommand();
dbCmd.CommandText = "select * from LesionDesGTDatas where ImageId='" + hashCode + "'";
dbReader = dbCmd.ExecuteReader();
if (dbReader.HasRows)
{
dbReader.Close();
dbCmd.Dispose();
continue;
}
// 以哈希值作为该图片的id,同时也作为图像名,复制原始图像到指定目录下
//string imgdstPath = System.IO.Path.Combine(_imageDataFolder, hashCode + ".jpg");
//File.Copy(file.FullName, imgdstPath);
// 将该图相关信息存到数据库里
List lesions = new List();
string strLesions = JsonConvert.SerializeObject(lesions);
List LesionsLabel = new List();
string strLesionsLabel = JsonConvert.SerializeObject(LesionsLabel);
dbCmd = dbCon.CreateCommand();
dbCmd.CommandText = "insert into LesionDesGTDatas(ImageId,Lesions,Label) select '" + hashCode + "','" + strLesions + "','" + strLesionsLabel + "'";
dbCmd.ExecuteNonQuery();
dbCmd.Dispose();
}
dbCon.Close();
dbCon.Dispose();
}
#endregion
private void OnBtnModelImageClicked(object sender, RoutedEventArgs e)
{
if(_image != null)
{
DetectImage(_image);
}
}
///
/// 使用模型检测,并显示在标注结果界面上
///
///
private void DetectImage(Bitmap image)
{
string name = _allImages[_imgIndex].ImageId;
RawImage rawImg = null;
//rawImg = RawImageShowUtils.BitmapToRawImage(image);
var rawImage = RawImageShowUtils.BitmapToRawImage(image);
_caseId = Guid.NewGuid().ToString();
_dataId = name;
_readingVideo = false;
var extendData = new Dictionary();
extendData.Add("CaseId", _caseId);
extendData.Add("DataId", _dataId);
extendData.Add("IsVideo", _readingVideo);
extendData.Add("TimeStamp", (double)_frameIndex);
_processId = _module.StartProcess();
var input = new ImageInputData(rawImage, extendData);
IDetectedObject[] result = _module.PushOnePieceOfData(_processId, input);
_newModelResult = result;
_module.EndProcess(_processId);
//var diagResult = _diagSystem.EvaluateOneImage(rawImg);
if(result != null)
{
var dstimage = ShowDiagResultsOnImage(image, result);//
ModelResultShow();
_dstImgWin = RawImageShowUtils.BitmapToBitmapImage(dstimage);
Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
{
if (_dstImgWin == null || CheckModelResult.IsChecked.Value == false)
{
OrigImage.Source = _origimg;
}
else
{
OrigImage.Source = _dstImgWin;
}
}
));
dstimage.Dispose();
}
else
{
System.Windows.MessageBox.Show("模型检测失败");
}
}
private Bitmap ShowDiagResultsOnImage(Bitmap image, IDetectedObject[] diagResult)
{
int breastLesionNum = 0;
Bitmap dstimage = image.Clone(new System.Drawing.Rectangle(0, 0, image.Width, image.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
//var organGt = diagResult.DiagResultsForEachOrgan;
foreach (var resultsPerOrgan in diagResult)
{
var Ilabel = resultsPerOrgan.Label;
var nameOrgan = Ilabel.GroupName;
int indexLabel = Ilabel.Index;
if (nameOrgan != "AI.Vaid.Breast.Lesion")
{
continue;
}
//if (resultsPerOrgan.Organ == EnumOrgans.Breast)
{
using (var g = Graphics.FromImage(dstimage))
{
int num = 0;
string strDescriptionShape = string.Empty;
string strDescriptionOrientation = string.Empty;
string strDescriptionEcho = string.Empty;
string strDescriptionBound = string.Empty;
string strDescriptionMargin = string.Empty;
System.Drawing.Brush brush = System.Drawing.Brushes.Green;
List CurImageLesion = new List();
if (_modelResult != null)
{
_modelResult = null;
_modelResult = new LesionDesGTImgInfo();
_modelResult.Lesions = new List();
_modelResult.Label = new List();
}
var resultConversion = AIModuleResultShowUtils.GetObjectStr(resultsPerOrgan);
if (resultsPerOrgan.Contour?.Contours.Length > 0)
{
//ShowContour(moduleResult.Contour, brush, null, transform);
int count = resultsPerOrgan.Contour.Contours.Length;
LesionInfo lesion = new LesionInfo();
for (int i = 0; i < count; i++)
{
var contourPoints = resultsPerOrgan.Contour.Contours[i];
int pointCount = contourPoints.Points.Length;
//var points = new List();
System.Drawing.PointF[] lesionContour = new PointF[pointCount];
List points = new List();
for (int j = 0; j < pointCount; j++)
{
var point = new System.Windows.Point(contourPoints.Points[j].X, contourPoints.Points[j].Y);
lesionContour[j].X = contourPoints.Points[j].X;
lesionContour[j].Y = contourPoints.Points[j].Y;
Point2D pt = new Point2D(contourPoints.Points[j].X, contourPoints.Points[j].Y);
points.Add(pt);
lesion.Contour.Add(pt);
}
g.DrawPolygon(new System.Drawing.Pen(brush, 2), lesionContour);
var desResult = resultsPerOrgan.Description;
var type = desResult.GetType();
string strDescription = string.Empty;
//if (type == typeof(BreastLesionDescription))
{
foreach (var key in desResult.Descriptions.Keys)
{
if (key == "Shape")
{
EnumDesShapeValue sss = new EnumDesShapeValue();
string des = string.Empty;
switch (desResult.Descriptions[key])
{
case "Oval":
des = "椭圆形";
sss = EnumDesShapeValue.Oval;
break;
case "Round":
des = "类圆形";
sss = EnumDesShapeValue.Round;
break;
case "Irregular":
des = "不规则形";
sss = EnumDesShapeValue.Irregular;
break;
}
lesion.Shape = sss;
strDescription += "形状:" + des + Environment.NewLine;
}
if (key == "Orientation")
{
EnumDesOrientationValue sss = new EnumDesOrientationValue();
string des = string.Empty;
switch (desResult.Descriptions[key])
{
case "Parallel":
des = "平行";
sss = EnumDesOrientationValue.Parallel;
break;
case "NonParallel":
des = "非平行";
sss = EnumDesOrientationValue.NonParallel;
break;
}
lesion.Orientation = sss;
strDescription += "生长方向:" + des + Environment.NewLine;
}
if (key == "EchoPattern")
{
EnumDesEchoPatternValue sss = new EnumDesEchoPatternValue();
string des = string.Empty;
switch (desResult.Descriptions[key])
{
case "Anechoic":
des = "无回声";
sss = EnumDesEchoPatternValue.Anechoic;
break;
case "Hypoechoic":
des = "低回声";
sss = EnumDesEchoPatternValue.Hypoechoic;
break;
case "Isoechoic":
des = "等回声";
sss = EnumDesEchoPatternValue.Isoechoic;
break;
case "Hyperechoic":
des = "高回声";
sss = EnumDesEchoPatternValue.Hyperechoic;
break;
case "Complex":
des = "混合回声";
sss = EnumDesEchoPatternValue.Complex;
break;
}
lesion.EchoPattern = sss;
strDescription += "回声类型:" + des + Environment.NewLine;
}
if (key == "Boundary")
{
EnumDesLesionBoundaryValue sss = new EnumDesLesionBoundaryValue();
string des = string.Empty;
switch (desResult.Descriptions[key])
{
case "AbruptInterface":
des = "清晰";
sss = EnumDesLesionBoundaryValue.AbruptInterface;
break;
case "EchogenicHalo":
des = "模糊";
sss = EnumDesLesionBoundaryValue.EchogenicHalo;
break;
}
lesion.Boundary = sss;
strDescription += "边界:" + des + Environment.NewLine;
}
if (key == "Margin")
{
EnumDesMarginValue sss = new EnumDesMarginValue();
string des = string.Empty;
switch (desResult.Descriptions[key])
{
case "Circumscribed":
des = "光整";
sss = EnumDesMarginValue.Circumscribed;
break;
case "NonCircumscribed":
des = "不光整";
sss = EnumDesMarginValue.NonCircumscribed;
break;
}
lesion.Margin = sss;
strDescription += "边缘:" + des + Environment.NewLine;
}
}
}
var rect = resultsPerOrgan.BoundingBox.Contour.BoundingBox();
var roiBox = resultsPerOrgan.BoundingBox;
var ss = roiBox.Contour.Points;
var lesionSize = Array.Find(resultsPerOrgan.Measurements, x => x.GetType() == typeof(TransverseLongitudinalDiameterMeasurement));
var size = (TransverseLongitudinalDiameterMeasurement)lesionSize;
var pointLineH1 = new System.Windows.Point(size.TransverseDiameterMarkPosition.LineStart.X, size.TransverseDiameterMarkPosition.LineStart.Y);
var pointLineH2 = new System.Windows.Point(size.TransverseDiameterMarkPosition.LineEnd.X, size.TransverseDiameterMarkPosition.LineEnd.Y);
var pointLineV1 = new System.Windows.Point(size.LongitudinalDiameterMarkPosition.LineStart.X, size.LongitudinalDiameterMarkPosition.LineStart.Y);
var pointLineV2 = new System.Windows.Point(size.LongitudinalDiameterMarkPosition.LineEnd.X, size.LongitudinalDiameterMarkPosition.LineEnd.Y);
System.Drawing.Point[] axisH = new System.Drawing.Point[2];
System.Drawing.Point[] axisV = new System.Drawing.Point[2];
axisH[0].X = (int)pointLineH1.X;
axisH[0].Y = (int)pointLineH1.Y;
axisH[1].X = (int)pointLineH2.X;
axisH[1].Y = (int)pointLineH2.Y;
axisV[0].X = (int)pointLineV1.X;
axisV[0].Y = (int)pointLineV1.Y;
axisV[1].X = (int)pointLineV2.X;
axisV[1].Y = (int)pointLineV2.Y;
System.Drawing.Pen pen_h = new System.Drawing.Pen(System.Drawing.Brushes.PaleGreen, 2);
g.DrawLines(pen_h, axisH); //横轴,浅绿色
System.Drawing.Pen pen_v = new System.Drawing.Pen(System.Drawing.Brushes.Red, 1);
g.DrawLines(pen_v, axisV); //纵轴,红色
var Measurements = resultsPerOrgan.Measurements;
var len = Measurements.Length;
if(len > 0)
{
var marks = Measurements[0].MeasureMarks;
int lenM = marks.Length;
var con = marks[0].Contour.Points;
int numC = con.Length;
}
}
_modelResult.Lesions.Add(lesion);
_modelResult.Label.Add(indexLabel);
num++;
}
g.Dispose();
}
}
}
if (breastLesionNum == 0)
{
//MessageBox.Show("未检测出病灶");
}
else
{
_lesionOriModelIndex = 0;
ModelComboBoxOriUpdated();
}
return dstimage;
}
///
/// 复制模型结果
///
///
///
private void OnBtnCopyModelResultClicked(object sender, RoutedEventArgs e)
{
// 保存当前图的结果
//_modified = true;
//if (_modified)
{
if(_allImages[_imgIndex].Lesions.Count > 0)
{
System.Windows.MessageBox.Show("已存在病灶信息,请先删除右图标注数据");
return;
}
if(_modelResult.Lesions.Count > 0)
{
if (_modelResult.Lesions[0].Contour.Count >0)
{
_lesions = _modelResult.Lesions;
_lesionsLabels = _modelResult.Label;// _lesionsModelLabels;
_allImages[_imgIndex].Lesions = _lesions;
_allImages[_imgIndex].Label = _lesionsLabels;
CopyModelToCurrentImgUpdated();
_lesionIndex = ComboBoxLesions.SelectedIndex;
//_lesionsLabels = _lesionsModelLabels; //分级
ComboBoxLesionsLabel.SelectedIndex = _lesionsLabels[_lesionIndex] ;
_modified = true;
}
}
else
{
if (_image != null)
{
DetectImage(_image);
}
if (_modelResult.Lesions[0].Contour.Count > 0)
{
_lesions = _modelResult.Lesions;
_lesionsLabels = _modelResult.Label;// _lesionsModelLabels;
_allImages[_imgIndex].Lesions = _lesions;
_allImages[_imgIndex].Label = _lesionsLabels;
CopyModelToCurrentImgUpdated();
_lesionIndex = ComboBoxLesions.SelectedIndex;
//_lesionsLabels = _lesionsModelLabels; //分级
ComboBoxLesionsLabel.SelectedIndex = _lesionsLabels[_lesionIndex];
_modified = true;
}
return;
}
}
}
///
/// 复制模型结果显示到右边界面
///
private void CopyModelToCurrentImgUpdated()
{
if (_imgIndex < 0 || _imgIndex >= _allImages.Count/* - 1*/)
{
throw new ArgumentOutOfRangeException("待更新的图像序号超出范围.");
}
TextBlockCurrentIndex.Text = _imgIndex.ToString();
LesionDesGTImgInfo imgInfo = _allImages[_imgIndex];
string imgPath = System.IO.Path.Combine(_imageDataFolder, imgInfo.ImageId + ".jpg");
//string imgPath = imgInfo.ImageId;
if (!File.Exists(imgPath))
{
throw new FileNotFoundException("找不到文件:" + imgPath);
}
_image = new Bitmap(imgPath);
_drawimg = RawImageShowUtils.BitmapToBitmapImage(_image);
_origimg = RawImageShowUtils.BitmapToBitmapImage(_image);
//image.Dispose();
ImageUpdated();
// 先清除所有已有显示
for (int ni = 0; ni < _lesions.Count; ni++)
{
RemoveContourInCanvas(ni.ToString());
RemoveLineInCanvas(EnumCanvasLineType.Horizontal, ni.ToString());
RemoveLineInCanvas(EnumCanvasLineType.Vertical, ni.ToString());
}
// 再更新
if (_lesions.Count <= 0)
{
_lesionIndex = -1;
}
else
{
_lesionIndex = 0;
}
ModelLesionsUpdated();
}
///
/// 将模型结果更新到图上的病灶
///
private void ModelLesionsUpdated()
{
ComboBoxLesions.SelectionChanged -= OnLesionSelectionChanged;
ComboBoxLesions.Items.Clear();
for (int ni = 0; ni < _modelResult.Lesions.Count; ni++)
{
ComboBoxLesions.Items.Add("病灶 " + ni.ToString());
}
if (ComboBoxLesions.SelectedIndex != _lesionIndex)
{
ComboBoxLesions.SelectedIndex = _lesionIndex;
}
_lesionIndex = 0;//强制为0
if (_lesionIndex < 0)
{
UserControlLesionSelected.SetLesionEmpty();
}
else
{
//病灶数据此时由模型给出,将病灶信息赋给LesionInfoSelector::UserControlLesionSelected
UserControlLesionSelected.SetLesion(_modelResult.Lesions[_lesionIndex]);
}
ComboBoxLesions.SelectionChanged += OnLesionSelectionChanged;
UpdateModelLesionsInCanvas();
//_lesionIndex = -1;
}
///
/// 更新显示已有的轮廓
///
private void UpdateModelLesionsInCanvas()
{
if (_drawimg == null)
{
return;
}
RemoveContourInCanvas("drawing");
RemoveLineInCanvas(EnumCanvasLineType.Horizontal, "drawing");
RemoveLineInCanvas(EnumCanvasLineType.Vertical, "drawing");
// 显示新的病灶
if(_showDrawingResult)
{
for (int ni = 0; ni < _modelResult.Lesions.Count; ni++)
{
// 显示病灶轮廓, 注意,所有点需转到Canvas坐标系下
List contour = _modelResult.Lesions[ni].Contour;
if (contour.Count > 0)
{
List contourInCanvas = new List();
for (int nj = 0; nj < contour.Count; nj++)
{
contourInCanvas.Add(GetPosInCanvas(contour[nj]));
}
if (ni == _lesionIndex)
{
DrawContourInCanvas(contourInCanvas, EnumCanvasItemType.Choosed, ni.ToString());
}
else
{
DrawContourInCanvas(contourInCanvas, EnumCanvasItemType.Existed, ni.ToString());
}
}
// 显示病灶横轴,注意,所有点需转到Canvas坐标系下
Point2D hP1 = _modelResult.Lesions[ni].HorizontalPoint1;
Point2D hP2 = _modelResult.Lesions[ni].HorizontalPoint2;
if (hP1 != null && hP2 != null)
{
System.Windows.Point hP1InCanvas = GetPosInCanvas(hP1);
System.Windows.Point hP2InCanvas = GetPosInCanvas(hP2);
if (ni == _lesionIndex)
{
DrawLineInCanvas(hP1InCanvas, hP2InCanvas, EnumCanvasLineType.Horizontal, EnumCanvasItemType.Choosed, ni.ToString());
}
else
{
DrawLineInCanvas(hP1InCanvas, hP2InCanvas, EnumCanvasLineType.Horizontal, EnumCanvasItemType.Existed, ni.ToString());
}
}
// 显示病灶纵轴,注意所有点需转到Canvas坐标系下
Point2D vP1 = _modelResult.Lesions[ni].VerticalPoint1;
Point2D vP2 = _modelResult.Lesions[ni].VerticalPoint2;
if (vP1 != null && vP2 != null)
{
System.Windows.Point vP1InCanvas = GetPosInCanvas(vP1);
System.Windows.Point vP2InCanvas = GetPosInCanvas(vP2);
if (ni == _lesionIndex)
{
DrawLineInCanvas(vP1InCanvas, vP2InCanvas, EnumCanvasLineType.Vertical, EnumCanvasItemType.Choosed, ni.ToString());
}
else
{
DrawLineInCanvas(vP1InCanvas, vP2InCanvas, EnumCanvasLineType.Vertical, EnumCanvasItemType.Existed, ni.ToString());
}
}
}
}
}
///
/// 将模型检测出的结果,显示在AI结果界面上
///
//private void ShowModelResult()
//{
// if (_image != null)
// {
// DetectImage(_image);
// if (_modelResult.Lesions.Count > 0)
// {
// _lesions = _modelResult.Lesions;
// _lesionsLabels = _modelResult.Label;// _lesionsModelLabels;
// if (_lesions.Count <= 0)
// {
// _lesionIndex = -1;
// }
// else
// {
// _lesionIndex = 0;
// }
// ComboBoxLesions.SelectedIndex = _lesionIndex;
// ModelLesionsUpdated();
// //_lesionIndex = ComboBoxLesions.SelectedIndex;
// }
// }
//}
private void OnCheckedCheckModelResult(object sender, RoutedEventArgs e)
{
_showModelResult = true;
OrigImage.Source = _dstImgWin;
}
private void OnUncheckedCheckModelResult(object sender, RoutedEventArgs e)
{
_showModelResult = false;
OrigImage.Source = _origimg;
}
private void OnModelLesionSelectionChanged(object sender, SelectionChangedEventArgs e)
{
_lesionOriModelIndex = ComboBoxOriLesions.SelectedIndex;
ModelResultShow();
ModelComboBoxOriUpdated();
}
///
/// 显示对应的模型检测结果
///
private void ModelComboBoxOriUpdated()
{
ComboBoxOriLesions.SelectionChanged -= OnModelLesionSelectionChanged;
ComboBoxOriLesions.Items.Clear();
for (int ni = 0; ni < _modelResult.Lesions.Count; ni++)
{
ComboBoxOriLesions.Items.Add("病灶 " + ni.ToString());
}
if (ComboBoxOriLesions.SelectedIndex != _lesionOriModelIndex)
{
ComboBoxOriLesions.SelectedIndex = _lesionOriModelIndex;
}
ComboBoxOriLesions.SelectionChanged += OnModelLesionSelectionChanged;
//UpdateModelLesionsInCanvas();
}
private void ModelResultShow()
{
if (_modelResult.Lesions != null)
{
if (_modelResult.Lesions.Count > 0)
{
var lesionCur = _modelResult.Lesions[_lesionOriModelIndex];
int lesionLabel = _modelResult.Label[_lesionOriModelIndex];
string strLabel = string.Empty;
switch (lesionLabel)
{
case 0:
strLabel = "0";
break;
case 1:
strLabel = "脂肪瘤";
break;
case 2:
strLabel = "2级";
break;
case 3:
strLabel = "3级";
break;
case 4:
strLabel = "4a级";
break;
case 5:
strLabel = "4b级";
break;
case 6:
strLabel = "4c级";
break;
case 7:
strLabel = "5级";
break;
}
string strShape = string.Empty;
switch (lesionCur.Shape)
{
case EnumDesShapeValue.Oval:
strShape = "椭圆形";
break;
case EnumDesShapeValue.Round:
strShape = "圆形";
break;
case EnumDesShapeValue.Irregular:
strShape = "不规则";
break;
}
string strOrientation = string.Empty;
switch (lesionCur.Orientation)
{
case EnumDesOrientationValue.Parallel:
strOrientation = "平行";
break;
case EnumDesOrientationValue.NonParallel:
strOrientation = "非平行";
break;
}
string strMargin = string.Empty;
switch (lesionCur.Margin)
{
case EnumDesMarginValue.Circumscribed:
strMargin = "光整";
break;
case EnumDesMarginValue.NonCircumscribed:
strMargin = "不光整";
break;
}
string strEcho = string.Empty;
switch (lesionCur.EchoPattern)
{
case EnumDesEchoPatternValue.Anechoic:
strEcho = "无回声";
break;
case EnumDesEchoPatternValue.Hypoechoic:
strEcho = "低回声";
break;
case EnumDesEchoPatternValue.Hyperechoic:
strEcho = "高回声";
break;
case EnumDesEchoPatternValue.Strongechoic:
strEcho = "强回声";
break;
case EnumDesEchoPatternValue.Complex:
strEcho = "混合回声";
break;
case EnumDesEchoPatternValue.Isoechoic:
strEcho = "等回声";
break;
}
string strBound = string.Empty;
switch (lesionCur.Boundary)
{
case EnumDesLesionBoundaryValue.AbruptInterface:
strBound = "清晰";
break;
case EnumDesLesionBoundaryValue.EchogenicHalo:
strBound = "模糊";
break;
}
Point2D horPt1 = lesionCur.HorizontalPoint1;
Point2D horPt2 = lesionCur.HorizontalPoint2;
Point2D verPt1 = lesionCur.VerticalPoint1;
Point2D verPt2 = lesionCur.VerticalPoint2;
strLabel = "0"; //add
TextBlockLabel.Text = "等级:" + strLabel;
TextBlockShape.Text = "形状:" + strShape;
TextBlockOrientation.Text = "生长方向:" + strOrientation;
TextBlockEcho.Text = "回声类型:" + strEcho;
TextBlockBound.Text = "边界:" + strBound;
TextBlockMargin.Text = "边缘:" + strMargin;
TextBlockHorizontal.Text = "横径:" + "{" + horPt1.X + "," + horPt1.Y + "}" + "{" + horPt2.X + "," + horPt2.Y + "}";
TextBlockVertical.Text = "纵径:" + "{" + verPt1.X + "," + verPt1.Y + "}" + "{" + verPt2.X + "," + verPt2.Y + "}";
};
}
}
private void OnLesionSelectionLabelChanged(object sender, SelectionChangedEventArgs e)
{
_lesionLabelIndex = ComboBoxLesionsLabel.SelectedIndex;
if(_lesionsLabels.Count >0)
{
if (_lesionsLabels[_lesionIndex] < 0)
{
_lesionsLabels[_lesionIndex] = _lesionLabelIndex;
}
else
{
if(_lesionLabelIndex >0)
{
_lesionsLabels[_lesionIndex] = _lesionLabelIndex;
}
}
//_lesionsLabels[_lesionIndex] = _lesionLabelIndex;
}
else
{
ComboBoxLesionsLabel.SelectedIndex = -1;
_lesionLabelIndex = 0;
}
}
private void InitializeComboBoxLesionsLabel()
{
// 分级
ComboBoxLesionsLabel.Items.Add("0");
ComboBoxLesionsLabel.Items.Add("脂肪瘤");
ComboBoxLesionsLabel.Items.Add("2级");
ComboBoxLesionsLabel.Items.Add("3级");
ComboBoxLesionsLabel.Items.Add("4a级");
ComboBoxLesionsLabel.Items.Add("4b级");
ComboBoxLesionsLabel.Items.Add("4c级");
ComboBoxLesionsLabel.Items.Add("5级");
}
private void OnCheckedCheckDrawingResult(object sender, RoutedEventArgs e)
{
_showDrawingResult = true;
//_image = new Bitmap(imgPath);
//_drawingPoints;
UpdateLesionsInCanvas();
ShowDrawingPts();
}
private void ShowDrawingPts()
{
int num = _drawingPoints.Count;
if (num > 0)
{
// 更新显示正在绘制的轮廓线
DrawContourInCanvas(_drawingPoints, EnumCanvasItemType.Drawing, "drawingPt");
}
}
private void OnUncheckedCheckDrawingResult(object sender, RoutedEventArgs e)
{
_showDrawingResult = false;;
RemoveContourLine();
}
private void RemoveContourLine()
{
if (_drawimg == null)
{
return;
}
// 先清空画布上旧的显示内容
for (int ni = 0; ni < _lesions.Count; ni++)
{
RemoveContourInCanvas(ni.ToString());
RemoveLineInCanvas(EnumCanvasLineType.Horizontal, ni.ToString());
RemoveLineInCanvas(EnumCanvasLineType.Vertical, ni.ToString());
}
int num = _drawingPoints.Count;
if (num > 0)
{
// 更新显示正在绘制的轮廓线
RemoveContourInCanvasForDrawPts("drawingPt");
}
}
private void RemoveContourInCanvasForDrawPts(string name)
{
string contourName = "Contour_" + name;
if (MyCanvasDraw.FindName(contourName) is Polyline contourExists)
{
MyCanvasDraw.Children.Remove(contourExists);
MyCanvasDraw.UnregisterName(contourName);
}
}
private void OnBtnSaveResultClicked(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog();
openFileDialog.Filter = "图片文件|*.png;*.bmp;*.jpg;*.jpeg";
openFileDialog.Multiselect = true;
openFileDialog.Title = "选择一幅或多幅图像";
if (openFileDialog.ShowDialog() ?? false)
{
foreach (string filename in openFileDialog.FileNames)
{
Bitmap img = new Bitmap(filename);
string imgName = System.IO.Path.GetFileNameWithoutExtension(filename);
string temp;
int idx = filename.LastIndexOf("\\");
temp = filename.Substring(idx);
string[] strs1 = temp.Split('\\');
temp = strs1[1];
//string[] strs2 = temp.Split(new char[4] { '.', 'j', 'p', 'g' }, 2);
string[] strs2 = System.Text.RegularExpressions.Regex.Split(temp, ".jpg", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
string ImgId = strs2[0];
int imgIdx = _allImages.FindIndex(x => x.ImageId == ImgId);
int imageId = imgIdx;
//_showImg = img;
if (imageId >= 0)
{
SaveModel(img, imageId, ImgId);
Save(img, imageId, ImgId);
JudgeResult(imageId);
}
}
}
}
private void JudgeResult(int imageId)
{
if (_modelResult.Lesions.Count > 0 && _allImages[imageId].Lesions.Count > 0)
{
if (_modelResult.Lesions.Count != _allImages[imageId].Lesions.Count)
{
return;
}
else if(_modelResult.Lesions.Count==1 && _allImages[imageId].Lesions.Count ==1)
{
var shapeGt = _allImages[imageId].Lesions[0].Shape;
var shapeModel = _modelResult.Lesions[0].Shape;
if (shapeGt == EnumDesShapeValue.Oval && shapeModel == EnumDesShapeValue.Oval)
{
_Oval_Oval_num++;
}
else if (shapeGt == EnumDesShapeValue.Oval && shapeModel == EnumDesShapeValue.Round)
{
_Oval_Round_num++;
}
else if (shapeGt == EnumDesShapeValue.Oval && shapeModel == EnumDesShapeValue.Irregular)
{
_Oval_Irregular_num++;
}
if (shapeGt == EnumDesShapeValue.Round && shapeModel == EnumDesShapeValue.Oval)
{
_Round_Oval_num++;
}
else if (shapeGt == EnumDesShapeValue.Round && shapeModel == EnumDesShapeValue.Round)
{
_Round_Round_num++;
}
else if (shapeGt == EnumDesShapeValue.Round && shapeModel == EnumDesShapeValue.Irregular)
{
_Round_Irregular_num++;
}
if (shapeGt == EnumDesShapeValue.Irregular && shapeModel == EnumDesShapeValue.Oval)
{
_Irregular_Oval_num++;
}
else if (shapeGt == EnumDesShapeValue.Irregular && shapeModel == EnumDesShapeValue.Round)
{
_Irregular_Round_num++;
}
else if (shapeGt == EnumDesShapeValue.Irregular && shapeModel == EnumDesShapeValue.Irregular)
{
_Irregular_Irregular_num++;
}
var orientationGt = _allImages[imageId].Lesions[0].Orientation;
var orientationModel = _modelResult.Lesions[0].Orientation;
if (orientationGt == EnumDesOrientationValue.Parallel && orientationModel == EnumDesOrientationValue.Parallel)
{
_Parallel_Parallel_num++;
}
else if(orientationGt == EnumDesOrientationValue.Parallel && orientationModel == EnumDesOrientationValue.NonParallel)
{
_Parallel_NonParallel_num++;
}
if (orientationGt == EnumDesOrientationValue.NonParallel && orientationModel == EnumDesOrientationValue.Parallel)
{
_NonParallel_Parallel_num++;
}
else if (orientationGt == EnumDesOrientationValue.NonParallel && orientationModel == EnumDesOrientationValue.NonParallel)
{
_NonParallel_NonParallel_num++;
}
var echoGt = _allImages[imageId].Lesions[0].EchoPattern;
var echoModel = _modelResult.Lesions[0].EchoPattern;
if (echoGt == EnumDesEchoPatternValue.Anechoic && echoModel == EnumDesEchoPatternValue.Anechoic)
{
_Anechoic_Anechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Anechoic && echoModel == EnumDesEchoPatternValue.Hypoechoic)
{
_Anechoic_Hypoechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Anechoic && echoModel == EnumDesEchoPatternValue.Isoechoic)
{
_Anechoic_Isoechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Anechoic && echoModel == EnumDesEchoPatternValue.Hyperechoic)
{
_Anechoic_Hyperechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Anechoic && echoModel == EnumDesEchoPatternValue.Complex)
{
_Anechoic_Complex_num++;
}
if (echoGt == EnumDesEchoPatternValue.Hypoechoic && echoModel == EnumDesEchoPatternValue.Anechoic)
{
_Hypoechoic_Anechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Hypoechoic && echoModel == EnumDesEchoPatternValue.Hypoechoic)
{
_Hypoechoic_Hypoechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Hypoechoic && echoModel == EnumDesEchoPatternValue.Isoechoic)
{
_Hypoechoic_Isoechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Hypoechoic && echoModel == EnumDesEchoPatternValue.Hyperechoic)
{
_Hypoechoic_Hyperechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Hypoechoic && echoModel == EnumDesEchoPatternValue.Complex)
{
_Hypoechoic_Complex_num++;
}
if (echoGt == EnumDesEchoPatternValue.Isoechoic && echoModel == EnumDesEchoPatternValue.Anechoic)
{
_Isoechoic_Anechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Isoechoic && echoModel == EnumDesEchoPatternValue.Hypoechoic)
{
_Isoechoic_Hypoechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Isoechoic && echoModel == EnumDesEchoPatternValue.Isoechoic)
{
_Isoechoic_Isoechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Isoechoic && echoModel == EnumDesEchoPatternValue.Hyperechoic)
{
_Isoechoic_Hyperechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Isoechoic && echoModel == EnumDesEchoPatternValue.Complex)
{
_Isoechoic_Complex_num++;
}
if (echoGt == EnumDesEchoPatternValue.Hyperechoic && echoModel == EnumDesEchoPatternValue.Anechoic)
{
_Hyperechoic_Anechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Hyperechoic && echoModel == EnumDesEchoPatternValue.Hypoechoic)
{
_Hyperechoic_Hypoechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Hyperechoic && echoModel == EnumDesEchoPatternValue.Isoechoic)
{
_Hyperechoic_Isoechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Hyperechoic && echoModel == EnumDesEchoPatternValue.Hyperechoic)
{
_Hyperechoic_Hyperechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Hyperechoic && echoModel == EnumDesEchoPatternValue.Complex)
{
_Hyperechoic_Complex_num++;
}
if (echoGt == EnumDesEchoPatternValue.Complex && echoModel == EnumDesEchoPatternValue.Anechoic)
{
_Complex_Anechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Complex && echoModel == EnumDesEchoPatternValue.Hypoechoic)
{
_Complex_Hypoechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Complex && echoModel == EnumDesEchoPatternValue.Isoechoic)
{
_Complex_Isoechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Complex && echoModel == EnumDesEchoPatternValue.Hyperechoic)
{
_Complex_Hyperechoic_num++;
}
else if (echoGt == EnumDesEchoPatternValue.Complex && echoModel == EnumDesEchoPatternValue.Complex)
{
_Complex_Complex_num++;
}
var boundGt = _allImages[imageId].Lesions[0].Boundary;
var boundModel = _modelResult.Lesions[0].Boundary;
if (boundGt == EnumDesLesionBoundaryValue.AbruptInterface && boundModel == EnumDesLesionBoundaryValue.AbruptInterface)
{
_AbruptInterface_AbruptInterface_num++;
}
else if (boundGt == EnumDesLesionBoundaryValue.AbruptInterface && boundModel == EnumDesLesionBoundaryValue.EchogenicHalo)
{
_AbruptInterface_EchogenicHalo_num++;
}
if (boundGt == EnumDesLesionBoundaryValue.EchogenicHalo && boundModel == EnumDesLesionBoundaryValue.AbruptInterface)
{
_EchogenicHalo_AbruptInterface_num++;
}
else if (boundGt == EnumDesLesionBoundaryValue.EchogenicHalo && boundModel == EnumDesLesionBoundaryValue.EchogenicHalo)
{
_EchogenicHalo_EchogenicHalo_num++;
}
var marginGt = _allImages[imageId].Lesions[0].Margin;
var marginModel = _modelResult.Lesions[0].Margin;
if (marginGt == EnumDesMarginValue.Circumscribed && marginModel == EnumDesMarginValue.Circumscribed)
{
_Circumscribed_NonCircumscribed_num++;
}
else if (marginGt == EnumDesMarginValue.Circumscribed && marginModel == EnumDesMarginValue.NonCircumscribed)
{
_Circumscribed_NonCircumscribed_num++;
}
if (marginGt == EnumDesMarginValue.NonCircumscribed && marginModel == EnumDesMarginValue.Circumscribed)
{
_NonCircumscribed_Circumscribed_num++;
}
else if (marginGt == EnumDesMarginValue.NonCircumscribed && marginModel == EnumDesMarginValue.NonCircumscribed)
{
_NonCircumscribed_NonCircumscribed_num++;
}
}
}
}
public void SaveModel(Bitmap image, int imageId, string imageName)
{
string currentPath = System.Environment.CurrentDirectory;
string newPath = System.IO.Path.Combine(currentPath, "result");
RawImage rawImg = null;
rawImg = RawImageShowUtils.BitmapToRawImage(image);
if(_newModelResult == null)
{
string name = _allImages[_imgIndex].ImageId;
_caseId = Guid.NewGuid().ToString();
_dataId = name;
_readingVideo = false;
var extendData = new Dictionary();
extendData.Add("CaseId", _caseId);
extendData.Add("DataId", _dataId);
extendData.Add("IsVideo", _readingVideo);
extendData.Add("TimeStamp", (double)_frameIndex);
_processId = _module.StartProcess();
var input = new ImageInputData(rawImg, extendData);
IDetectedObject[] result = _module.PushOnePieceOfData(_processId, input);
_newModelResult = result;
_module.EndProcess(_processId);
}
else
{
}
//var diagResult = _diagSystem.EvaluateOneImage(rawImg);
int breastLesionNum = 0;
Bitmap dstimage = image.Clone(new System.Drawing.Rectangle(0, 0, image.Width, image.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
if (_newModelResult != null)
{
foreach (var moduleResult in _newModelResult)
{
var label = moduleResult.Label;
var nameOrgan = label.GroupName;
var Ilabel = moduleResult.Label;
int indexLabel = Ilabel.Index;
if (nameOrgan == "AI.Vaid.Breast.Lesion")
{
using (var g = Graphics.FromImage(dstimage))
{
int num = 0;
string strDescriptionShape = string.Empty;
string strDescriptionOrientation = string.Empty;
string strDescriptionEcho = string.Empty;
string strDescriptionBound = string.Empty;
string strDescriptionMargin = string.Empty;
System.Drawing.Brush brush = System.Drawing.Brushes.Green;
List CurImageLesion = new List();
if (moduleResult.Contour?.Contours.Length > 0)
{
int count = moduleResult.Contour.Contours.Length;
for (int i = 0; i < count; i++)
{
brush = System.Drawing.Brushes.Green;
int labelName = indexLabel;
LesionInfo lesion = new LesionInfo();
var contourPoints = moduleResult.Contour.Contours[i];
int pointCount = contourPoints.Points.Length;
var points = new List();
System.Drawing.PointF[] lesionContour = new PointF[pointCount];
for (int j = 0; j < pointCount; j++)
{
var point = new System.Windows.Point(contourPoints.Points[j].X, contourPoints.Points[j].Y);
lesionContour[j].X = contourPoints.Points[j].X;
lesionContour[j].Y = contourPoints.Points[j].Y;
Point2D pt = new Point2D(contourPoints.Points[j].X, contourPoints.Points[j].Y);
points.Add(pt);
lesion.Contour.Add(pt);
}
g.DrawPolygon(new System.Drawing.Pen(brush, 2), lesionContour);
var desResult = moduleResult.Description;
var type = desResult.GetType();
string strDescription = string.Empty;
{
foreach (var key in desResult.Descriptions.Keys)
{
if (key == "Shape")
{
EnumDesShapeValue sss = new EnumDesShapeValue();
string des = string.Empty;
switch (desResult.Descriptions[key])
{
case "Oval":
des = "椭圆形";
sss = EnumDesShapeValue.Oval;
break;
case "Round":
des = "类圆形";
sss = EnumDesShapeValue.Round;
break;
case "Irregular":
des = "不规则形";
sss = EnumDesShapeValue.Irregular;
break;
}
lesion.Shape = sss;
strDescription += "形状:" + des + Environment.NewLine;
}
if (key == "Orientation")
{
EnumDesOrientationValue sss = new EnumDesOrientationValue();
string des = string.Empty;
switch (desResult.Descriptions[key])
{
case "Parallel":
des = "平行";
sss = EnumDesOrientationValue.Parallel;
break;
case "NonParallel":
des = "非平行";
sss = EnumDesOrientationValue.NonParallel;
break;
}
lesion.Orientation = sss;
strDescription += "生长方向:" + des + Environment.NewLine;
}
if (key == "EchoPattern")
{
EnumDesEchoPatternValue sss = new EnumDesEchoPatternValue();
string des = string.Empty;
switch (desResult.Descriptions[key])
{
case "Anechoic":
des = "无回声";
sss = EnumDesEchoPatternValue.Anechoic;
break;
case "Hypoechoic":
des = "低回声";
sss = EnumDesEchoPatternValue.Hypoechoic;
break;
case "Isoechoic":
des = "等回声";
sss = EnumDesEchoPatternValue.Isoechoic;
break;
case "Hyperechoic":
des = "高回声";
sss = EnumDesEchoPatternValue.Hyperechoic;
break;
case "Complex":
des = "混合回声";
sss = EnumDesEchoPatternValue.Complex;
break;
}
lesion.EchoPattern = sss;
strDescription += "回声类型:" + des + Environment.NewLine;
}
if (key == "Boundary")
{
EnumDesLesionBoundaryValue sss = new EnumDesLesionBoundaryValue();
string des = string.Empty;
switch (desResult.Descriptions[key])
{
case "AbruptInterface":
des = "清晰";
sss = EnumDesLesionBoundaryValue.AbruptInterface;
break;
case "EchogenicHalo":
des = "模糊";
sss = EnumDesLesionBoundaryValue.EchogenicHalo;
break;
}
lesion.Boundary = sss;
strDescription += "边界:" + des + Environment.NewLine;
}
if (key == "Margin")
{
EnumDesMarginValue sss = new EnumDesMarginValue();
string des = string.Empty;
switch (desResult.Descriptions[key])
{
case "Circumscribed":
des = "光整";
sss = EnumDesMarginValue.Circumscribed;
break;
case "NonCircumscribed":
des = "不光整";
sss = EnumDesMarginValue.NonCircumscribed;
break;
}
lesion.Margin = sss;
strDescription += "边缘:" + des + Environment.NewLine;
}
}
}
var rect = moduleResult.BoundingBox.Contour.BoundingBox();
var roiBox = moduleResult.BoundingBox;
var ss = roiBox.Contour.Points;
var lesionSize = Array.Find(moduleResult.Measurements, x => x.GetType() == typeof(TransverseLongitudinalDiameterMeasurement));
var size = (TransverseLongitudinalDiameterMeasurement)lesionSize;
var pointLineH1 = new System.Windows.Point(size.TransverseDiameterMarkPosition.LineStart.X, size.TransverseDiameterMarkPosition.LineStart.Y);
var pointLineH2 = new System.Windows.Point(size.TransverseDiameterMarkPosition.LineEnd.X, size.TransverseDiameterMarkPosition.LineEnd.Y);
var pointLineV1 = new System.Windows.Point(size.LongitudinalDiameterMarkPosition.LineStart.X, size.LongitudinalDiameterMarkPosition.LineStart.Y);
var pointLineV2 = new System.Windows.Point(size.LongitudinalDiameterMarkPosition.LineEnd.X, size.LongitudinalDiameterMarkPosition.LineEnd.Y);
System.Drawing.Point[] axisH = new System.Drawing.Point[2];
System.Drawing.Point[] axisV = new System.Drawing.Point[2];
axisH[0].X = (int)pointLineH1.X;
axisH[0].Y = (int)pointLineH1.Y;
axisH[1].X = (int)pointLineH2.X;
axisH[1].Y = (int)pointLineH2.Y;
axisV[0].X = (int)pointLineV1.X;
axisV[0].Y = (int)pointLineV1.Y;
axisV[1].X = (int)pointLineV2.X;
axisV[1].Y = (int)pointLineV2.Y;
System.Drawing.Pen pen_h = new System.Drawing.Pen(System.Drawing.Brushes.PaleGreen, 2);
g.DrawLines(pen_h, axisH); //横轴,浅绿色
System.Drawing.Pen pen_v = new System.Drawing.Pen(System.Drawing.Brushes.Red, 1);
g.DrawLines(pen_v, axisV); //纵轴,红色
Font drawFont = new Font("黑体", 24);
SolidBrush drawBrush = new SolidBrush(System.Drawing.Color.GreenYellow);
float ptx = 10.0f;
float pty = 0.0f + 20;
string drawText = strDescriptionEcho;//
g.DrawString(drawText, drawFont, drawBrush, ptx, pty + 30 * 4 * num);
drawText = strDescriptionShape;
g.DrawString(drawText, drawFont, drawBrush, ptx, pty + 30 * (4 * num + 1));
drawText = strDescriptionMargin;
g.DrawString(drawText, drawFont, drawBrush, ptx, pty + 30 * (4 * num + 2));
drawText = strDescriptionOrientation;
g.DrawString(drawText, drawFont, drawBrush, ptx, pty + 30 * (4 * num + 3));
drawText = strDescriptionBound;
g.DrawString(drawText, drawFont, drawBrush, ptx, pty + 30 * (4 * num + 4));
//
drawText = num.ToString();
g.DrawString(drawText, drawFont, drawBrush, axisH[0].X, axisH[0].Y);
num++;
}
}
g.Dispose();
}
string name = newPath + "\\" + imageName + ".jpg";
dstimage.Save(name, System.Drawing.Imaging.ImageFormat.Png);
dstimage.Dispose();
}
}
}
}
public void Save(Bitmap image, int imageId, string imageName)
{
string currentPath = System.Environment.CurrentDirectory;
string newPath = System.IO.Path.Combine(currentPath, "result");
System.IO.Directory.CreateDirectory(newPath);
int imgNum = _allImages.Count;
if (image == null || _allImages.Count <= 0)
{
return;
}
if (_allImages[imageId].Lesions.Count <= 0)
{
string name = newPath + "\\" + imageName + ".png";
//image.Save(name, System.Drawing.Imaging.ImageFormat.Png);
}
else
{
int numLesions = _allImages[imageId].Lesions.Count;
Bitmap origImg = image;
for (int jj = 0; jj < numLesions; jj++)
{
EnumDesEchoPatternValue echoGT = _allImages[imageId].Lesions[jj].EchoPattern;
EnumDesShapeValue shapeGT = _allImages[imageId].Lesions[jj].Shape;
EnumDesMarginValue marginGT = _allImages[imageId].Lesions[jj].Margin;
EnumDesOrientationValue orientationGT = _allImages[imageId].Lesions[jj].Orientation;
EnumDesLesionBoundaryValue boundGT = _allImages[imageId].Lesions[jj].Boundary;
string echo = null, shape = null, margin = null, orientation = null, bound = null;
switch (echoGT)
{
case EnumDesEchoPatternValue.Anechoic:
echo = "无回声";
break;
case EnumDesEchoPatternValue.Hypoechoic:
echo = "低回声";
break;
case EnumDesEchoPatternValue.Hyperechoic:
echo = "高回声";
break;
case EnumDesEchoPatternValue.Strongechoic:
echo = "强回声";
break;
case EnumDesEchoPatternValue.Complex:
echo = "混合回声";
break;
case EnumDesEchoPatternValue.Isoechoic:
echo = "等回声";
break;
}
switch (shapeGT)
{
case EnumDesShapeValue.Oval:
shape = "椭圆形";
break;
case EnumDesShapeValue.Round:
shape = "圆形";
break;
case EnumDesShapeValue.Irregular:
shape = "不规则";
break;
}
switch (marginGT)
{
case EnumDesMarginValue.Circumscribed:
margin = "光整";
break;
case EnumDesMarginValue.NonCircumscribed:
margin = "不光整";
break;
}
switch (orientationGT)
{
case EnumDesOrientationValue.Parallel:
orientation = "平行";
break;
case EnumDesOrientationValue.NonParallel:
orientation = "非平行";
break;
}
switch (boundGT)
{
case EnumDesLesionBoundaryValue.AbruptInterface:
bound = "清晰";
break;
case EnumDesLesionBoundaryValue.EchogenicHalo:
bound = "模糊";
break;
}
// 显示新的病灶
LesionInfo lesion = _allImages[imageId].Lesions[jj];
int num2 = lesion.Contour.Count;
using (var g = Graphics.FromImage(origImg))
{
System.Drawing.Pen pen3 = new System.Drawing.Pen(System.Drawing.Brushes.Navy, 2);
System.Drawing.PointF[] lesionContour = new PointF[num2];
for (int i = 0; i < num2; i++)
{
lesionContour[i].X = _allImages[imageId].Lesions[jj].Contour[i].X;
lesionContour[i].Y = _allImages[imageId].Lesions[jj].Contour[i].Y;
}
if (num2 > 0)
{
System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Brushes.Orange, 2);
g.DrawLines(pen, lesionContour); //画病灶轮廓
pen.Dispose();
}
System.Drawing.PointF[] axisH = new PointF[2];
System.Drawing.PointF[] axisV = new PointF[2];
axisH[0].X = lesion.HorizontalPoint1.X;
axisH[0].Y = lesion.HorizontalPoint1.Y;
axisH[1].X = lesion.HorizontalPoint2.X;
axisH[1].Y = lesion.HorizontalPoint2.Y;
axisV[0].X = lesion.VerticalPoint1.X;
axisV[0].Y = lesion.VerticalPoint1.Y;
axisV[1].X = lesion.VerticalPoint2.X;
axisV[1].Y = lesion.VerticalPoint2.Y;
//画轮廓的长短轴
System.Drawing.Pen pen_h = new System.Drawing.Pen(System.Drawing.Brushes.PaleGreen, 2);
g.DrawLines(pen_h, axisH); //横轴,浅绿色
System.Drawing.Pen pen_v = new System.Drawing.Pen(System.Drawing.Brushes.Red, 1);
g.DrawLines(pen_v, axisV); //纵轴,红色
//写汉字
Font drawFont = new Font("黑体", 24);
SolidBrush drawBrush = new SolidBrush(System.Drawing.Color.GreenYellow);
float x = 10.0f;
float y = 0.0f + 20;
string drawText = echo;//
g.DrawString(drawText, drawFont, drawBrush, x, y + 30 * 4 * jj);
drawText = shape;
g.DrawString(drawText, drawFont, drawBrush, x, y + 30 * (4 * jj + 1));
drawText = margin;
g.DrawString(drawText, drawFont, drawBrush, x, y + 30 * (4 * jj + 2));
drawText = orientation;
g.DrawString(drawText, drawFont, drawBrush, x, y + 30 * (4 * jj + 3));
drawText = bound;
g.DrawString(drawText, drawFont, drawBrush, x, y + 30 * (4 * jj + 4));
//
drawText = jj.ToString();
g.DrawString(drawText, drawFont, drawBrush, axisH[0].X, axisH[0].Y);
g.Dispose();
}
}
string name = newPath + "\\" + imageName + ".png";
origImg.Save(name, System.Drawing.Imaging.ImageFormat.Png);
origImg.Dispose();
}
}
private void OnBtnGoBackClicked(object sender, RoutedEventArgs e)
{
int num = _drawingPoints.Count;
if (num > 0)
{
_drawingPoints.RemoveAt(num - 1);
DrawContourInCanvas(_drawingPoints, EnumCanvasItemType.Drawing, "drawingPt");
}
else
{
System.Windows.MessageBox.Show("轮廓点不存在");
}
//UpdateLesionsInCanvas();
////_drawingPoints.Add(_drawingPoints[0]);
//List contourInOrigImg = new List();
//foreach (var point in _drawingPoints)
//{
// contourInOrigImg.Add(GetPosInOrigImage(point));
//}
//_drawingPoints = new List();
//_mouseOper = EnumMouseOperType.None;
//RemoveContourInCanvas("drawing");
//UserControlLesionSelected.SetContour(contourInOrigImg);
}
}
}