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
{
///
/// 物相提取的处理程序
///
public unsafe class PhaseExtractionIntent
{
///
/// 中间变量
///
private static Mat phaseTemp;
///
/// 中间变量
///
private static Mat phaseTemp1;
///
/// 中间变量
///
private static Mat phaseTemp2;
///
/// 视场Mat
///
private static Mat viewMat;
///
/// 相颜色
///
private static Vec4b vec4B;
///
/// 透明的颜色
///
private static Vec4b vec4BTransparent = new Vec4b(0,0,0,0);
///
/// RGB/HLS的范围值
///
private static int item0L, item0R, item1L, item1R, item2L, item2R;
///
/// 目标选择
///
private static FieldOfViewParameters targetSelection;
///
/// 定义物体
///
private static DefineObjectsParameters defineObjects = DefineObjectsParameters.Click;
///
/// 定义物体->点击->容许值
///
private static int allowable = 0;
///
/// 定义物体->点击->范围大小
///
private static int scopeSize = 0;
///
/// 定义物体->轮廓,默认多边形
///
private static ContourParameters shape = ContourParameters.Polygon;
///
/// 删除边界对象
///
private static bool deleteBoundaryObject = false;
///
/// 孔洞填充
///
private static bool holeFilling = false;
///
/// 碎屑删除
///
private static bool debrisRemoval = false;
///
/// 碎屑面积起
///
private static int debrisAreaStart = 0;
///
/// 碎屑面积止
///
private static int debrisAreaEnd = 0;
///
/// 二值样式
///
private static StyleParameters binaryType;
///
/// 目标选择
///
private static ProcessingParameters targetProcess;
///
/// RGB/HLS 默认0 rgb
///
private static int rgborhls = 0;
///
/// 单个目标,偏差
///
private static int deviation = 0;
#region 无视场
///
/// 【无视场】二值操作-物相提取
///
/// 源图像
/// 参数集合
///
public static Mat ImagePhaseExtraction(Mat src, PhaseModel phase, System.Drawing.Point point, List 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 whole = lists[0].choiseList[0].lists;
//单个目标的参数
List 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)lists[0].choiseList[0].Lists[6].Value)[0]);
debrisAreaEnd = (int)(((List)lists[0].choiseList[0].Lists[6].Value)[1]);
//rgb或hls
rgborhls = ((bool)whole[7].choiseList[0].Value) ? 0 : 1;
//RGB/HLS的值区间
item2L = (int)(((List)whole[7].choiseList[0].Lists[0].Value)[0]);
item2R = (int)(((List)whole[7].choiseList[0].Lists[0].Value)[1]);
item1L = (int)(((List)whole[7].choiseList[0].Lists[1].Value)[0]);
item1R = (int)(((List)whole[7].choiseList[0].Lists[1].Value)[1]);
item0L = (int)(((List)whole[7].choiseList[0].Lists[2].Value)[0]);
item0R = (int)(((List)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;
}
///
/// 点击时的整个提取
///
///
///
public static Mat WholeExtract(Mat source)
{
//原始轮廓信息
OpenCvSharp.Point[][] contours;
//轮廓的拓扑信息
HierarchyIndex[] hierachy;
//删除的对象的索引
List deleteIndexs = new List();
//二值提取
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;
}
///
/// 从全部轮廓中删除被移除的轮廓
/// 根据条件绘制轮廓或填充轮廓
///
///
///
///
///
///
///
///
private static Mat FillOrDrawContours(Mat src, OpenCvSharp.Point[][] contours,
List 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 drawContours = contours.ToList();
//循环处理轮廓,过滤到被删除的轮廓及其子轮廓
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(y, x, vec4BTransparent);
}
if ((t->Item0 >= item0L && t->Item0 <= item0R)
&& (t->Item1 >= item1L && t->Item1 <= item1R)
&& (t->Item2 >= item2L && t->Item2 <= item2R))
{
phaseTemp1.Set(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(y, x, vec4BTransparent);
}
if ((t->Item0 >= item0L && t->Item0 <= item0R)
&& (t->Item1 >= item1L && t->Item1 <= item1R)
&& (t->Item2 >= item2L && t->Item2 <= item2R))
{
phaseTemp1.Set(y, x, vec4B);
}
}
///
/// 单个目标的提取
///
/// 源图像
/// 鼠标点击位置
/// 相颜色
///
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> lists = new List>();
foreach (OpenCvSharp.Point[] points in contours)
{
lists.Add(points.ToList());
}
//填充轮廓
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;
}
///
/// 单个目标的提取
///
///
///
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(y - 1, x - 1, vec4B);
}
}
///
/// 孔洞填充
///
///
///
///
///
///
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> ps = new List>();
ps.Add(contours[i].ToList());
Cv2.FillPoly(src, ps, new Scalar(255, 0, 0, 255));
}
}
}
return src;
}
///
/// 删除边界对象 以及 碎屑删除
///
/// 是否删除边界对象
/// 是否删除碎屑
/// 轮廓
/// 结构
/// 碎屑面积
/// 碎屑面积
/// 被删除的轮廓的下标
/// 源
public static void DeleteContours(bool deleteBoundaryObject, bool debrisRemoval,
OpenCvSharp.Point[][] contours, HierarchyIndex[] hierachy,
int debrisAreaStart, int debrisAreaEnd, List 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 pointsTemp = new List();
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 pointsTemp = new List();
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 lists)
{
viewMat = hls;
Mat returnValue = new Mat();
Color color = Color.FromArgb(phase.color);
vec4B = new Vec4b(color.B, color.G, color.R, 255);
//整个图像的参数
List whole = lists[0].choiseList[0].lists;
//单个目标的参数
List 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)lists[0].choiseList[0].Lists[6].Value)[0]);
debrisAreaEnd = (int)(((List)lists[0].choiseList[0].Lists[6].Value)[1]);
//rgb或hls
rgborhls = ((bool)whole[7].choiseList[0].Value) ? 0 : 1;
//RGB/HLS的值区间
item2L = (int)(((List)whole[7].choiseList[0].Lists[0].Value)[0]);
item2R = (int)(((List)whole[7].choiseList[0].Lists[0].Value)[1]);
item1L = (int)(((List)whole[7].choiseList[0].Lists[1].Value)[0]);
item1R = (int)(((List)whole[7].choiseList[0].Lists[1].Value)[1]);
item0L = (int)(((List)whole[7].choiseList[0].Lists[2].Value)[0]);
item0R = (int)(((List)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;
}
///
/// 点击时的整个提取
///
/// 视场mat,rgb或hls
/// if(rgb){ 原图的mat }else if(hls){ rgba视场的mat }
///
public static Mat WholeExtractView(Mat hls, Mat rgb, Mat origin)
{
//原图内轮廓信息
OpenCvSharp.Point[][] originContours;
//原图内轮廓的拓扑信息
HierarchyIndex[] originHierachy;
//原始轮廓信息
OpenCvSharp.Point[][] contours;
//轮廓的拓扑信息
HierarchyIndex[] hierachy;
//删除的对象的索引
List deleteIndexs = new List();
//二值提取
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;
}
///
/// 单个目标的提取
///
/// 源图像
/// 鼠标点击位置
/// 相颜色
///
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(y - 1, x - 1)[3]>0)
phaseTemp1.Set(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(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(y, x, vec4B);
if (t->Item3 > 0)
phaseTemp1.Set(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(y, x, vec4BTransparent);
}
Vec4b m4b = phaseTemp2.At(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(y, x, vec4B);
if (m4b.Item3 > 0)
phaseTemp1.Set(y, x, vec4B);
}
}
}
///
/// 孔洞填充
///
///
///
///
///
///
///
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> ps = new List>();
ps.Add(contours[i].ToList());
Cv2.FillPoly(src, ps, new Scalar(phaseColor.Item0, phaseColor.Item1, phaseColor.Item2, 255));
}
}
}
return src;
}
///
/// 删除边界对象 以及 碎屑删除
///
/// 是否删除边界对象
/// 是否删除碎屑
/// 轮廓
/// 结构
/// 碎屑面积
/// 碎屑面积
/// 被删除的轮廓的下标
/// 源
public static void DeleteContoursWithView(bool deleteBoundaryObject, bool debrisRemoval,
OpenCvSharp.Point[][] contours, HierarchyIndex[] hierachy,
int debrisAreaStart, int debrisAreaEnd, List 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;
}
}
}
}
}
}
}
///
/// 从全部轮廓中删除被移除的轮廓
/// 根据条件绘制轮廓或填充轮廓
///
///
/// 视场图轮廓
/// 原图轮廓
///
///
///
///
/// 目标选择
///
private static Mat FillOrDrawContoursWithView(bool holeFilling, Mat src, OpenCvSharp.Point[][] contours, OpenCvSharp.Point[][] originContours,
List 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 drawContours = contours.ToList();
//用于绘制的轮廓对应的关系
List hierachys = new List();
//处理目标选择,以及过滤到被删除的轮廓及其子轮廓
drawContours = CalcContoursByTargetSelection(holeFilling, deleteIndexs, drawContours, hierachy, originContours, originHierachy, targetSelection);
if(drawContours.Count == 0) drawContours = contours.ToList();
//二值样式 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;
}
///
/// 根据目标选择参数进行轮廓的筛选
///
/// 经过筛选的视场图内的轮廓
/// 原图二值化后的所有轮廓
///
private static List CalcContoursByTargetSelection(bool holeFilling, List deleteIndexs, List drawContours, HierarchyIndex[] hierachy, OpenCvSharp.Point[][] originContours, HierarchyIndex[] originHierachy, FieldOfViewParameters targetSelection)
{
List points = new List();
List originPoints = originContours.ToList();
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 pointsTemp = new List();
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 smallInt = new List();
List bigInt = new List();
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 pointsTemp = new List();
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 pointsTemp = new List();
RecursiveFindChildContours(originPoints, originHierachy, f, pointsTemp);
points.AddRange(pointsTemp);
}
}
}
}
}
f++;
}
k++;
}
}
return points;
}
#endregion
#region 公共递归方法
///
/// 递归处理
///
///
///
///
///
private static void RecursiveFindChildContours(
List drawContours,
HierarchyIndex[] hierachy,
int position,
List points
)
{
int m = 0;
foreach (HierarchyIndex index in hierachy)
{
if (index.Parent == position)
{
points.Add(drawContours[m]);
RecursiveFindChildContours(drawContours, hierachy, m, points);
}
m++;
}
}
///
/// 递归处理
///
///
///
///
///
private static void RecursiveFindChildContours(
List drawContours,
HierarchyIndex[] hierachy,
int position,
List 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
}
}