123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Drawing;
- using System.Windows.Media.Imaging;
- using System.Drawing.Imaging;
- using System.Runtime.InteropServices;
- namespace SegmentDescribDemo
- {
- /// <summary>
- /// 图像处理工具类
- /// </summary>
- [StructLayout(LayoutKind.Sequential)]
- public struct MyPoint
- {
- public int x;
- public int y;
- }
- /// <summary>
- /// 病灶轮廓的纵、横轴的坐标点
- /// </summary>
- public struct AxisPoint
- {
- public MyPoint horizontalPt1; // 病灶轮廓的 横轴(水平方向) 端点坐标
- public MyPoint horizontalPt2;
- public MyPoint verticalPt1; // 病灶轮廓的 纵轴 端点坐标
- public MyPoint verticalPt2;
- }
-
- public struct LesionDescri
- {
- public int shape; /// 形状描述。0未标注,1椭圆,2类圆,3不规则
- public int orientation; /// 生长方向。0未标注,1平行,2非平行
- public int echo; /// 回声类型。0未标注,1无回声,2低回声,3等回声,4高回声,5混合回声
- public int boundary; /// 边界清晰度。0未标注,1清晰,2不清晰
- public int margin; /// 边缘光整度。0未标注,1光整,不光整
- public int calcification; /// 钙化。0未标注,1无钙化,2粗大钙化,3内部微钙化,外部微钙化
- public AxisPoint axisPt;
- }
- public struct LesionDescriNow
- {
- public int shape; /// 形状描述。0未标注,1椭圆,2类圆,3不规则
- public int orientation; /// 生长方向。0未标注,1平行,2非平行
- public int echo; /// 回声类型。0未标注,1无回声,2低回声,3等回声,4高回声,5混合回声
- public int boundary; /// 边界清晰度。0未标注,1清晰,2不清晰
- public int margin; /// 边缘光整度。0未标注,1光整,不光整
- public int calcification; /// 钙化。0未标注,1无钙化,2粗大钙化,3内部微钙化,外部微钙化
- public int posteriorAcousticFeature; /// 后部声学特征 :
- }
- public static class ImageUtility
- {
- [DllImport(@"BreastLesionSeg.dll", CallingConvention = CallingConvention.Cdecl)]
- public static unsafe extern int ContourDetectBLS(byte[] img_data, int channels, int img_width, int img_height,
- roiCoor roi_vec, [In, Out] MyPoint[] contour_points);
- [DllImport(@"ActiveContourWithoutEdge_IO.dll", CallingConvention = CallingConvention.Cdecl)]
- public static unsafe extern int ContourDetectACWE(byte[] img_data, int channels, int img_width, int img_height,
- roiCoor roi_vec, [In, Out] MyPoint[] contour_points);
- [DllImport(@"ActiveContourDRLSE_IO.dll", EntryPoint = "ContourDetectDRLSE", CallingConvention = CallingConvention.Cdecl)]
- public static unsafe extern int ContourDetectDRLSE(byte[] img_data, int channels, int img_width, int img_height,
- roiCoor roi_vec, [In, Out] MyPoint[] contour_points);
- [DllImport(@"ActiveContourLocalBinaryFitting.dll", EntryPoint = "ContourDetectLBF", CallingConvention = CallingConvention.Cdecl)]
- public static unsafe extern int ContourDetectLBF(byte[] img_data, int channels, int img_width, int img_height,
- roiCoor roi_vec, [In, Out] MyPoint[] contour_points);
- [DllImport(@"LevelSetEvolutionWithoutReinitialization.dll", EntryPoint = "ContourDetectLSEWR", CallingConvention = CallingConvention.Cdecl)]
- public static unsafe extern int ContourDetectLSEWR(byte[] img_data, int channels, int img_width, int img_height,
- roiCoor roi_vec, [In, Out] MyPoint[] contour_points);
- [DllImport(@"FCM_IO.dll", CallingConvention = CallingConvention.Cdecl)]
- public static unsafe extern int ContourDetectFCM(byte[] img_data, int channels, float contrast_value, int img_width, int img_height,
- roiCoor roi_vec, [In, Out] MyPoint[] contour_points);
- [DllImport(@"LesionDescription.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void LoadModel(char[] shapePath);
- [DllImport(@"LesionDescription.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void BreastDescription(byte[] img_data, int channels, int img_w, int img_h, roiCoor roi_vec, int num_pts,
- MyPoint[] contour_points, AxisPoint axisPt, ref LesionDescriNow lesionDescr);
- [DllImport(@"LesionDescription.dll", CallingConvention = CallingConvention.Cdecl)]
- public static extern void FreeModel();
- public static BitmapImage BitmapToBitmapImage(Bitmap img)
- {
- BitmapImage bmpimg = new BitmapImage();
- using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
- {
- img.Save(ms, ImageFormat.Png);
- bmpimg.BeginInit();
- bmpimg.StreamSource = ms;
- bmpimg.CacheOption = BitmapCacheOption.OnLoad;
- bmpimg.EndInit();
- bmpimg.Freeze();
- ms.Dispose();
- }
- return bmpimg;
- }
- public unsafe static PointF[] ContourDetect(SegDataInput data, EnumSegMethod segMethod)
- {
- if ((data.InputImage.PixelFormat != PixelFormat.Format24bppRgb) &&
- (data.InputImage.PixelFormat != PixelFormat.Format8bppIndexed) &&
- (data.InputImage.PixelFormat != PixelFormat.Format32bppRgb))
- {
- return new PointF[0];
- }
- if (data.InputRoi.Width * data.InputRoi.Height <= 0)
- {
- return new PointF[0];
- }
- BitmapData bmData;
- int imgWidth = data.InputImage.Width;
- int imgHeight = data.InputImage.Height;
- int channels = (data.InputImage.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 1;
- Rectangle rect = new Rectangle(0, 0, imgWidth, imgHeight);
- bmData = data.InputImage.LockBits(rect, ImageLockMode.ReadOnly, data.InputImage.PixelFormat);
- byte[] imgData = new byte[imgWidth * imgHeight * channels];
- var ptr0 = (byte*)bmData.Scan0.ToPointer();
- int stride = bmData.Stride;
- for (int y = 0; y < imgHeight; y++)
- {
- for (int x = 0; x < imgWidth; x++)
- {
- for (int c = 0; c < channels; c++) // 通道数
- {
- imgData[y * imgWidth * channels + x * channels + c] = ptr0[y * stride + x * channels + c];
- }
- }
- }
- int max_num = data.InputRoi.Height * data.InputRoi.Width;
- MyPoint[] contourPts_tmp = new MyPoint[max_num];
- roiCoor roi;
- roi.x = data.InputRoi.X;
- roi.y = data.InputRoi.Y;
- roi.width = data.InputRoi.Width;
- roi.height = data.InputRoi.Height;
- int ptsNum = 0;
- if (segMethod == EnumSegMethod.BLS)
- {
- ptsNum = ContourDetectBLS(imgData, channels, imgWidth, imgHeight, roi, contourPts_tmp);
- }
- if (segMethod == EnumSegMethod.FCM)
- {
- ptsNum = ContourDetectFCM(imgData, channels, 120, imgWidth, imgHeight, roi, contourPts_tmp);
- }
- if (segMethod == EnumSegMethod.ACWE)
- {
- ptsNum = ContourDetectACWE(imgData, channels, imgWidth, imgHeight, roi, contourPts_tmp);
- }
- if (segMethod == EnumSegMethod.DRLSE)
- {
- ptsNum = ContourDetectDRLSE(imgData, channels, imgWidth, imgHeight, roi, contourPts_tmp);
- }
- if (segMethod == EnumSegMethod.LBF)
- {
- ptsNum = ContourDetectLBF(imgData, channels, imgWidth, imgHeight, roi, contourPts_tmp);
- }
- if (segMethod == EnumSegMethod.LSEWR)
- {
- ptsNum = ContourDetectLSEWR(imgData, channels, imgWidth, imgHeight, roi, contourPts_tmp);
- }
- data.InputImage.UnlockBits(bmData);
- if (ptsNum <= 0)
- {
- return new PointF[0];
- }
- Point[] contourPts = new Point[ptsNum];
- for (int i = 0; i < ptsNum; i++)
- {
- contourPts[i].X = contourPts_tmp[i].x;
- contourPts[i].Y = contourPts_tmp[i].y;
- }
- PointF[] contour_points = new PointF[ptsNum];
- for (int i = 0; i < ptsNum; i++)
- {
- contour_points[i] = new PointF(contourPts[i].X, contourPts[i].Y);
- }
- return contour_points;
- }
- public unsafe static LesionDescriptionResult BreastDescription(DesDataInput data, AxisPoint axisPt)
- {
- System.Drawing.PointF[] contours = data.Contour;
- LesionDescriptionResult result = null;
- // 病灶轮廓描述
- int pts_num = contours.GetLength(0);
- int imgWidth = data.InputImage.Width;
- int imgHeight = data.InputImage.Height;
- MyPoint[] contourPts_tmp = new MyPoint[pts_num];
- for (int i = 0; i < pts_num; i++)
- {
- contourPts_tmp[i].x = (int)contours[i].X;
- contourPts_tmp[i].y = (int)contours[i].Y;
- }
- int channels = (data.InputImage.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb) ? 3 : 1;
- BitmapData bmData;
- System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, imgWidth, imgHeight);
- bmData = data.InputImage.LockBits(rect, ImageLockMode.ReadOnly, data.InputImage.PixelFormat);
- byte[] img_data = new byte[imgWidth * imgHeight * channels];
- var ptr0 = (byte*)bmData.Scan0.ToPointer();
- int stride = bmData.Stride;
- for (int y = 0; y < imgHeight; y++)
- {
- for (int x = 0; x < imgWidth; x++)
- {
- for (int c = 0; c < channels; c++)
- {
- img_data[y * imgWidth * channels + x * channels + c] = ptr0[y * stride + x * channels + c];
- }
- }
- }
- roiCoor roi;
- roi.x = data.InputRoi.X;
- roi.y = data.InputRoi.Y;
- roi.width = data.InputRoi.Width;
- roi.height = data.InputRoi.Height;
- LesionDescriNow lesionDescr = new LesionDescriNow();
- lesionDescr.boundary = 0;
- lesionDescr.margin = 0;
- lesionDescr.echo = 0;
- lesionDescr.calcification = 0;
- lesionDescr.orientation = 0;
- AxisPoint axisPtNew = new AxisPoint();
- axisPtNew.horizontalPt1 = new MyPoint { x = 0, y = 0 };
- axisPtNew.horizontalPt2 = new MyPoint { x = 0, y = 0 };
- axisPtNew.verticalPt1 = new MyPoint { x = 0, y = 0 };
- axisPtNew.verticalPt2 = new MyPoint { x = 0, y = 0 };
- if( true/*axisPt*/ )
- {
- axisPtNew.horizontalPt1 = axisPt.horizontalPt1;
- axisPtNew.horizontalPt2 = axisPt.horizontalPt2;
- axisPtNew.verticalPt1 = axisPt.verticalPt1;
- axisPtNew.verticalPt2 = axisPt.verticalPt2;
- }
- int startTime2 = Environment.TickCount;
- BreastDescription(img_data, channels, imgWidth, imgHeight, roi,
- pts_num, contourPts_tmp, axisPtNew, ref lesionDescr);
- int endTime2 = Environment.TickCount;
- Console.WriteLine("TestTime:" + (endTime2 - startTime2) + "ms");
- result = new LesionDescriptionResult(lesionDescr.shape,
- lesionDescr.orientation,
- lesionDescr.echo,
- lesionDescr.boundary,
- lesionDescr.margin,
- lesionDescr.calcification,
- lesionDescr.posteriorAcousticFeature
- );
- return result;
- }
- public static void Init()
- {
- string shapePath = "../TrainModel/shape66.xml";
- int startTime1 = Environment.TickCount;
- LoadModel(shapePath.ToCharArray());
- int endTime1 = Environment.TickCount;
- Console.WriteLine("LoadTime:" + (endTime1 - startTime1) + "ms");
- }
- public static void Dispose()
- {
- // DisposeModel
- //FreeModel();
- }
- }
- /// <summary>
- /// 分割选用的方法
- /// </summary>
- public enum EnumSegMethod
- {
- FCM,
- ACWE,
- DRLSE,
- LBF,
- LSEWR,
- BLS, //最新的分割算法
- }
- /// <summary>
- /// 分割的输入数据
- /// </summary>
- public class SegDataInput
- {
- /// <summary>
- /// 输入图像
- /// </summary>
- public Bitmap InputImage { get; set; } = null;
- /// <summary>
- /// 感兴趣区域
- /// </summary>
- public Rectangle InputRoi { get; set; } = Rectangle.Empty;
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="img"></param>
- /// <param name="rect"></param>
- public SegDataInput(Bitmap img, Rectangle rect)
- {
- InputImage = (Bitmap)img.Clone();
- InputRoi = rect;
- }
- public void Dispose()
- {
- InputImage?.Dispose();
- }
- }
- /// <summary>
- /// 描述的输入数据
- /// </summary>
- public class DesDataInput
- {
- /// <summary>
- /// 输入图像
- /// </summary>
- public Bitmap InputImage { get; set; } = null;
- /// <summary>
- /// 感兴趣区域
- /// </summary>
- public Rectangle InputRoi { get; set; } = Rectangle.Empty;
- /// <summary>
- /// 病灶轮廓
- /// </summary>
- public PointF[] Contour { get; set; } = null;
- public DesDataInput(Bitmap img, Rectangle rect, PointF[] contour)
- {
- InputImage = (Bitmap)img.Clone();
- InputRoi = rect;
- Contour = contour;
- }
- public void Dispose()
- {
- InputImage?.Dispose();
- }
- }
- /// <summary>
- /// 病灶描述结果
- /// </summary>
- public class LesionDescriptionResult
- {
- public LesionDescriptionResult(int shape, int orientation, int echo,
- int boundary, int margin, int calcification, int posteriorAcousticFeature)
- {
- Shape = shape;
- Orientation = orientation;
- Echo = echo;
- Boundary = boundary;
- Margin = margin;
- Calcification = calcification;
- PosteriorAcousticFeature = posteriorAcousticFeature;
- }
- public bool Succeed { get; private set; }
- public int Shape { get; private set; }
- public int Orientation { get; private set; }
- public int Echo { get; private set; }
- public int Boundary { get; private set; }
- public int Margin { get; private set; }
- public int Calcification { get; private set; }
- public int PosteriorAcousticFeature { get; private set; } /// 后部声学特征 :
- }
- }
|