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