| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032 | using OpenCvSharp;using PaintDotNet.Base;using PaintDotNet.Base.Enum;using PaintDotNet.Base.Functionodel;using System;using System.Collections.Generic;using System.Drawing;using System.Linq;namespace PaintDotNet.Adjust{    /// <summary>    /// 物相提取的处理程序    /// </summary>    public unsafe class PhaseExtractionIntent    {        /// <summary>        /// 中间变量        /// </summary>        private static Mat phaseTemp;        /// <summary>        /// 中间变量        /// </summary>        private static Mat phaseTemp1;        /// <summary>        /// 中间变量        /// </summary>        private static Mat phaseTemp2;        /// <summary>        /// 视场Mat        /// </summary>        private static Mat viewMat;        /// <summary>        /// 相颜色        /// </summary>        private static Vec4b vec4B;        /// <summary>        /// 透明的颜色        /// </summary>        private static Vec4b vec4BTransparent = new Vec4b(0,0,0,0);        /// <summary>        /// RGB/HLS的范围值        /// </summary>        private static int item0L, item0R, item1L, item1R, item2L, item2R;        /// <summary>        /// 目标选择        /// </summary>        private static FieldOfViewParameters targetSelection;        /// <summary>        /// 定义物体        /// </summary>        private static DefineObjectsParameters defineObjects = DefineObjectsParameters.Click;        /// <summary>        /// 定义物体->点击->容许值        /// </summary>        private static int allowable = 0;        /// <summary>        /// 定义物体->点击->范围大小        /// </summary>        private static int scopeSize = 0;        /// <summary>        /// 定义物体->轮廓,默认多边形        /// </summary>        private static ContourParameters shape = ContourParameters.Polygon;        /// <summary>        /// 删除边界对象        /// </summary>        private static bool deleteBoundaryObject = false;        /// <summary>        /// 孔洞填充        /// </summary>        private static bool holeFilling = false;        /// <summary>        /// 碎屑删除        /// </summary>        private static bool debrisRemoval = false;        /// <summary>        /// 碎屑面积起        /// </summary>        private static int debrisAreaStart = 0;        /// <summary>        /// 碎屑面积止        /// </summary>        private static int debrisAreaEnd = 0;        /// <summary>        /// 二值样式        /// </summary>        private static StyleParameters binaryType;        /// <summary>        /// 目标选择        /// </summary>        private static ProcessingParameters targetProcess;        /// <summary>        /// RGB/HLS 默认0 rgb        /// </summary>        private static int rgborhls = 0;        /// <summary>        /// 单个目标,偏差        /// </summary>        private static int deviation = 0;        #region 无视场        /// <summary>        /// 【无视场】二值操作-物相提取        /// </summary>        /// <param name="src">源图像</param>        /// <param name="lists">参数集合</param>        /// <returns></returns>        public static Mat ImagePhaseExtraction(Mat src, PhaseModel phase, System.Drawing.Point point, List<Args> lists)        {            if (phase == null)                return src;            Mat returnValue = new Mat();            Color color = Color.FromArgb(phase.color);            vec4B = new Vec4b(color.B, color.G, color.R, 255);            //整个图像的参数            List<Args> whole = lists[0].choiseList[0].lists;            //单个目标的参数            List<Args> single = lists[0].choiseList[1].lists;            //提取模式->整个图像            bool wholeObject = (bool)(lists[0].choiseList[0].value);            //提取模式->单个目标            bool singleObject = (bool)(lists[0].choiseList[1].value);            //目标选择            targetSelection = (FieldOfViewParameters)lists[0].choiseList[2].Value;            //二值样式            binaryType = (StyleParameters)lists[0].choiseList[0].Lists[1].Value;            //目标选择            targetProcess = (ProcessingParameters)lists[0].choiseList[0].Lists[2].Value;            //整个图像            if (wholeObject)            {                //定义物体,点击或轮廓                //bool click = (bool)lists[0].choiseList[0].lists.Find(a => a.Key.Equals("defineObject")).choiseList[0].Value;                bool profile = (bool)lists[0].choiseList[0].lists.Find(a => a.Key.Equals("defineObject")).choiseList[1].Value;                defineObjects = profile ? DefineObjectsParameters.Profile : DefineObjectsParameters.Click;                //定义物体->点击->容许值                allowable = (int)((lists[0].choiseList[0].Lists[0].choiseList[0].Lists[0])).Value;                //定义物体->点击->范围大小                scopeSize = (int)((lists[0].choiseList[0].Lists[0].choiseList[0].Lists[1])).Value;                //定义物体->轮廓                shape = (ContourParameters)lists[0].choiseList[0].Lists[0].choiseList[1].lists[0].Value;                //删除边界对象                deleteBoundaryObject = (bool)whole[3].Value;                //孔洞填充                holeFilling = (bool)whole[4].Value;                //碎屑删除                debrisRemoval = (bool)whole[5].Value;                //碎屑面积                debrisAreaStart = (int)(((List<double>)lists[0].choiseList[0].Lists[6].Value)[0]);                debrisAreaEnd = (int)(((List<double>)lists[0].choiseList[0].Lists[6].Value)[1]);                //rgb或hls                rgborhls = ((bool)whole[7].choiseList[0].Value) ? 0 : 1;                //RGB/HLS的值区间                item2L = (int)(((List<double>)whole[7].choiseList[0].Lists[0].Value)[0]);                item2R = (int)(((List<double>)whole[7].choiseList[0].Lists[0].Value)[1]);                item1L = (int)(((List<double>)whole[7].choiseList[0].Lists[1].Value)[0]);                item1R = (int)(((List<double>)whole[7].choiseList[0].Lists[1].Value)[1]);                item0L = (int)(((List<double>)whole[7].choiseList[0].Lists[2].Value)[0]);                item0R = (int)(((List<double>)whole[7].choiseList[0].Lists[2].Value)[1]);            }            //提取单个目标的参数列表            if (singleObject)            {                deviation = (int)single[0].Value;            }            if (wholeObject)            {                returnValue = WholeExtract(src);            }            if (singleObject)            {                returnValue = SingleExtract(src, phase.mat, point);            }            return returnValue;        }        /// <summary>        /// 点击时的整个提取        /// </summary>        /// <param name="source"></param>        /// <returns></returns>        public static Mat WholeExtract(Mat source)        {            //原始轮廓信息            OpenCvSharp.Point[][] contours;            //轮廓的拓扑信息            HierarchyIndex[] hierachy;            //删除的对象的索引            List<int> deleteIndexs = new List<int>();            //二值提取            phaseTemp1 = new Mat(source.Rows, source.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));            //如果是rgb            if (rgborhls == 0)            {                source.ForEachAsVec4b(ForeachFunctionByteForWhole4B);            }            else            {                source.ForEachAsVec3b(ForeachFunctionByteForWhole3B);            }            //寻找轮廓            Cv2.FindContours(phaseTemp1.CvtColor(ColorConversionCodes.BGR2GRAY), out contours, out hierachy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);            //孔洞填充            phaseTemp1 = HoleFilling(holeFilling, hierachy, contours, phaseTemp1);            //寻找轮廓            Cv2.FindContours(phaseTemp1.CvtColor(ColorConversionCodes.BGR2GRAY), out contours, out hierachy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);            //删除边界对象/碎屑删除            DeleteContours(deleteBoundaryObject, debrisRemoval, contours, hierachy, debrisAreaStart, debrisAreaEnd, deleteIndexs, phaseTemp1);            //过滤掉被删除的轮廓,对剩下的填充或绘制轮廓            phaseTemp1 = FillOrDrawContours(phaseTemp1, contours, deleteIndexs, binaryType, vec4B, hierachy);            return phaseTemp1;        }        /// <summary>        /// 从全部轮廓中删除被移除的轮廓        /// 根据条件绘制轮廓或填充轮廓        /// </summary>        /// <param name="src"></param>        /// <param name="contours"></param>        /// <param name="deleteIndexs"></param>        /// <param name="binaryStyle"></param>        /// <param name="phaseColor"></param>        /// <param name="hierachy"></param>        /// <returns></returns>        private static Mat FillOrDrawContours(Mat src, OpenCvSharp.Point[][] contours,            List<int> deleteIndexs, StyleParameters binaryStyle, OpenCvSharp.Vec4b phaseColor, HierarchyIndex[] hierachy)        {            //创建一个新mat            src = new Mat(src.Size(), src.Type(), new Scalar(0, 0, 0, 0));            //src.EmptyClone();            //用于绘制的轮廓            List<OpenCvSharp.Point[]> drawContours = contours.ToList<OpenCvSharp.Point[]>();            //循环处理轮廓,过滤到被删除的轮廓及其子轮廓            if (deleteIndexs.Count > 0)            {                drawContours.Clear();                for (int i = 0; i < contours.Length; i++)                {                    if (!deleteIndexs.Exists(a => a == i))// && !deleteIndexs.Exists(a => a == hierachy[i].Parent)                    {                        drawContours.Add(contours[i]);                    }                }            }            //二值样式 1实心 2边线            if (binaryStyle == StyleParameters.Solid)            {                Cv2.FillPoly(src, drawContours, new Scalar(phaseColor.Item0, phaseColor.Item1, phaseColor.Item2, 255), LineTypes.Link8);            }            else            {                Cv2.DrawContours(src, drawContours, -1, new Scalar(phaseColor.Item0, phaseColor.Item1, phaseColor.Item2, 255), 1);            }            return src;        }        public unsafe static void ForeachFunctionByteForWhole4B(Vec4b* t, int* position)        {            int y = position[0];            int x = position[1];                        //如果是删除            if (targetProcess == ProcessingParameters.Delete)            {                phaseTemp1.Set<Vec4b>(y, x, vec4BTransparent);            }            if ((t->Item0 >= item0L && t->Item0 <= item0R)                && (t->Item1 >= item1L && t->Item1 <= item1R)                && (t->Item2 >= item2L && t->Item2 <= item2R))            {                phaseTemp1.Set<Vec4b>(y, x, vec4B);            }        }        public unsafe static void ForeachFunctionByteForWhole3B(Vec3b* t, int* position)        {            int y = position[0];            int x = position[1];            //如果是删除            if (targetProcess == ProcessingParameters.Delete)            {                phaseTemp1.Set<Vec4b>(y, x, vec4BTransparent);            }            if ((t->Item0 >= item0L && t->Item0 <= item0R)                    && (t->Item1 >= item1L && t->Item1 <= item1R)                    && (t->Item2 >= item2L && t->Item2 <= item2R))            {                phaseTemp1.Set<Vec4b>(y, x, vec4B);            }        }        /// <summary>        /// 单个目标的提取        /// </summary>        /// <param name="source">源图像</param>        /// <param name="point">鼠标点击位置</param>        /// <param name="vec4b">相颜色</param>        /// <returns></returns>        public static Mat SingleExtract(Mat source, Mat phase, System.Drawing.Point point)        {            try            {                if (phase == null)                {                    phaseTemp1 = new Mat(source.Rows, source.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));                }                else                {                    phase.CopyTo(phaseTemp1);                }                phaseTemp = new Mat(source.Rows + 2, source.Cols + 2, MatType.CV_8U, Scalar.All(0));                Mat sourceTemp = new Mat();                source.CopyTo(sourceTemp);                sourceTemp = sourceTemp.CvtColor(ColorConversionCodes.BGRA2BGR);                                Rect rect = new Rect();                Cv2.FloodFill(sourceTemp, phaseTemp, new OpenCvSharp.Point(point.X, point.Y), new Scalar(255), out rect, new Scalar(deviation, deviation, deviation), new Scalar(deviation, deviation, deviation), FloodFillFlags.Link8 | FloodFillFlags.FixedRange | FloodFillFlags.MaskOnly);                //二值样式 1实心 2边线                if (binaryType == StyleParameters.Sideline)                {                    Mat nowTemp1 = new Mat(source.Rows, source.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));                    //原始轮廓信息                    OpenCvSharp.Point[][] contours;                    //轮廓的拓扑信息                    HierarchyIndex[] hierachy;                    //去掉外边的2个像素                    //Mat roi = new Mat(phaseTemp, new Rect(1, 1, source.Width, source.Height));                    phaseTemp.ForEachAsByte(ForeachFunctionByteForChoise);                    Cv2.FindContours(phaseTemp1.CvtColor(ColorConversionCodes.BGRA2GRAY), out contours, out hierachy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);                    Cv2.DrawContours(nowTemp1, contours, -1, new Scalar(vec4B.Item0, vec4B.Item1, vec4B.Item2, 255), 1);                    nowTemp1.CopyTo(phaseTemp1);                }                else                {                    /*if(phase!=null)                    {                        //原始轮廓信息                        OpenCvSharp.Point[][] contours;                        //轮廓的拓扑信息                        HierarchyIndex[] hierachy;                        //寻找轮廓信息                        Cv2.FindContours(phase.CvtColor(ColorConversionCodes.BGR2GRAY), out contours, out hierachy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);                        List<List<OpenCvSharp.Point>> lists = new List<List<OpenCvSharp.Point>>();                        foreach (OpenCvSharp.Point[] points in contours)                        {                            lists.Add(points.ToList<OpenCvSharp.Point>());                        }                        //填充轮廓                        Cv2.FillPoly(phaseTemp, lists, new Scalar(vec4B.Item0, vec4B.Item1, vec4B.Item2, 255), LineTypes.Link8);                    }*/                    phaseTemp.ForEachAsByte(ForeachFunctionByteForChoise);                }            }            catch (Exception)            {            }            finally            {                if (phaseTemp != null && !phaseTemp.IsDisposed) phaseTemp.Dispose();            }            return phaseTemp1;        }        /// <summary>        /// 单个目标的提取        /// </summary>        /// <param name="value"></param>        /// <param name="position"></param>        public unsafe static void ForeachFunctionByteForChoise(byte* value, int* position)        {            int y = position[0];            int x = position[1];            byte intencity = *value;            if (intencity == 1 && x > 0 && y > 0 && x < phaseTemp.Width - 1 && y < phaseTemp.Height - 1)            {                phaseTemp1.Set<Vec4b>(y - 1, x - 1, vec4B);            }        }        /// <summary>        /// 孔洞填充        /// </summary>        /// <param name="holeFilling"></param>        /// <param name="hierachy"></param>        /// <param name="contours"></param>        /// <param name="src"></param>        /// <returns></returns>        private static Mat HoleFilling(bool holeFilling, HierarchyIndex[] hierachy,            OpenCvSharp.Point[][] contours, Mat src)        {            if (holeFilling && hierachy != null)            {                for (int i = 0; i < hierachy.Length; i++)                {                    //如果需要还可以判断面积范围                    if (hierachy[i].Parent > -1)                    {                        List<List<OpenCvSharp.Point>> ps = new List<List<OpenCvSharp.Point>>();                        ps.Add(contours[i].ToList());                        Cv2.FillPoly(src, ps, new Scalar(255, 0, 0, 255));                    }                }            }            return src;        }        /// <summary>        /// 删除边界对象 以及 碎屑删除        /// </summary>        /// <param name="deleteBoundaryObject">是否删除边界对象</param>        /// <param name="debrisRemoval">是否删除碎屑</param>        /// <param name="contours">轮廓</param>        /// <param name="hierachy">结构</param>        /// <param name="debrisAreaStart">碎屑面积</param>        /// <param name="debrisAreaEnd">碎屑面积</param>        /// <param name="deleteIndexs">被删除的轮廓的下标</param>        /// <param name="src">源</param>        public static void DeleteContours(bool deleteBoundaryObject, bool debrisRemoval,            OpenCvSharp.Point[][] contours, HierarchyIndex[] hierachy,            int debrisAreaStart, int debrisAreaEnd, List<int> deleteIndexs, Mat src)        {            if ((deleteBoundaryObject || debrisRemoval) && contours != null)            {                if (contours.Length > 0)                {                    for (int i = 0; i < contours.Length; i++)                    {                        bool delete = false;                        if (debrisRemoval)                        {                            double area = Cv2.ContourArea(contours[i]);                            if (area >= debrisAreaStart && area <= debrisAreaEnd && hierachy[i].Parent == -1)                            {                                deleteIndexs.Add(i);                                List<OpenCvSharp.Point[]> pointsTemp = new List<OpenCvSharp.Point[]>();                                RecursiveFindChildContours(contours.ToList(), hierachy, i, deleteIndexs);                                delete = true;                            }                        }                        if (deleteBoundaryObject && !delete)                        {                            for (int y = 0; y < contours[i].Length; y++)                            {                                if (contours[i][y].X == 0 || contours[i][y].X == src.Width-1 || contours[i][y].Y == 0 || contours[i][y].Y == src.Height-1)                                {                                    deleteIndexs.Add(i);                                    List<OpenCvSharp.Point[]> pointsTemp = new List<OpenCvSharp.Point[]>();                                    RecursiveFindChildContours(contours.ToList(), hierachy, i, deleteIndexs);                                    break;                                }                            }                        }                    }                }            }        }        #endregion        #region 有视场        public static Mat ImagePhaseExtractionWithView(Mat hls, Mat rgb, Mat origin, PhaseModel phase, System.Drawing.Point point, List<Args> lists)        {            viewMat = hls;            Mat returnValue = new Mat();            Color color = Color.FromArgb(phase.color);            vec4B = new Vec4b(color.B, color.G, color.R, 255);            //整个图像的参数            List<Args> whole = lists[0].choiseList[0].lists;            //单个目标的参数            List<Args> single = lists[0].choiseList[1].lists;            //提取模式->整个图像            bool wholeObject = (bool)(lists[0].choiseList[0].value);            //提取模式->单个目标            bool singleObject = (bool)(lists[0].choiseList[1].value);            //目标选择            targetSelection = (FieldOfViewParameters)lists[0].choiseList[2].Value;            //二值样式            binaryType = (StyleParameters)lists[0].choiseList[0].Lists[1].Value;            //目标选择            targetProcess = (ProcessingParameters)lists[0].choiseList[0].Lists[2].Value;            //整个图像            if (wholeObject)            {                //定义物体,点击或轮廓                //bool click = (bool)lists[0].choiseList[0].lists.Find(a => a.Key.Equals("defineObject")).choiseList[0].Value;                bool profile = (bool)lists[0].choiseList[0].lists.Find(a => a.Key.Equals("defineObject")).choiseList[1].Value;                defineObjects = profile ? DefineObjectsParameters.Profile : DefineObjectsParameters.Click;                //定义物体->点击->容许值                allowable = (int)((lists[0].choiseList[0].Lists[0].choiseList[0].Lists[0])).Value;                //定义物体->点击->范围大小                scopeSize = (int)((lists[0].choiseList[0].Lists[0].choiseList[0].Lists[1])).Value;                //定义物体->轮廓                shape = (ContourParameters)lists[0].choiseList[0].Lists[0].choiseList[1].lists[0].Value;                //删除边界对象                deleteBoundaryObject = (bool)whole[3].Value;                //孔洞填充                holeFilling = (bool)whole[4].Value;                //碎屑删除                debrisRemoval = (bool)whole[5].Value;                //碎屑面积                debrisAreaStart = (int)(((List<double>)lists[0].choiseList[0].Lists[6].Value)[0]);                debrisAreaEnd = (int)(((List<double>)lists[0].choiseList[0].Lists[6].Value)[1]);                                //rgb或hls                rgborhls = ((bool)whole[7].choiseList[0].Value) ? 0 : 1;                //RGB/HLS的值区间                item2L = (int)(((List<double>)whole[7].choiseList[0].Lists[0].Value)[0]);                item2R = (int)(((List<double>)whole[7].choiseList[0].Lists[0].Value)[1]);                item1L = (int)(((List<double>)whole[7].choiseList[0].Lists[1].Value)[0]);                item1R = (int)(((List<double>)whole[7].choiseList[0].Lists[1].Value)[1]);                item0L = (int)(((List<double>)whole[7].choiseList[0].Lists[2].Value)[0]);                item0R = (int)(((List<double>)whole[7].choiseList[0].Lists[2].Value)[1]);            }            //提取单个目标的参数列表            if (singleObject)            {                deviation = (int)single[0].Value;            }            if (wholeObject)            {                returnValue = WholeExtractView(hls, phase.mat, rgb);            }            if (singleObject)            {                returnValue = SingleExtractView(hls, phase.mat, point);            }            return returnValue;        }        /// <summary>        /// 点击时的整个提取        /// </summary>        /// <param name="view">视场mat,rgb或hls</param>        /// <param name="matBin">if(rgb){ 原图的mat }else if(hls){ rgba视场的mat }</param>        /// <returns></returns>        public static Mat WholeExtractView(Mat hls, Mat rgb, Mat origin)        {            //原图内轮廓信息            OpenCvSharp.Point[][] originContours;            //原图内轮廓的拓扑信息            HierarchyIndex[] originHierachy;            //原始轮廓信息            OpenCvSharp.Point[][] contours;            //轮廓的拓扑信息            HierarchyIndex[] hierachy;            //删除的对象的索引            List<int> deleteIndexs = new List<int>();            //二值提取            phaseTemp = new Mat(hls.Rows, hls.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));            phaseTemp1 = new Mat(hls.Rows, hls.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));            phaseTemp2 = origin;            if (rgborhls==0)            {                origin.ForEachAsVec4b(ForeachFunctionByteForWholeWithView4B);            }            else            {                hls.ForEachAsVec3b(ForeachFunctionByteForWholeWithView3B);            }            //Cv2.ImShow("原", phaseTemp);            //原图mat寻找轮廓            Cv2.FindContours(phaseTemp.CvtColor(ColorConversionCodes.BGR2GRAY), out originContours, out originHierachy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);            //寻找轮廓            Cv2.FindContours(phaseTemp1.CvtColor(ColorConversionCodes.BGR2GRAY), out contours, out hierachy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);            //孔洞填充            phaseTemp1 = HoleFillingWithView(holeFilling, hierachy, contours, phaseTemp1, vec4B);            //寻找轮廓            Cv2.FindContours(phaseTemp1.CvtColor(ColorConversionCodes.BGR2GRAY), out contours, out hierachy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);            //删除边界对象/碎屑删除            DeleteContoursWithView(deleteBoundaryObject, debrisRemoval, contours, hierachy, debrisAreaStart, debrisAreaEnd, deleteIndexs, phaseTemp1);            //过滤掉被删除的轮廓,对剩下的填充或绘制轮廓            phaseTemp1 = FillOrDrawContoursWithView(holeFilling, phaseTemp1, contours, originContours, deleteIndexs, binaryType, vec4B, hierachy, originHierachy, targetSelection);            return phaseTemp1;        }        /// <summary>        /// 单个目标的提取        /// </summary>        /// <param name="source">源图像</param>        /// <param name="point">鼠标点击位置</param>        /// <param name="vec4b">相颜色</param>        /// <returns></returns>        public static Mat SingleExtractView(Mat source, Mat phase, System.Drawing.Point point)        {            try            {                if (phase == null)                {                    phaseTemp1 = new Mat(source.Rows, source.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));                }                else                {                    phase.CopyTo(phaseTemp1);                }                phaseTemp = new Mat(source.Rows + 2, source.Cols + 2, MatType.CV_8U, Scalar.All(0));                Mat sourceTemp = new Mat();                source.CopyTo(sourceTemp);                sourceTemp = sourceTemp.CvtColor(ColorConversionCodes.BGRA2BGR);                Rect rect = new Rect();                Cv2.FloodFill(sourceTemp, phaseTemp, new OpenCvSharp.Point(point.X, point.Y), new Scalar(255), out rect, new Scalar(deviation, deviation, deviation), new Scalar(deviation, deviation, deviation), FloodFillFlags.Link8 | FloodFillFlags.FixedRange | FloodFillFlags.MaskOnly);                phaseTemp.ForEachAsByte(ForeachFunctionByteForChoiseWithView);            }            catch (Exception)            {            }            finally            {                if (phaseTemp != null && !phaseTemp.IsDisposed) phaseTemp.Dispose();            }            return phaseTemp1;        }        public unsafe static void ForeachFunctionByteForChoiseWithView(byte* value, int* position)        {            int y = position[0];            int x = position[1];            byte intencity = *value;            if (intencity == 1 && x > 0 && y > 0 && x < phaseTemp.Width - 1 && y < phaseTemp.Height - 1)            {                if(viewMat.At<Vec4b>(y - 1, x - 1)[3]>0)                    phaseTemp1.Set<Vec4b>(y - 1, x - 1, vec4B);            }        }        public unsafe static void ForeachFunctionByteForWholeWithView4B(Vec4b* t, int* position)        {            int y = position[0];            int x = position[1];            //如果是删除            if (targetProcess == ProcessingParameters.Delete)            {                phaseTemp1.Set<Vec4b>(y, x, vec4BTransparent);            }            //如果不透明则进行处理            //if (t->Item3 > 0)             {                if ((t->Item0 >= item0L && t->Item0 <= item0R)                    && (t->Item1 >= item1L && t->Item1 <= item1R)                    && (t->Item2 >= item2L && t->Item2 <= item2R))                {                    phaseTemp.Set<Vec4b>(y, x, vec4B);                                     if (t->Item3 > 0)                        phaseTemp1.Set<Vec4b>(y, x, vec4B);                }            }        }        public unsafe static void ForeachFunctionByteForWholeWithView3B(Vec3b* t, int* position)        {            int y = position[0];            int x = position[1];            //如果是删除            if (targetProcess == ProcessingParameters.Delete)            {                phaseTemp1.Set<Vec4b>(y, x, vec4BTransparent);            }            Vec4b m4b = phaseTemp2.At<Vec4b>(y, x);            //如果不透明则进行处理            //if (m4b.Item3 > 0)            {                if ((t->Item0 >= item0L && t->Item0 <= item0R)                    && (t->Item1 >= item1L && t->Item1 <= item1R)                    && (t->Item2 >= item2L && t->Item2 <= item2R))                {                    phaseTemp.Set<Vec4b>(y, x, vec4B);                    if (m4b.Item3 > 0)                        phaseTemp1.Set<Vec4b>(y, x, vec4B);                }            }        }                /// <summary>        /// 孔洞填充        /// </summary>        /// <param name="holeFilling"></param>        /// <param name="hierachy"></param>        /// <param name="contours"></param>        /// <param name="src"></param>        /// <param name="phaseColor"></param>        /// <returns></returns>        private static Mat HoleFillingWithView(bool holeFilling, HierarchyIndex[] hierachy,            OpenCvSharp.Point[][] contours, Mat src, Vec4b phaseColor)        {            if (holeFilling && hierachy != null)            {                for (int i = 0; i < hierachy.Length; i++)                {                    //如果需要还可以判断面积范围                    if (hierachy[i].Parent > -1)                    {                        List<List<OpenCvSharp.Point>> ps = new List<List<OpenCvSharp.Point>>();                        ps.Add(contours[i].ToList());                        Cv2.FillPoly(src, ps, new Scalar(phaseColor.Item0, phaseColor.Item1, phaseColor.Item2, 255));                    }                }            }            return src;        }        /// <summary>        /// 删除边界对象 以及 碎屑删除        /// </summary>        /// <param name="deleteBoundaryObject">是否删除边界对象</param>        /// <param name="debrisRemoval">是否删除碎屑</param>        /// <param name="contours">轮廓</param>        /// <param name="hierachy">结构</param>        /// <param name="debrisAreaStart">碎屑面积</param>        /// <param name="debrisAreaEnd">碎屑面积</param>        /// <param name="deleteIndexs">被删除的轮廓的下标</param>        /// <param name="src">源</param>        public static void DeleteContoursWithView(bool deleteBoundaryObject, bool debrisRemoval,            OpenCvSharp.Point[][] contours, HierarchyIndex[] hierachy,            int debrisAreaStart, int debrisAreaEnd, List<int> deleteIndexs, Mat src)        {            if ((deleteBoundaryObject || debrisRemoval) && contours != null)            {                if (contours.Length > 0)                {                    for (int i = 0; i < contours.Length; i++)                    {                        bool delete = false;                        if (debrisRemoval)                        {                            double area = Cv2.ContourArea(contours[i]);                            if (area > debrisAreaStart && area < debrisAreaEnd && hierachy[i].Parent == -1)                            {                                deleteIndexs.Add(i);                                RecursiveFindChildContours(contours.ToList(), hierachy, i, deleteIndexs);                                delete = true;                            }                        }                        if (deleteBoundaryObject && !delete)                        {                            for (int y = 0; y < contours[i].Length; y++)                            {                                if (contours[i][y].X == 0 || contours[i][y].X == src.Width-1 || contours[i][y].Y == 0 || contours[i][y].Y == src.Height-1)                                {                                    deleteIndexs.Add(i);                                    RecursiveFindChildContours(contours.ToList(), hierachy, i, deleteIndexs);                                    break;                                }                            }                        }                    }                }            }        }        /// <summary>        /// 从全部轮廓中删除被移除的轮廓        /// 根据条件绘制轮廓或填充轮廓        /// </summary>        /// <param name="src"></param>        /// <param name="contours">视场图轮廓</param>        /// <param name="originContours">原图轮廓</param>        /// <param name="deleteIndexs"></param>        /// <param name="binaryStyle"></param>        /// <param name="phaseColor"></param>        /// <param name="hierachy"></param>        /// <param name="targetSelection">目标选择</param>        /// <returns></returns>        private static Mat FillOrDrawContoursWithView(bool holeFilling, Mat src, OpenCvSharp.Point[][] contours, OpenCvSharp.Point[][] originContours,            List<int> deleteIndexs, StyleParameters binaryStyle, Vec4b phaseColor, HierarchyIndex[] hierachy, HierarchyIndex[] originHierachy, FieldOfViewParameters targetSelection)        {            if(src==null)                src = new Mat(phaseTemp1.Size(), phaseTemp1.Type(), new Scalar(0, 0, 0, 0));            //创建一个新mat            //Mat src = new Mat(temp.Size(), temp.Type(), new Scalar(0, 0, 0, 0));            //用于绘制的轮廓            List<OpenCvSharp.Point[]> drawContours = contours.ToList<OpenCvSharp.Point[]>();            //用于绘制的轮廓对应的关系            List<HierarchyIndex> hierachys = new List<HierarchyIndex>();            //处理目标选择,以及过滤到被删除的轮廓及其子轮廓            drawContours = CalcContoursByTargetSelection(holeFilling, deleteIndexs, drawContours, hierachy, originContours, originHierachy, targetSelection);                        if(drawContours.Count == 0) drawContours = contours.ToList<OpenCvSharp.Point[]>();            //二值样式 1实心 2边线            if (binaryStyle == StyleParameters.Solid)            {                Cv2.FillPoly(src, drawContours, new Scalar(phaseColor.Item0, phaseColor.Item1, phaseColor.Item2, 255));            }            else            {                Cv2.DrawContours(src, drawContours, -1, new Scalar(phaseColor.Item0, phaseColor.Item1, phaseColor.Item2, 255), 1);            }            return src;        }        /// <summary>        /// 根据目标选择参数进行轮廓的筛选        /// </summary>        /// <param name="drawContours">经过筛选的视场图内的轮廓</param>        /// <param name="originContours">原图二值化后的所有轮廓</param>        /// <returns></returns>        private static List<OpenCvSharp.Point[]> CalcContoursByTargetSelection(bool holeFilling, List<int> deleteIndexs, List<OpenCvSharp.Point[]> drawContours, HierarchyIndex[] hierachy, OpenCvSharp.Point[][] originContours, HierarchyIndex[] originHierachy, FieldOfViewParameters targetSelection)        {            List<OpenCvSharp.Point[]> points = new List<OpenCvSharp.Point[]>();            List<OpenCvSharp.Point[]> originPoints = originContours.ToList<OpenCvSharp.Point[]>();            if (targetSelection == FieldOfViewParameters.One)            {                int k = 0;                foreach (OpenCvSharp.Point[] ps in drawContours)                {                    if (deleteIndexs.Count > 0)                    {                        if (deleteIndexs.Exists(a => a == k))                        {                            k++;                            continue;                        }                    }                    foreach (OpenCvSharp.Point[] os in originPoints)                    {                        if (Cv2.PointPolygonTest(os, ps[0], false) >= 0)                        {                            if (Cv2.ContourArea(ps, false) == Cv2.ContourArea(os, false))                            {                                if (hierachy[k].Parent == -1)                                {                                    points.Add(ps);                                    List<OpenCvSharp.Point[]> pointsTemp = new List<OpenCvSharp.Point[]>();                                    RecursiveFindChildContours(drawContours, hierachy, k, pointsTemp);                                    points.AddRange(pointsTemp);                                }                            }                        }                    }                    k++;                }            }            else if (targetSelection == FieldOfViewParameters.Two)            {                if (deleteIndexs.Count > 0)                {                    for (int i = 0; i < drawContours.Count; i++)                    {                        if (!deleteIndexs.Exists(a => a == i) && !deleteIndexs.Exists(a => a == hierachy[i].Parent))                        {                            points.Add(drawContours[i]);                        }                    }                }                else                {                    points = drawContours;                }            }            else if (targetSelection == FieldOfViewParameters.Three)            {                List<int> smallInt = new List<int>();                List<int> bigInt = new List<int>();                int k = 0;                foreach (OpenCvSharp.Point[] ps in drawContours)                {                    int f = 0;                    if (deleteIndexs.Count > 0)                    {                        if (deleteIndexs.Exists(a => a == k))                        {                            k++;                            continue;                        }                    }                    foreach (OpenCvSharp.Point[] os in originPoints)                    {                        if (Cv2.PointPolygonTest(os, ps[0], false) >= 0 && hierachy[k].Parent == -1)                        {                            if (Cv2.ContourArea(ps, false) == Cv2.ContourArea(os, false))                            {                                if (originHierachy[f].Parent == -1)                                {                                    if (!smallInt.Exists(a => a == k))                                    {                                        smallInt.Add(k);                                        points.Add(ps);                                        if (!holeFilling)                                        {                                            List<OpenCvSharp.Point[]> pointsTemp = new List<OpenCvSharp.Point[]>();                                            RecursiveFindChildContours(drawContours, hierachy, k, pointsTemp);                                            points.AddRange(pointsTemp);                                        }                                    }                                }                            }                            else                            {                                if (originHierachy[f].Parent == -1)                                {                                    if (!bigInt.Exists(a => a == f))                                    {                                        bigInt.Add(f);                                        points.Add(os);                                        if (!holeFilling)                                        {                                            List<OpenCvSharp.Point[]> pointsTemp = new List<OpenCvSharp.Point[]>();                                            RecursiveFindChildContours(originPoints, originHierachy, f, pointsTemp);                                            points.AddRange(pointsTemp);                                        }                                    }                                }                            }                        }                        f++;                    }                    k++;                }            }            return points;        }        #endregion        #region 公共递归方法        /// <summary>        /// 递归处理        /// </summary>        /// <param name="drawContours"></param>        /// <param name="hierachy"></param>        /// <param name="position"></param>        /// <param name="points"></param>        private static void RecursiveFindChildContours(            List<OpenCvSharp.Point[]> drawContours,            HierarchyIndex[] hierachy,            int position,            List<OpenCvSharp.Point[]> points            )        {            int m = 0;            foreach (HierarchyIndex index in hierachy)            {                if (index.Parent == position)                {                    points.Add(drawContours[m]);                    RecursiveFindChildContours(drawContours, hierachy, m, points);                }                m++;            }        }        /// <summary>        /// 递归处理        /// </summary>        /// <param name="drawContours"></param>        /// <param name="hierachy"></param>        /// <param name="position"></param>        /// <param name="points"></param>        private static void RecursiveFindChildContours(            List<OpenCvSharp.Point[]> drawContours,            HierarchyIndex[] hierachy,            int position,            List<int> points            )        {            int m = 0;            foreach (HierarchyIndex index in hierachy)            {                if (index.Parent == position)                {                    points.Add(m);                    RecursiveFindChildContours(drawContours, hierachy, m, points);                }                m++;            }        }        #endregion        #region 无视场删除        #endregion        #region 有视场删除        #endregion    }}
 |