using OpenCvSharp;
using PaintDotNet.Annotation;
using PaintDotNet.Base;
using PaintDotNet.Base.CommTool;
using PaintDotNet.Base.Functionodel;
using PaintDotNet.Base.SettingModel;
using PaintDotNet.Data.Param;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
namespace PaintDotNet
{
class BinaryClassForB
{
private int menuId;
protected static string ParamKey_binaryStyle = "binaryStyle";//二值样式
//protected static string ParamKey_displaygrid = "displaygrid";//显示网格
//protected static string ParamKey_displaysections = "displaysections";//显示截点
///
/// 是否针对全图进行二值化操作
///
public bool processWholeMat = false;
///
/// 是否显示视场
///
public Boolean ShowDrawClassView = true;
///
/// 调色板
///
PaintDotNet.ColorsForm colorsForm1;
///
/// 构造工作结构
///
private Dictionary documentItems;
///
/// 需要的数据在这里引用
///
CustomControl.BinaryControlSmaller bmc;
///
/// 需要的数据在这里引用
///
CustomControl.BinaryControl bc;
AppWorkspace appWorkspace;
DocumentWorkspaceWindow documentWorkspace;
ListView listView1;
public DedicatedAnalysis.Battery.BatteryCrackBallDialog parent { get; set; }
//二次球与单晶
public DedicatedAnalysis.Battery.BatteryBallAndCrystalDialog parentCrystal { get; set; }
//单晶
public DedicatedAnalysis.Battery.BatteryCrystalDialog parentSinglCrystal { get; set; }
//单晶
public DedicatedAnalysis.Battery.BatteryPrimaryDialog parentPrimary { get; set; }
///
/// 是否要调用二值化的算法
///
private bool toApplyBinary = true;
///
/// 处理程序
///
private ParamObject action = new Data.Action.Action0001();
///
/// 二值参数配置值(当前图片)
///
private BinaryExtractionModel binaryExtractionModel;
///
/// 二值参数是否进行全部应用,用于更新图片二值化效果,默认为false
///
private Dictionary binaryModelFlag = new Dictionary();
///
/// 二值参数配置值(全部图片的)
///
private Dictionary binaryModelDict = new Dictionary();
///
/// 二值(备份全部图片)
///
private Dictionary binaryData1Dict = new Dictionary();
///
/// 相0的图片,处理多视场使用
///
public Mat PhaseModels0Mat;
///
/// 辅助线集成
///
public PaintDotNet.DedicatedAnalysis.GrainSizeStandard.IntegrationClass.GrainSizeGuideClass guideClass;
public ComboBox comboBox1;
public static Mat dstBinary;
//最大轮廓
public OpenCvSharp.Point[] maxContour = new OpenCvSharp.Point[] { };
//中心点
public OpenCvSharp.Point center = new OpenCvSharp.Point();
//指定圆心
public OpenCvSharp.Point SetCenter = new OpenCvSharp.Point();
double maxArea = 0;
//半径
public int r = 0;
//半径
public int R = 0;
//同心圆数
public int CilCount = 0;
/// 存储轮廓集合
private List> lineList = new List>();
/// 存储添加孔隙集合
private List> kongLineList = new List>();
/// 存储删除孔隙集合
private List delLineList = new List();
/// 存储轮廓集合
private List> lineList_ball = new List>();
/// 存储开裂球
private List kailie_ball = new List();
/// 存储普通球
private List putong_ball = new List();
//存储选择球
private PointF selectPointFs = new PointF();
//处理后画过轮廓的截面孔隙图
private Mat LunkMat = new Mat();
//处理后的单晶图片
private Bitmap bitDJ;
//模块编号:1开裂球,2单晶,3二次球与单晶
public int imageType { set; get; }
//单晶尺寸
public double pointsize { set; get; }
//边界
public int border { set; get; }
//长宽比
public double HW { set; get; }
//面积率
public double AreaRatio { set; get; }
//底边区域
public int borderBottom { set; get; }
//保留小数位数
public int numDecimals { set; get; }
//筛选条件
public int CheckState { set; get; }
//是否画测距
public bool isDis = false;
//是否画矩形
public bool isJu = false;
///
/// 单位标尺
///
public double unitLength = 1;
//测量区域
public List Contour { set; get; }
//提示框内容
public string tipString = "";
///
/// 公开的事件,每次二值化之后需要的计算事件写在这里
///
public event EventHandler BinaryImplFinishAction;
private void OnBinaryImplFinishAction()
{
if (BinaryImplFinishAction != null)
{
BinaryImplFinishAction(this, new EventArgs());
}
}
public BinaryClassForB(int menuId)
{
this.menuId = menuId;
}
public void InitBinaryControlEvent()
{
if (bmc != null)
{
bmc.InitBinaryControlEvent();
bmc.BinaryGetParamAction += new EventHandler(this.bcBinaryGetParamAction);
bmc.AutoThresClickAction += new EventHandler(this.bcAutoThresClickAction);
bmc.InverseClickAction += new EventHandler(this.bcBinaryGetParamAction);
bmc.InverseClickAction += new EventHandler(this.bcApplyButtonImplAction);
bmc.RadioButton1ChangedAction += new EventHandler(this.bcBinaryGetParamAction);
bmc.RadioButton2ChangedAction += new EventHandler(this.bcBinaryGetParamAction);
bmc.ApplyButtonImplAction += new EventHandler(this.bcApplyButtonImplAction);
bmc.BinaryCheckedChangedAction += new EventHandler(this.bcBinaryCheckedChanged);
bmc.OriginCheckedChangedAction += new EventHandler(this.bcOriginCheckedChanged);
bmc.BinaryEditClickAction += new EventHandler(this.bcBinaryEditClickAction);
bmc.PanelColorClickAction += new EventHandler(this.bcPanelColorClickAction);//初始化颜色点击事件
return;
}
if (bc == null)
return;
bc.InitBinaryControlEvent();
bc.BinaryGetParamAction += new EventHandler(this.bcBinaryGetParamAction);
bc.AutoThresClickAction += new EventHandler(this.bcAutoThresClickAction);
bc.InverseClickAction += new EventHandler(this.bcBinaryGetParamAction);
bc.InverseClickAction += new EventHandler(this.bcApplyButtonImplAction);
bc.RadioButton1ChangedAction += new EventHandler(this.bcBinaryGetParamAction);
bc.RadioButton2ChangedAction += new EventHandler(this.bcBinaryGetParamAction);
bc.ApplyButtonImplAction += new EventHandler(this.bcApplyButtonImplAction);
bc.BinaryCheckedChangedAction += new EventHandler(this.bcBinaryCheckedChanged);
bc.OriginCheckedChangedAction += new EventHandler(this.bcOriginCheckedChanged);
bc.BinaryEditClickAction += new EventHandler(this.bcBinaryEditClickAction);
bc.PanelColorClickAction += new EventHandler(this.bcPanelColorClickAction);//初始化颜色点击事件
}
///
/// 相颜色点击事件
///
///
///
private void bcPanelColorClickAction(object sender, EventArgs e)
{
this.colorsForm1.UserPrimaryColor = ColorBgra.FromColor(bmc != null ? bmc.BinaryBackColor : bc.BinaryBackColor);
this.colorsForm1.ShowDialog();
}
///
/// 二值筛选
///
///
///
private void bcBinaryEditClickAction(object sender, EventArgs e)
{
if (this.documentWorkspace.PhaseModels[0].mat == null)
{
MessageBox.Show(PdnResources.GetString("Menu.Pleaseperonfirst.text"));
return;
}
PaintDotNet.DedicatedAnalysis.GrainSizeStandard.IntegrationClass.GrainBinaryBoundaryEditingDialog boundaryEditingDialog = new PaintDotNet.DedicatedAnalysis.GrainSizeStandard.IntegrationClass.GrainBinaryBoundaryEditingDialog(this.appWorkspace, this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index, bmc != null ? bmc.BinaryBackColor : bc.BinaryBackColor
, this.documentWorkspace.PhaseModels[0].mat.Clone(), ShowDrawClassView, this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].GetRuler(MeasurementUnit.Micron));
////1013###19326 晶粒度的晶界编辑页面,需要把辅助线带过去(客户编辑只处理辅助线位置的晶界)
if (this.guideClass != null && this.comboBox1 != null && this.comboBox1.SelectedItem != null)
{
boundaryEditingDialog.GuideClass = this.guideClass;
boundaryEditingDialog.SelectedItem = this.comboBox1.SelectedItem;
}
if (boundaryEditingDialog.ShowDialog() == DialogResult.OK)
{
this.documentWorkspace.PhaseModels[0].mat = boundaryEditingDialog.PhaseMat.Clone();
OnBinaryImplFinishAction();
}
}
///
/// 显示原图勾选改变事件
///
///
///
private void bcOriginCheckedChanged(object sender, EventArgs e)
{
if (bc == null && bmc == null)
return;
int BinaryCheckFlag = 0;
if (bmc != null ? bmc.OriginChecked : bc.OriginChecked)
BinaryCheckFlag += 1;
if (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked)
BinaryCheckFlag += 2;
this.binaryExtractionModel.BinaryCheckFlag = BinaryCheckFlag;
}
///
/// 二值化勾选改变事件
///
///
///
private void bcBinaryCheckedChanged(object sender, EventArgs e)
{
if (bc == null && bmc == null)
return;
int BinaryCheckFlag = 0;
if (bmc != null ? bmc.OriginChecked : bc.OriginChecked)
BinaryCheckFlag += 1;
if (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked)
BinaryCheckFlag += 2;
this.binaryExtractionModel.BinaryCheckFlag = BinaryCheckFlag;
if ((bmc != null ? bmc.BinaryChecked : bc.BinaryChecked) && !(bmc != null ? bmc.OriginChecked : bc.OriginChecked))
{
this.documentWorkspace.PhaseModels[0].choise = true;
}
else
{
this.documentWorkspace.PhaseModels[0].choise = false;
}
if (toApplyBinary)
this.applyButtonImpl();
else
OnBinaryImplFinishAction();
toApplyBinary = true;
if (this.listView1.FocusedItem == null || !(bmc != null ? bmc.BinaryChecked : bc.BinaryChecked))
this.documentWorkspace.Refresh();
}
///
/// 自动阈值
///
///
///
public void bcAutoThresClickAction(object sender, EventArgs e)
{
if (bc == null && bmc == null)
return;
Bitmap bitmap = null;
if (listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0)
bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
if (bitmap != null)
{
//先计算阈值
Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);
Mat gray = mat.CvtColor(ColorConversionCodes.BGR2GRAY);
double otsu = Cv2.Threshold(gray, gray, 0, 255, ThresholdTypes.Triangle/*.Otsu*/);
if (otsu <= 10 || otsu >= 245)
{
otsu = Cv2.Threshold(mat.CvtColor(ColorConversionCodes.BGR2GRAY), gray, 0, 255, ThresholdTypes.Otsu);//.Triangle
}
//如果当前是两个区间,则需要重新计算一次
if (this.ColorInterval == 2)
{
if (bmc != null)
bmc.OnInverseClickAction();
else
bc.OnInverseClickAction();
this.ColorInterval = (bmc != null ? bmc.getInverseStyle() : bc.getInverseStyle());
}
else
{
if (bmc != null)
bmc.setInverseStyle(1);
else
bc.setInverseStyle(1);
}
//给控件赋值
if (bmc != null)
bmc.scope1Start = 0;
else
bc.scope1Start = 0;
if (bmc != null)
bmc.scope1End = otsu;
else
bc.scope1End = otsu;
//处理直方图
if (bmc != null)
bmc.UpdateVerticalBarWithOneScope(0, Convert.ToInt32(bmc.scope1End));
else
bc.UpdateVerticalBarWithOneScope(0, Convert.ToInt32(bc.scope1End));
mat.Dispose();
GC.Collect();
this.bcApplyButtonImplAction(sender, e);
}
else
{
MessageBox.Show(PdnResources.GetString("Menu.Pleaseselectapicturefirst.text"));
}
}
///
/// 执行读取参数的事件
///
///
///
private void bcBinaryGetParamAction(object sender, EventArgs e)
{
if (bc == null && bmc == null)
return;
this.binaryExtractionModel.ColorInterval = (bmc != null ? bmc.getInverseStyle() : bc.getInverseStyle());//###
this.binaryExtractionModel.BinaryStyle = (bmc != null ? bmc.BinaryStyle : bc.BinaryStyle);
this.binaryExtractionModel.ColorOneStart = (int)(bmc != null ? bmc.scope1Start : bc.scope1Start);
this.binaryExtractionModel.ColorOneEnd = (int)(bmc != null ? bmc.scope1End : bc.scope1End);
this.binaryExtractionModel.ColorTwoStart = (int)(bmc != null ? bmc.scope2Start : bc.scope2Start);
this.binaryExtractionModel.ColorTwoEnd = (int)(bmc != null ? bmc.scope2End : bc.scope2End);
this.binaryExtractionModel.ColorThreeStart = (int)(bmc != null ? bmc.scope3Start : bc.scope3Start);
this.binaryExtractionModel.ColorThreeEnd = (int)(bmc != null ? bmc.scope3End : bc.scope3End);
this.initParamsToAction();
}
///
/// 获取相的工作结构
///
/// 指明获取第几个相的工作结构
///
public List getPhaseModels(int index)
{
return this.documentItems[index].phaseModels;
}
///
/// ListView图片选择改变事件
///
/// 选择改变后的图片
public void listView1_SelectedIndexChanged(Bitmap bitmap, string imagesKey = null)
{
Document document = Document.FromImage(bitmap);
this.documentWorkspace.Document = document;
this.documentWorkspace.Visible = true;
this.documentWorkspace.GraphicsList = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].GraphicsList;
this.documentWorkspace.PhaseModels = new List();
this.documentWorkspace.PhaseModels.AddRange(this.getPhaseModels(this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index));
LunkMat = null;
if (imageType != 4)
{
this.applyButtonImpl();
}
if (imagesKey != null && binaryModelFlag.ContainsKey(imagesKey)/*用于更新图片二值化效果*/)
{
this.documentWorkspace.PhaseModels[0].choise = (this.binaryExtractionModel.BinaryCheckFlag == 2);// (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked);
binaryModelFlag[imagesKey] = false;
if (bmc != null)
bmc.BinaryChecked = this.documentWorkspace.PhaseModels[0].choise || (this.binaryExtractionModel.BinaryCheckFlag > 1);
else
bc.BinaryChecked = this.documentWorkspace.PhaseModels[0].choise || (this.binaryExtractionModel.BinaryCheckFlag > 1);
}
else if ((bc != null || bmc != null) && !this.documentWorkspace.PhaseModels[0].choise
&& (this.binaryExtractionModel.BinaryCheckFlag <= 1))
if (bmc != null)
bmc.BinaryChecked = false;
else
bc.BinaryChecked = false;
if (imagesKey != null)
{
if (this.binaryExtractionModel.BinaryCheckFlag % 2 == 1)
{
if (bmc != null)
bmc.OriginChecked = true;
else
bc.OriginChecked = true;
}
else
{
if (bmc != null)
bmc.OriginChecked = false;
else
bc.OriginChecked = false;
}
}
//显示直方图
if (bc != null || bmc != null)
if (bmc != null)
bmc.CreateHistogram(bitmap, true, 339, 130, 0);
else
bc.CreateHistogram(bitmap, true, 339, 130, 0);
this.RefreshHistogramControl1Values();
}
///
/// 构造相的工作结构
///
/// 相的命名,如果只有二值则只传PdnResources.GetString("Menu.BinaryAction.BinaryExtraction.Text")即可,没有特殊情况命名第一个相为PdnResources.GetString("Menu.BinaryAction.BinaryExtraction.Text")
///
///
///
public void createDocumentItemsSmaller(string[] phaseNames, CustomControl.BinaryControlSmaller bmc, AppWorkspace appWorkspace
, DocumentWorkspaceWindow documentWorkspace, ListView listView1)
{
this.bmc = bmc;
this.appWorkspace = appWorkspace;
this.documentWorkspace = documentWorkspace;
this.listView1 = listView1;
this.initParams();
for (int i = 0; i < phaseNames.Length; i++)
{
PhaseModel model = new PhaseModel();
model.choise = true;
model.mat = null;
model.color = (i == 0 && bmc != null) ? bmc.BinaryBackColor.ToArgb() : Color.Green.ToArgb();//###
model.position = documentWorkspace.PhaseModels.Count + 1;
model.name = phaseNames[i];
documentWorkspace.PhaseModels.Add(model);
}
this.documentItems = new Dictionary();
// 构造工作结构
for (int i = 0; i < appWorkspace.DocumentWorkspaces.Length; i++)
{
Bitmap bitmap = appWorkspace.DocumentWorkspaces[i].CompositionSurface.CreateAliasedBitmap();
GraphicsList graphicsList = new GraphicsList();
for (int j = 0; j < appWorkspace.DocumentWorkspaces[i].GraphicsList.Count; j++)
{
graphicsList.Add(appWorkspace.DocumentWorkspaces[i].GraphicsList[j]);
}
List phaseModels = new List();
for (int j = 0; j < phaseNames.Length; j++)
{
//二值化相关
if (j == 0)
{
PhaseModel analysisModel = appWorkspace.DocumentWorkspaces[i].AnalysisPhaseModel;
if (analysisModel == null)
{
PhaseModel model = new PhaseModel();
model.choise = true;
model.mat = null;
model.color = bmc != null ? bmc.BinaryBackColor.ToArgb() : Color.Green.ToArgb();
model.position = phaseModels.Count + 1;
model.name = phaseNames[j];
phaseModels.Add(model);
}
else
phaseModels.Add(analysisModel);
}
else
{
PhaseModel model = new PhaseModel();
model.choise = true;
model.mat = null;
model.color = Color.Green/*panel2.BackColor*/.ToArgb();//###
model.position = phaseModels.Count + 1;
model.name = phaseNames[j];
phaseModels.Add(model);
}
}
this.documentItems.Add(i, new DocumentItem(bitmap, graphicsList, phaseModels));
}
//
//调色板
//
this.colorsForm1 = new ColorsForm();
this.colorsForm1.StartPosition = FormStartPosition.CenterScreen;
this.colorsForm1.setSaveBtn_Click(new System.EventHandler(this.colorsForm1Changed));
this.InitParameterToControl();//###
if (this.binaryExtractionModel != null)
this.applyButtonImpl();
this.InitBinaryControlEvent();
}
///
/// 无视场执行运算
///
public OpenCvSharp.Mat PerformProcess(OpenCvSharp.Mat src) { return action.PerformProcess(src); }
///
/// 无视场执行运算
///
public OpenCvSharp.Mat PerformProcess(OpenCvSharp.Mat src, Base.Functionodel.PhaseModel phaseModel, System.Drawing.Point point) { return action.PerformProcess(src, phaseModel, point); }
///
/// 无视场执行运算
///
public OpenCvSharp.Mat PerformProcessGetdata(OpenCvSharp.Mat src, out List> data) { return action.PerformProcessGetdata(src, out data); }
/// 无视场执行运算
///
public OpenCvSharp.Mat PerformProcessGetdata(OpenCvSharp.Mat src, OpenCvSharp.Mat source, out List> data) { return action.PerformProcessGetdata(src, source, out data); }
///
/// 多视场执行运算
///
/// 视场mat
/// 原图mat
///
public OpenCvSharp.Mat PerformProcess(OpenCvSharp.Mat src, OpenCvSharp.Mat mat) { return action.PerformProcess(src, mat); }
public int ColorInterval
{
get
{
return this.binaryExtractionModel.ColorInterval;
}
set
{
this.binaryExtractionModel.ColorInterval = value;
}
}
private void colorsForm1Changed(object sender, EventArgs e)
{
Color color = this.colorsForm1.UserPrimaryColor.ToColor();
this.SetBinaryBackColor(color);//改变参数配置的相颜色
this.colorsForm1.Close();
}
///
/// 把参数的值设置到控件上
///
public void InitParameterToControl()
{
if (this.binaryExtractionModel != null)
{
if (bc != null || bmc != null)
{
if (this.binaryExtractionModel.BinaryCheckFlag > 1)
{
if (bmc != null)
bmc.BinaryChecked = true;
else
bc.BinaryChecked = true;
}
if (this.binaryExtractionModel.BinaryCheckFlag % 2 == 1)
{
if (bmc != null)
bmc.OriginChecked = true;
else
bc.OriginChecked = true;
}
if (imageType == 2)
{
return;
}
//阈值相关
//1个颜色区间还是2个
if (bmc != null)
bmc.setInverseStyle((this.binaryExtractionModel.ColorInterval == 1) ? 1 : 2);
else
bc.setInverseStyle((this.binaryExtractionModel.ColorInterval == 1) ? 1 : 2);
//删除事件
if (bmc != null)
bmc.DeleteEventHandler();
else
bc.DeleteEventHandler();
if (imageType == 2)
{
return;
}
if (bmc != null)
bmc.scope1End = this.binaryExtractionModel.ColorOneEnd;
else
bc.scope1End = this.binaryExtractionModel.ColorOneEnd;
if (bmc != null)
bmc.scope1Start = this.binaryExtractionModel.ColorOneStart;
else
bc.scope1Start = this.binaryExtractionModel.ColorOneStart;
if (bmc != null)
bmc.scope2End = this.binaryExtractionModel.ColorTwoEnd;
else
bc.scope2End = this.binaryExtractionModel.ColorTwoEnd;
if (bmc != null)
bmc.scope2Start = this.binaryExtractionModel.ColorTwoStart;
else
bc.scope2Start = this.binaryExtractionModel.ColorTwoStart;
if (bmc != null)
bmc.scope3End = this.binaryExtractionModel.ColorThreeEnd;
else
bc.scope3End = this.binaryExtractionModel.ColorThreeEnd;
if (bmc != null)
bmc.scope3Start = this.binaryExtractionModel.ColorThreeStart;
else
bc.scope3Start = this.binaryExtractionModel.ColorThreeStart;
if (bmc != null)
bmc.BinaryStyle = this.binaryExtractionModel.BinaryStyle;
else
bc.BinaryStyle = this.binaryExtractionModel.BinaryStyle;
if (bmc != null)
bmc.BinaryBackColor = Color.FromArgb(this.binaryExtractionModel.PhaseColor);
else
bc.BinaryBackColor = Color.FromArgb(this.binaryExtractionModel.PhaseColor);
//添加事件
if (bmc != null)
bmc.AddEventHandler();
else
bc.AddEventHandler();
if (bmc != null)
bmc.InitParameterToControl();
else
bc.InitParameterToControl();
}
}
}
///
/// 更新显示直方图的数据
///
public void RefreshHistogramControl1Values()
{
////显示直方图
//if (bc != null || bmc != null)
// if (bmc != null)
// bmc.CreateHistogram(bitmap, true, 339, 130, 0);
// else
// bc.CreateHistogram(bitmap, true, 339, 130, 0);
if (bmc != null)
bmc.InitParameterToControl(this.binaryExtractionModel.ColorInterval);
else if (bc != null)
bc.InitParameterToControl(this.binaryExtractionModel.ColorInterval);
}
public void SetBinaryBackColor(Color color)
{
if (bmc != null)
bmc.BinaryBackColor = color;//设置panel背景
else
bc.BinaryBackColor = color;//设置panel背景
this.binaryExtractionModel.PhaseColor = color.ToArgb();
//###
foreach (Args args in action.Lists)
{
if (args.Key == "phaseColor")
{
args.Value = color.ToArgb();//this.binaryExtractionModel.PhaseColor
break;
}
}
this.applyButtonImpl();
}
///
/// 保证二值化颜色赋值到action
///
public void loadParams()
{
if (bc == null && bmc == null)
return;
foreach (Args args in action.Lists)
{
switch (args.Key)
{
case "scope1"://不反选时候的范围
if (bmc != null)
bmc.ScopeValue1ChangedAction += new EventHandler(((DecimalScope)args).numberScope_ValueChanged);
else
bc.ScopeValue1ChangedAction += new EventHandler(((DecimalScope)args).numberScope_ValueChanged);
break;
case "scope2"://反选时候的范围1
if (bmc != null)
bmc.ScopeValue2ChangedAction += new EventHandler(((DecimalScope)args).numberScope_ValueChanged);
else
bc.ScopeValue2ChangedAction += new EventHandler(((DecimalScope)args).numberScope_ValueChanged);
break;
case "scope3"://反选时候的范围2
if (bmc != null)
bmc.ScopeValue3ChangedAction += new EventHandler(((DecimalScope)args).numberScope_ValueChanged);
else
bc.ScopeValue3ChangedAction += new EventHandler(((DecimalScope)args).numberScope_ValueChanged);
break;
case "phaseColor":
args.Value = this.binaryExtractionModel.PhaseColor;
break;
default:
break;
}
}
}
///
/// 执行二值方法的事件
///
///
///
private void bcApplyButtonImplAction(object sender, EventArgs e)
{
this.applyButtonImpl(/*bitmap*/);
}
private bool cornerHarris_demo()
{
string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
string newbitmap = subPath + "\\mask.jpg";
Bitmap bmOld = new Bitmap(newbitmap);
int iwidth = bmOld.Width;
int iHeight = bmOld.Height;
Bitmap newBmp = new Bitmap(bmOld);
Bitmap bitmap1 = newBmp.Clone(new Rectangle(0, 0, iwidth, iHeight), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
bitDJ = bitmap1;
Mat src = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap1);
Mat gray = new Mat();
Cv2.CvtColor(src, gray, ColorConversionCodes.BGRA2GRAY);
using (new Window("ss", WindowMode.Normal, gray))
{
Cv2.WaitKey(0);
}
OpenCvSharp.Point[][] contours;
HierarchyIndex[] hierarchy;
Cv2.FindContours(gray, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
for (int h = 0; h < contours.Length; h++)
{
if (contours[h].Length < 20)
{
continue;
}
Mat src_gray = Mat.Zeros(src.Size(), MatType.CV_8UC1);
src_gray.DrawContours(contours, h, new Scalar(255), -1);
//src_gray.Resize(new OpenCvSharp.Size(src_gray.Width * 3, src_gray.Height * 3));
Mat dst = src_gray.Clone();
using (new Window("s1", WindowMode.Normal, dst))
{
Cv2.WaitKey(0);
}
// Cv2.MedianBlur(src_gray, src_gray, 9);
Point2f[] cornersPoint = Cv2.GoodFeaturesToTrack(src_gray, 100, 0.01, 30, new Mat(), 3, false, 0.04);
foreach (var item in cornersPoint)
{
Cv2.Circle(dst, Convert.ToInt16(item.X), Convert.ToInt16(item.Y), 10, Scalar.White, 2);
}
using (new Window("ss", WindowMode.Normal, dst))
{
Cv2.WaitKey(0);
}
}
return false;
}
/////
///// 参数改变时,重新处理图像
/////
/// 不是当前显示图片的需要传值
/// 不是当前显示图片的需要传值
/// 不带视场处理的需要传值
/// 模块编号:1开裂球,2单晶,3二次球与单晶,4开裂球
public void applyButtonImpl(string imagesKey = null, int analysisPicture = -1, Bitmap bitmap = null)
{
List> data = new List>() { };
Mat newMat = new Mat();
ProgressThreadProcClass procClass = new ProgressThreadProcClass();
int itemCount = 100;
ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
switch (imageType)
{
case 2:
#region 单晶
if (listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0)
{
bool processWholeMat11 = (bitmap != null);
if (bitmap == null)
/*Bitmap */
bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
//cornerHarris_demo();
//判断是否存在视场,如果存在视场,则把视场提取出来,进行处理//可能会带视场//########################
DocumentView documentWorkspace = this.documentWorkspace;
// string name = this.listView1.FocusedItem.Name.Split('.')[0];
string name = "inputImg";
if (analysisPicture == -1)
{
action.Lists.Add(new Args() { Key = "imageType", Value = 12 });
action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
action.Lists.Add(new Args() { Key = "pointsize", Value = pointsize });
action.Lists.Add(new Args() { Key = "borderBottom", Value = borderBottom });
action.Lists.Add(new Args() { Key = "Micron", Value = unitLength });
action.Lists.Add(new Args() { Key = "border", Value = border });
action.Lists.Add(new Args() { Key = "HW", Value = HW });
action.Lists.Add(new Args() { Key = "AreaRatio", Value = AreaRatio });
action.Lists.Add(new Args() { Key = "DelPointFs", Value = null });
action.Lists.Add(new Args() { Key = "AddPontins", Value = null });
action.Lists.Add(new Args() { Key = "Contour", Value = null });
action.Lists.Add(new Args() { Key = "isDis", Value = isDis });
action.Lists.Add(new Args() { Key = "isJu", Value = isJu });
System.Threading.ThreadStart copyThreadProcCrystal =
delegate ()
{
try
{
//检查是否存在文件夹
//string subPath = @"C:\MetisTemp";
string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
if (false == System.IO.Directory.Exists(subPath))
{
//创建pic文件夹
System.IO.Directory.CreateDirectory(subPath);
}
else
{
DirectoryInfo di = new DirectoryInfo(subPath);
FileSystemInfo[] fileinfo = di.GetFileSystemInfos();
try
{
foreach (FileSystemInfo item in fileinfo)
{
//if(item.Name!= "mask.jpg")
item.Delete();
// File.Delete(item.FullName);
}
}
catch (Exception e)
{
}
}
string savepath = subPath + "\\" + name + ".png";
string isCpu = System.Configuration.ConfigurationManager.AppSettings["CpuORGpu"];
bitmap.Save(savepath, System.Drawing.Imaging.ImageFormat.Png);
//1金相/2析出物 0是cpu,1是GPU 尺寸0是自动算
string sArguments = subPath + " " + name + ".png 2 " + isCpu + " 0";
//string sArguments = "-filepath "+subPath + "\\" + name + ".png --useGpu " + isCpu + " --diameter 30,20";
System.Diagnostics.Process p = new System.Diagnostics.Process();
//p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\crystal\\crystal.exe";
p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\educt\\educt.exe";
//p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\granule_engine_3G\\granule_engine.exe";
p.StartInfo.Arguments = sArguments;//python命令的参数
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
string strOutput = null;
p.Start();
strOutput = p.StandardOutput.ReadToEnd();
p.WaitForExit();
p.Close();
string newbitmap = subPath + "\\mask.jpg";
//Bitmap bmOld = new Bitmap(newbitmap);
//int iwidth = bmOld.Width;
//int iHeight = bmOld.Height;
//Bitmap newBmp = new Bitmap(bmOld);
//Bitmap bitmap1 = newBmp.Clone(new Rectangle(0, 0, iwidth, iHeight), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
//bitDJ = (Bitmap)bitmap1.Clone();
// newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap1), out data);
Mat mask = Cv2.ImRead(newbitmap);
newMat = this.PerformProcessGetdata(mask, out data);
if (bmc != null) { bmc.data = data; bmc.isedit = true; }
if (bc != null) { bc.data = data; bc.isedit = true; }
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
documentWorkspace.Refresh();
}
catch (Exception e)
{
}
finally
{
progressEvents.EndOperation(OperationResult.Finished);
}
};
if (string.IsNullOrEmpty(tipString))
{
procClass.StartProgressAction(/*currentForm*/parentSinglCrystal, itemCount, copyThreadProcCrystal, progressEvents, null);
}
else
{
procClass.StartProgressAction(/*currentForm*/parentSinglCrystal, itemCount, copyThreadProcCrystal, progressEvents, tipString);
}
}
}
#endregion
break;
case 4:
#region 开裂球
if (bc == null && bmc == null)
return;
//long start = Cv2.GetTickCount();
if (bitmap != null ||
(listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0) && (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked))
{
bool processWholeMat11 = (bitmap != null);
if (bitmap == null)
/*Bitmap */
bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
action.Lists.Add(new Args() { Key = "imageTypes", Value = 4 });
action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
string name = this.listView1.FocusedItem.Name.Split('.')[0];
System.Threading.ThreadStart copyThreadProc =
delegate ()
{
try
{
#region 人工只能找轮廓
//检查是否存在文件夹
//string subPath = @"C:\MetisTemp";
//string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
//if (false == System.IO.Directory.Exists(subPath))
//{
// //创建pic文件夹
// System.IO.Directory.CreateDirectory(subPath);
//}
//else
//{
// DirectoryInfo di = new DirectoryInfo(subPath);
// FileSystemInfo[] fileinfo = di.GetFileSystemInfos();
// foreach (FileSystemInfo item in fileinfo)
// {
// item.Delete();
// // File.Delete(item.FullName);
// }
//}
//string savepath = subPath + "\\" + name + ".png";
//bitmap.Save(savepath, System.Drawing.Imaging.ImageFormat.Png);
////1金相/2析出物 0是cpu1是GPU 尺寸0是自动算
//string sArguments = subPath + " " + name + ".png 1 0 0";
//System.Diagnostics.Process p = new System.Diagnostics.Process();
////p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\crystal\\crystal.exe";
//p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\educt\\educt.exe";
//p.StartInfo.Arguments = sArguments;//python命令的参数
//p.StartInfo.UseShellExecute = false;
//p.StartInfo.RedirectStandardInput = true;
//p.StartInfo.RedirectStandardOutput = true;
//p.StartInfo.RedirectStandardError = true;
//p.StartInfo.CreateNoWindow = true;
//string strOutput = null;
//p.Start();
//strOutput = p.StandardOutput.ReadToEnd();
//p.WaitForExit();
//p.Close();
//string newbitmap = subPath + "\\mask.jpg";
//Bitmap bmOld = new Bitmap(newbitmap);
//int iwidth = bmOld.Width;
//int iHeight = bmOld.Height;
//Bitmap newBmp = new Bitmap(bmOld);
//Bitmap bitmap1 = newBmp.Clone(new Rectangle(0, 0, iwidth, iHeight), System.Drawing.Imaging.PixelFormat.Format32bppArgb);
//bitDJ = bitmap1;
//Mat pyston = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap1);
#endregion
#region 分水岭找轮廓
newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
PhaseModel model = new PhaseModel();
model.color = -14607873;
model.mat = new OpenCvSharp.Mat();
newMat.CopyTo(model.mat);
newMat = this.PerformProcess(newMat, model, new System.Drawing.Point());
LunkMat = newMat.Clone();
action.Lists.Add(new Args() { Key = "imageTypes", Value = 14 });
data.Clear();
#endregion
newMat = this.PerformProcessGetdata(LunkMat, OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
}
catch (Exception e)
{
}
finally
{
progressEvents.EndOperation(OperationResult.Finished);
}
};
procClass.StartProgressAction(/*currentForm*/parent, itemCount, copyThreadProc, progressEvents, null);
if (bmc != null) { bmc.data = data; bmc.isedit = true; }
if (bc != null) { bc.data = data; bc.isedit = true; }
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
documentWorkspace.Refresh();
}
#endregion
break;
case 3:
#region 二次球与单晶
if (bc == null && bmc == null)
return;
//long start = Cv2.GetTickCount();
if (bitmap != null ||
(listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0) && (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked))
{
bool processWholeMat11 = (bitmap != null);
if (bitmap == null)
/*Bitmap */
bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
action.Lists.Add(new Args() { Key = "CircleCount", Value = 0 });
action.Lists.Add(new Args() { Key = "imageTypes", Value = 3 });
newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
if (bmc != null) { bmc.data = data; bmc.isedit = true; }
if (bc != null) { bc.data = data; bc.isedit = true; }
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
documentWorkspace.Refresh();
}
#endregion
break;
case 1:
#region 截面孔隙
if (bc == null && bmc == null)
return;
//long start = Cv2.GetTickCount();
if (bitmap != null ||
(listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0) && (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked))
{
bool processWholeMat11 = (bitmap != null);
if (bitmap == null)
/*Bitmap */
bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
//判断是否存在视场,如果存在视场,则把视场提取出来,进行处理//可能会带视场//########################
DocumentView documentWorkspace = this.documentWorkspace;
//GetParameter2();
if (analysisPicture == -1)
{
if (LunkMat != null && LunkMat.Rows > 10)
{
}
else
{
Mat maptomat = getimage(bitmap);
LunkMat = maptomat.Clone();
List colorList = new List() { new Scalar(0, 0, 255, 255), new Scalar(0, 255, 0, 255), new Scalar(0, 255, 255, 255), new Scalar(128, 0, 128, 255), new Scalar(230, 216, 173, 255) };
double dist = 0;
double maxdist = 0;
//InputArray contoursAll = InputArray.Create(maxContour);
//List outArr = new List();
//OutputArray hull = OutputArray.Create(outArr);
//Cv2.ConvexHull(contoursAll, hull, true);
//using (new Window("InputImage", WindowMode.Normal, LunkMat))
//{
// Cv2.WaitKey(0);
//}
if (CilCount > 1)
{
for (int i = 0; i < maptomat.Cols; i = i + 50)
{
for (int j = 0; j < maptomat.Rows; j = j + 50)
{
OpenCvSharp.Point point = new OpenCvSharp.Point(i, j);
dist = Cv2.PointPolygonTest(maxContour, point, true);
if (dist > maxdist)
{
maxdist = dist;
center = point;
}
}
}
R = Convert.ToInt32(maxdist);
r = Convert.ToInt32(maxdist) / CilCount;
}
SetCenter = center;
//r = r - 10;
action.Lists.Add(new Args() { Key = "CircleCount", Value = CilCount });
action.Lists.Add(new Args() { Key = "CircleR", Value = r });
action.Lists.Add(new Args() { Key = "Center", Value = center });
action.Lists.Add(new Args() { Key = "imageType", Value = 1 });
action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
action.Lists.Add(new Args() { Key = "DelPointFs", Value = null });
action.Lists.Add(new Args() { Key = "AddPontins", Value = null });
}
newMat = this.PerformProcessGetdata(LunkMat, out data);
List CircleDate = data[0];
CircleDate[CircleDate.Count - 1] = Convert.ToInt32(maxArea);
if (bmc != null) { bmc.data = data; bmc.isedit = true; }
if (bc != null) { bc.data = data; bc.isedit = true; }
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
documentWorkspace.Refresh();
}
}
if (analysisPicture == -1)
OnBinaryImplFinishAction();
#endregion
break;
case 5:
#region 隔膜
if (bc == null && bmc == null)
return;
//long start = Cv2.GetTickCount();
if (bitmap != null ||
(listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0) && (bmc != null ? bmc.BinaryChecked : bc.BinaryChecked))
{
bool processWholeMat11 = (bitmap != null);
if (bitmap == null)
/*Bitmap */
bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
// double d = GetRuler();
//判断是否存在视场,如果存在视场,则把视场提取出来,进行处理//可能会带视场//########################
DocumentView documentWorkspace = this.documentWorkspace;
//GetParameter2();
if (analysisPicture == -1)
{
action.Lists.Add(new Args() { Key = "CircleCount", Value = 0 });
action.Lists.Add(new Args() { Key = "imageType", Value = 5 });
action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
if (bmc != null) { bmc.data = data; bmc.isedit = true; }
if (bc != null) { bc.data = data; bc.isedit = true; }
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
documentWorkspace.Refresh();
}
}
if (analysisPicture == -1)
OnBinaryImplFinishAction();
#endregion
break;
case 6:
#region 前驱截面一次颗粒
if (bc == null && bmc == null)
return;
if (listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0)
{
bool processWholeMat11 = (bitmap != null);
if (bitmap == null)
/*Bitmap */
bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
//判断是否存在视场,如果存在视场,则把视场提取出来,进行处理//可能会带视场//########################
DocumentView documentWorkspace = this.documentWorkspace;
string name = "inputImg";
double d = documentWorkspace.GetRuler(MeasurementUnit.Micron);
if (analysisPicture == -1)
{
action.Lists.Add(new Args() { Key = "imageType", Value = 12 });
action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
action.Lists.Add(new Args() { Key = "pointsize", Value = pointsize });
action.Lists.Add(new Args() { Key = "Micron", Value = d });
action.Lists.Add(new Args() { Key = "border", Value = border });
action.Lists.Add(new Args() { Key = "HW", Value = HW });
action.Lists.Add(new Args() { Key = "AreaRatio", Value = AreaRatio });
action.Lists.Add(new Args() { Key = "DelPointFs", Value = null });
action.Lists.Add(new Args() { Key = "AddPontins", Value = null });
action.Lists.Add(new Args() { Key = "Contour", Value = null });
System.Threading.ThreadStart copyThreadProcCrystal =
delegate ()
{
try
{
//检查是否存在文件夹
//string subPath = @"C:\MetisTemp";
string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
if (false == System.IO.Directory.Exists(subPath))
{
//创建pic文件夹
System.IO.Directory.CreateDirectory(subPath);
}
else
{
DirectoryInfo di = new DirectoryInfo(subPath);
FileSystemInfo[] fileinfo = di.GetFileSystemInfos();
foreach (FileSystemInfo item in fileinfo)
{
item.Delete();
// File.Delete(item.FullName);
}
}
string savepath = subPath + "\\" + name + ".png";
string isCpu = System.Configuration.ConfigurationManager.AppSettings["CpuORGpu"];
bitmap.Save(savepath, System.Drawing.Imaging.ImageFormat.Png);
//1金相/2析出物 0是cpu,1是GPU 尺寸0是自动算
string sArguments = subPath + " " + name + ".png 1 " + isCpu + " 0";
System.Diagnostics.Process p = new System.Diagnostics.Process();
//p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\crystal\\crystal.exe";
p.StartInfo.FileName = System.Environment.CurrentDirectory + "\\educt\\educt.exe";
p.StartInfo.Arguments = sArguments;//python命令的参数
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
string strOutput = null;
p.Start();
strOutput = p.StandardOutput.ReadToEnd();
p.WaitForExit();
p.Close();
string newbitmap = subPath + "\\mask.jpg";
Mat mask = Cv2.ImRead(newbitmap);
newMat = this.PerformProcessGetdata(mask, out data);
if (bmc != null) { bmc.data = data; bmc.isedit = true; }
if (bc != null) { bc.data = data; bc.isedit = true; }
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
documentWorkspace.Refresh();
}
catch (Exception e)
{
}
finally
{
progressEvents.EndOperation(OperationResult.Finished);
}
};
procClass.StartProgressAction(parentPrimary, itemCount, copyThreadProcCrystal, progressEvents, null);
}
}
#endregion
break;
}
}
///
/// 同心圆绘制返回数据
///
///
public List> getCircleDate(int count)
{
if (bmc != null) { bmc.isedit = true; }
if (bc != null) { bc.isedit = true; }
CilCount = count;
List> data = new List>() { };
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
// Mat maptomat = getimage(bitmap);
if (LunkMat != null && LunkMat.Rows > 10)
{
}
else
{
Mat maptomat = getimage(bitmap);
LunkMat = maptomat.Clone();
}
List colorList = new List() { new Scalar(0, 0, 255, 255), new Scalar(0, 255, 0, 255), new Scalar(0, 255, 255, 255), new Scalar(128, 0, 128, 255), new Scalar(230, 216, 173, 255) };
double dist = 0;
double maxdist = 0;
if (SetCenter != null && SetCenter.X > 0)
{
center = SetCenter;
if (count > 0)
r = R / count;
else
r = R;
}
else
{
InputArray contoursAll = InputArray.Create(maxContour);
List outArr = new List();
OutputArray hull = OutputArray.Create(outArr);
Cv2.ConvexHull(contoursAll, hull, true);
for (int i = 0; i < LunkMat.Cols; i = i + 50)
{
for (int j = 0; j < LunkMat.Rows; j = j + 50)
{
OpenCvSharp.Point point = new OpenCvSharp.Point(i, j);
dist = Cv2.PointPolygonTest(outArr.ToArray(), point, true);
if (dist > maxdist)
{
maxdist = dist;
center = point;
}
}
}
R = Convert.ToInt32(maxdist);
if (count > 0)
r = Convert.ToInt32(maxdist) / count;
else
r = R;
}
action.Lists.Add(new Args() { Key = "CircleCount", Value = count });
action.Lists.Add(new Args() { Key = "CircleR", Value = r });
action.Lists.Add(new Args() { Key = "Center", Value = center });
action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
Mat newMat = this.PerformProcessGetdata(LunkMat, out data);
if (data.Count > 0)
{
List CircleDate = data[0];
CircleDate[CircleDate.Count - 1] = Convert.ToInt32(maxArea);
}
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
documentWorkspace.Refresh();
return data;
}
///
/// 手动同心圆绘制返回数据
///
///
public List> getCircleDate(Dictionary ListRadiusColor)
{
if (bmc != null) { bmc.isedit = true; }
if (bc != null) { bc.isedit = true; }
List> data = new List>() { };
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
// Mat maptomat = getimage(bitmap);
if (LunkMat != null && LunkMat.Rows > 10)
{
}
else
{
Mat maptomat = getimage(bitmap);
LunkMat = maptomat.Clone();
}
action.Lists.Add(new Args() { Key = "ListRadiusColor", Value = ListRadiusColor });
action.Lists.Add(new Args() { Key = "Center", Value = center });
action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
Mat newMat = this.PerformProcessGetdata(LunkMat, out data);
if (data.Count > 0)
{
List CircleDate = data[0];
CircleDate[CircleDate.Count - 1] = Convert.ToInt32(maxArea);
}
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
documentWorkspace.Refresh();
return data;
}
///
/// 绘制轮廓
///
///
public List> DrwLunKuo(List> pointFs, List> KongPointFs, List delPointFs)
{
if (this.listView1.Items.Count == 0)
{
return null;
}
lineList = pointFs;
kongLineList = KongPointFs;
delLineList = delPointFs;
List> data = new List>() { };
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
Mat maptomat = getimage(bitmap);
// Mat maptomat = getLineMat(bitmap);
LunkMat = maptomat.Clone();
action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
action.Lists.Add(new Args() { Key = "DelPointFs", Value = delPointFs });
Mat newMat = this.PerformProcessGetdata(maptomat, out data);
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
documentWorkspace.Refresh();
List CircleDate = data[0];
CircleDate[CircleDate.Count - 1] = Convert.ToInt32(maxArea);
return data;
}
///
/// 重新绘制轮廓
///
///
public List> DrwLunKuoNew(List> pointFs, List> KongPointFs, List delPointFs)
{
lineList = pointFs;
kongLineList = KongPointFs;
delLineList = delPointFs;
List> data = new List>() { };
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
Mat maptomat = getLineMat(bitmap);
// Mat maptomat = getLineMat(bitmap);
LunkMat = maptomat.Clone();
action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
action.Lists.Add(new Args() { Key = "DelPointFs", Value = delPointFs });
Mat newMat = this.PerformProcessGetdata(maptomat, out data);
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
documentWorkspace.Refresh();
List CircleDate = data[0];
CircleDate[CircleDate.Count - 1] = Convert.ToInt32(maxArea);
return data;
}
///
/// 选择颗粒
///
///
public void DrwLunKuoSel(int index)
{
List> data = new List>() { };
action.Lists.Add(new Args() { Key = "SelPointFs", Value = index });
Mat newMat = this.PerformProcessGetdata(LunkMat, out data);
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
documentWorkspace.Refresh();
}
///
/// 选择隔膜孔隙
///
///
public void MembranesSel(int index)
{
List> data = new List>() { };
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
action.Lists.Add(new Args() { Key = "SelPointFs", Value = index });
Mat newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.Refresh();
}
///
/// 绘制轮廓单晶
///
///
public List> DrwLunKuoDJ(List> pointFs, List> KongPointFs, List delPointFs)
{
lineList = pointFs;
kongLineList = KongPointFs;
delLineList = delPointFs;
List> data = new List>() { };
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
action.Lists.Add(new Args() { Key = "DelPointFs", Value = delPointFs });
Mat newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
documentWorkspace.Refresh();
return data;
}
///
/// 绘制轮廓二次球均匀性
///
///
public List> DrwLunKuoBallAndCrystal(List options, List KongPointFs, List delPointFs, List> LKPointFs)
{
kailie_ball = KongPointFs;
delLineList = delPointFs;
List> data = new List>() { };
ProgressThreadProcClass procClass = new ProgressThreadProcClass();
int itemCount = 100;
Mat newMat = new Mat();
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
System.Threading.ThreadStart copyThreadProc =
delegate ()
{
try
{
action.Lists.Add(new Args() { Key = "BlurSiaze", Value = options[0] });
action.Lists.Add(new Args() { Key = "param2", Value = options[1] });
action.Lists.Add(new Args() { Key = "minRadius", Value = options[2] });
action.Lists.Add(new Args() { Key = "maxRadius", Value = options[3] });
action.Lists.Add(new Args() { Key = "boundary", Value = options[4] });
action.Lists.Add(new Args() { Key = "BallPointFs", Value = kailie_ball });
action.Lists.Add(new Args() { Key = "CrystalPointFs", Value = delLineList });
action.Lists.Add(new Args() { Key = "CrystalLunkuo", Value = LKPointFs });
newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
}
catch (Exception e)
{
}
finally
{
progressEvents.EndOperation(OperationResult.Finished);
}
};
procClass.StartProgressAction(/*currentForm*/parentCrystal, itemCount, copyThreadProc, progressEvents, null);
if (bmc != null) { bmc.data = data; bmc.isedit = true; }
if (bc != null) { bc.data = data; bc.isedit = true; }
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.PhaseModels[0].color = (bmc != null ? bmc.BinaryBackColor.ToArgb() : bc.BinaryBackColor.ToArgb());
documentWorkspace.Refresh();
return data;
}
///
/// 初始化二值化相关的变量
///
public void initParams()
{
string xmlFilePath = Application.StartupPath + "\\Config\\" + Startup.instance.SettingPrefix + "\\BinaryConfig\\Default_" + this.menuId + ".xml";
bool createNewFile = !System.IO.File.Exists(xmlFilePath);
if (createNewFile)
xmlFilePath = Application.StartupPath + "\\Config\\" + Startup.instance.SettingPrefix + "\\BinaryExtraction\\Default.xml";
this.binaryExtractionModel = XmlSerializeHelper.DESerializer(FileOperationHelper.ReadStringFromFile(xmlFilePath, FileMode.Open));
if (createNewFile)
this.binaryExtractionModel.BinaryCheckFlag = 0;
if (imageType == 2)
{
//binaryExtractionModel.ColorOneEnd = 200;
pointsize = Convert.ToDouble(binaryExtractionModel.ColorOneStart) / 100;
border = binaryExtractionModel.ColorOneEnd / 100;
HW = Convert.ToDouble(binaryExtractionModel.ColorTwoStart) / 100;
AreaRatio = Convert.ToDouble(binaryExtractionModel.ColorTwoEnd) / 100;
CheckState = binaryExtractionModel.ColorThreeStart;
borderBottom = binaryExtractionModel.ColorThreeEnd / 100;
numDecimals = Convert.ToInt32(binaryExtractionModel.DebrisAreaStart);
}
if (imageType == 4)
{
binaryExtractionModel.ColorOneEnd = 200;
}
this.initParamsToAction();
}
///
/// 把参数的值设置到action
///
public void initParamsToAction()
{
foreach (Args args in action.Lists)
{
if (args.Key == "colorInterval")
args.Value = this.binaryExtractionModel.ColorInterval;
else if (args.Key == "binaryStyle")
args.Value = this.binaryExtractionModel.BinaryStyle;
else if (args.Key == "scope1")
{
((List)args.Value)[0] = (int)(this.binaryExtractionModel.ColorOneStart);
((List)args.Value)[1] = (int)(this.binaryExtractionModel.ColorOneEnd);
}
else if (args.Key == "scope2")
{
((List)args.Value)[0] = (int)(this.binaryExtractionModel.ColorTwoStart);
((List)args.Value)[1] = (int)(this.binaryExtractionModel.ColorTwoEnd);
}
else if (args.Key == "scope3")
{
((List)args.Value)[0] = (int)(this.binaryExtractionModel.ColorThreeStart);
((List)args.Value)[1] = (int)(this.binaryExtractionModel.ColorThreeEnd);
}
else if (args.Key == "phaseColor")//#22092
{
args.Value = this.binaryExtractionModel.PhaseColor;
}
}
}
///
/// 保存变量
///
public void saveParams(List paramsList)
{
this.binaryExtractionModel.ColorOneStart = paramsList[0];
this.binaryExtractionModel.ColorOneEnd = paramsList[1];
this.binaryExtractionModel.ColorTwoStart = paramsList[2];
this.binaryExtractionModel.ColorTwoEnd = paramsList[3];
this.binaryExtractionModel.ColorThreeEnd = paramsList[4];
this.binaryExtractionModel.ColorThreeStart = paramsList[6];
this.binaryExtractionModel.DebrisAreaStart = paramsList[5];
string xmlFilePath = Application.StartupPath + "\\Config\\" + Startup.instance.SettingPrefix + "\\BinaryConfig\\Default_" + this.menuId + ".xml";
string userInfoXml = XmlSerializeHelper.XmlSerialize(this.binaryExtractionModel);
FileOperationHelper.WriteStringToFile(userInfoXml, xmlFilePath, System.IO.FileMode.Create);
}
///
/// 保存二值化相关的变量
///
public void saveParams()
{
string xmlFilePath = Application.StartupPath + "\\Config\\" + Startup.instance.SettingPrefix + "\\BinaryConfig\\Default_" + this.menuId + ".xml";
string userInfoXml = XmlSerializeHelper.XmlSerialize(this.binaryExtractionModel);
FileOperationHelper.WriteStringToFile(userInfoXml, xmlFilePath, System.IO.FileMode.Create);
}
#region 内部类
internal class LocalListViewItem
{
public DocumentWorkspace Value { get; }
public string Display { get; }
public LocalListViewItem(DocumentWorkspace Value, string Display)
{
this.Value = Value;
this.Display = Display;
}
}
internal class DocumentItem
{
public Bitmap bitmap;
public GraphicsList graphicsList;
public List phaseModels;
public DocumentItem(Bitmap bitmap, GraphicsList graphicsList, List phaseModels)
{
this.bitmap = bitmap;
this.graphicsList = graphicsList;
this.phaseModels = phaseModels;
}
}
#endregion
#region 前驱截面
private Mat getLineMat(Bitmap img)
{
Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(img);
double dist = 0;
double maxdist = 0;
List pointList = lineList[0];
List> list = new List>();
List point = new List();
if (kongLineList.Count > 0)
{
List> Allkonglist = new List>() { };
for (int i = 0; i < kongLineList.Count; i++)
{
List konglist = new List();
for (int j = 0; j < kongLineList[i].Count; j++)
{
OpenCvSharp.Point po = new OpenCvSharp.Point() { X = (int)kongLineList[i][j].X, Y = (int)kongLineList[i][j].Y };
konglist.Add(po);
}
Allkonglist.Add(konglist);
}
for (int kong = 0; kong < kongLineList.Count; kong++)
{
Cv2.DrawContours(mat, Allkonglist, kong, new Scalar(0, 0, 0, 255), Cv2.FILLED);
}
}
for (int i = 0; i < pointList.Count(); i++)
{
point.Add(new OpenCvSharp.Point() { X = (int)pointList[i].X, Y = (int)pointList[i].Y });
}
list.Add(point);
Mat mask = Mat.Zeros(mat.Size(), MatType.CV_8UC1);
Cv2.DrawContours(mask, list, 0, new Scalar(255, 255, 255, 255), -1);
maxContour = point.ToArray();
InputArray contoursAll = InputArray.Create(maxContour);
List outArr = new List();
OutputArray hull = OutputArray.Create(outArr);
maxArea = Cv2.ContourArea(maxContour);
Cv2.ConvexHull(contoursAll, hull, true);
if (SetCenter != null && SetCenter.X > 0&& CilCount>0)
{
center = SetCenter;
r = R / CilCount;
}
else
{
for (int i = 0; i < mat.Cols; i = i + 50)
{
for (int j = 0; j < mat.Rows; j = j + 50)
{
OpenCvSharp.Point point1 = new OpenCvSharp.Point(i, j);
dist = Cv2.PointPolygonTest(outArr, point1, true);
if (dist > maxdist)
{
maxdist = dist;
center = point1;
}
}
}
R = Convert.ToInt32(maxdist);
r = Convert.ToInt32(maxdist);
}
// r = r - 10;
action.Lists.Add(new Args() { Key = "maxContour", Value = maxContour });
action.Lists.Add(new Args() { Key = "CircleCount", Value = CilCount });
action.Lists.Add(new Args() { Key = "CircleR", Value = r });
action.Lists.Add(new Args() { Key = "Center", Value = center });
action.Lists.Add(new Args() { Key = "imageType", Value = 1 });
action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
Mat dst = new Mat();
mat.CopyTo(dst, mask);
return dst;
}
private Mat getimage(Bitmap img)
{
Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(img);
Mat g_grayImage = new Mat();
Mat g_dstImage = new Mat();
Mat g_bwImage = new Mat();
Mat mask = Mat.Zeros(mat.Size(), MatType.CV_8UC1);
Mat dst = new Mat();
if (lineList.Count > 0)
{
for (int line = 0; line < lineList.Count; line++)
{
List pointList = lineList[line];
for (int i = 0; i < pointList.Count - 1; i++)
{
Cv2.Line(mat, new OpenCvSharp.Point() { X = (int)pointList[i].X, Y = (int)pointList[i].Y }, new OpenCvSharp.Point() { X = (int)pointList[i + 1].X, Y = (int)pointList[i + 1].Y }, new Scalar(0, 0, 0), 20);
}
}
}
if (kongLineList.Count > 0)
{
List> Allkonglist = new List>() { };
for (int i = 0; i < kongLineList.Count; i++)
{
List konglist = new List();
for (int j = 0; j < kongLineList[i].Count; j++)
{
OpenCvSharp.Point point = new OpenCvSharp.Point() { X = (int)kongLineList[i][j].X, Y = (int)kongLineList[i][j].Y };
konglist.Add(point);
}
Allkonglist.Add(konglist);
}
for (int kong = 0; kong < kongLineList.Count; kong++)
{
Cv2.DrawContours(mat, Allkonglist, kong, new Scalar(0, 0, 0, 255), Cv2.FILLED);
}
}
//灰度图
Cv2.CvtColor(mat, g_grayImage, ColorConversionCodes.BGR2GRAY);
Cv2.Erode(g_grayImage, g_grayImage, null);
Cv2.Erode(g_grayImage, g_grayImage, null);
//算子
InputArray kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5), new OpenCvSharp.Point(2, 2));
//闭操作
Cv2.MorphologyEx(g_grayImage, g_dstImage, MorphTypes.Close, kernel, new OpenCvSharp.Point(-1, -1));
//平均阈值
Scalar scalar = Cv2.Mean(g_dstImage);
double val = scalar.Val0 + 11;
//图像二值化
Cv2.Threshold(g_dstImage, g_bwImage, val, 255, ThresholdTypes.Binary);
OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
//轮廓
Cv2.FindContours(g_bwImage, out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxNone);
Mat view = mask.Clone();
int maxcontourIdx = 0;
maxArea = 0;
for (int i = 0; i < contours.Length; i++)
{
double area = Cv2.ContourArea(contours[i]);
if (area > maxArea)
{
maxArea = area;
maxContour = contours[i];
maxcontourIdx = i;
}
//Cv2.DrawContours(view, contours, i, new Scalar(255, 255, 255, 255), -1);
}
//Mat matret = new Mat(mat.Rows, mat.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
//Cv2.DrawContours(matret, contours, maxcontourIdx, new Scalar(255, 0, 255, 255), 2);
InputArray contoursAll = InputArray.Create(contours[maxcontourIdx]);
List outArr = new List();
List hullpoint = new List();
OutputArray hull = OutputArray.Create(outArr);
Cv2.ConvexHull(contoursAll, hull, true);
Cv2.DrawContours(mask, new List> { outArr }, 0, new Scalar(255, 255, 255, 255), -1);
action.Lists.Add(new Args() { Key = "maxContour", Value = outArr.ToArray() });
maxContour = outArr.ToArray();
//using (new Window("ss",WindowMode.Normal, view))
//{
// Cv2.WaitKey(0);
//}
maxArea = Cv2.ContourArea(outArr);
mat.CopyTo(dst, mask);
//List ret = expand_polygon(maxContour);
//Cv2.DrawContours(dst, new List> { ret }, 0, new Scalar(255, 255, 255, 255), -1);
//Cv2.ImShow("ss", dst);
return dst;
}
private List expand_polygon(OpenCvSharp.Point[] pList)
{
List points = new List() { };
List dpList = new List() { }, ndpList = new List() { };
int count = pList.Count();
for (int i = 0; i < count; i++)
{
int next = (i == (count - 1) ? 0 : (i + 1));
dpList.Add(pList[next] - pList[i]);
double unitLen = 1.0 / Math.Sqrt(dpList[i].DotProduct(dpList[i]));
ndpList.Add(dpList[i] * unitLen);
}
// 3. compute Line
float SAFELINE = -1.3f;//负数为内缩, 正数为外扩。 需要注意算法本身并没有检测内缩多少后折线会自相交,那不是本代码的示范意图
for (int i = 0; i < count; i++)
{
int startIndex = (i == 0 ? (count - 1) : (i - 1));
int endIndex = i;
float sinTheta = (float)ndpList[startIndex].CrossProduct(ndpList[endIndex]);
Point2f orientVector = ndpList[endIndex] - ndpList[startIndex];//i.e. PV2-V1P=PV2+PV1
OpenCvSharp.Point temp_out;
temp_out.X = Convert.ToInt32(pList[i].X + SAFELINE / sinTheta * orientVector.X);
temp_out.Y = Convert.ToInt32(pList[i].Y + SAFELINE / sinTheta * orientVector.Y);
points.Add(temp_out);
}
return points;
}
///
/// 自动阈值
///
///
///
public void bcDefault()
{
if (bc == null && bmc == null)
return;
Bitmap bitmap = null;
if (listView1.FocusedItem != null || this.listView1.SelectedItems != null && this.listView1.SelectedItems.Count > 0)
bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
if (bitmap != null)
{
//先计算阈值
Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);
Mat gray = mat.CvtColor(ColorConversionCodes.BGR2GRAY);
double otsu = Cv2.Threshold(gray, gray, 0, 255, ThresholdTypes.Triangle/*.Otsu*/);
if (otsu <= 10 || otsu >= 245)
{
otsu = Cv2.Threshold(mat.CvtColor(ColorConversionCodes.BGR2GRAY), gray, 0, 255, ThresholdTypes.Otsu);//.Triangle
}
//如果当前是两个区间,则需要重新计算一次
if (this.ColorInterval == 2)
{
if (bmc != null)
bmc.OnInverseClickAction();
else
bc.OnInverseClickAction();
this.ColorInterval = (bmc != null ? bmc.getInverseStyle() : bc.getInverseStyle());
}
else
{
if (bmc != null)
bmc.setInverseStyle(1);
else
bc.setInverseStyle(1);
}
// Scalar scalar = Cv2.Mean(mat);
int val = 0;
switch (imageType)
{
case 2:
val = GetDefultValueForCrystal(mat);
//给控件赋值
if (bmc != null)
bmc.scope1Start = val;
else
bc.scope1Start = val;
if (bmc != null)
bmc.scope1End = 200;
else
bc.scope1End = 200;
break;
case 3:
val = GetDefultValueForCrystal(mat);
//给控件赋值
if (bmc != null)
bmc.scope1Start = val;
else
bc.scope1Start = val;
if (bmc != null)
bmc.scope1End = 245;
else
bc.scope1End = 245;
break;
case 4:
val = GetDefultValueForBall(mat);
//给控件赋值
if ((bmc != null && bmc.scope1Start == val) || (bc != null && bc.scope1Start == val))
{
val = val + 1;
}
if (bmc != null)
bmc.scope1Start = val;
else
bc.scope1Start = val;
if (bmc != null)
bmc.scope1End = 200;
else
bc.scope1End = 200;
break;
case 1:
val = GetDefultValue(mat);
//给控件赋值
if (bmc != null)
bmc.scope1Start = 0;
else
bc.scope1Start = 0;
if (bmc != null)
bmc.scope1End = val;
else
bc.scope1End = val;
break;
case 5:
val = GetDefultValue(mat);
//给控件赋值
if (bmc != null)
bmc.scope1Start = 0;
else
bc.scope1Start = 0;
if (bmc != null)
bmc.scope1End = val;
else
bc.scope1End = val;
break;
}
//处理直方图
if (bmc != null)
bmc.UpdateVerticalBarWithOneScope(Convert.ToInt32(bmc.scope1Start), Convert.ToInt32(bmc.scope1End));
else
bc.UpdateVerticalBarWithOneScope(Convert.ToInt32(bmc.scope1Start), Convert.ToInt32(bc.scope1End));
mat.Dispose();
GC.Collect();
}
else
{
MessageBox.Show(PdnResources.GetString("Menu.Pleaseselectapicturefirst.text"));
}
}
///
/// 计算截面孔隙初始值
///
///
private int GetDefultValue(Mat mat)
{
//配置输出的结果存储的 空间 ,用MatND类型来存储结果
Mat hist = new Mat();
Mat Gaos = new Mat();
Cv2.GaussianBlur(mat, Gaos, new OpenCvSharp.Size(7, 7), 0);
//设置计算直方图的维度
int dims = 1;
//直方图的每一个维度的柱条的数目(就是将数值分组,共有多少组)
int[] histSize = { 255 };
Rangef[] pranges = new Rangef[1];//一个通道,范围
pranges[0].Start = 0.0F;//从0开始(含)
pranges[0].End = 256.0F;//到256结束(不含)
//6--计算直方图
Cv2.CalcHist(new Mat[1] { mat }, new int[] { 0 }, new Mat(), hist, dims, histSize, pranges);
int nHistSize = 256;
float maxY = 0;
int maxX = 0;
List vs = new List() { };
List list = new List() { };
for (int i = 1; i < nHistSize - 1; i++)
{
float y = hist.At(i);
list.Add(y);
}
//maxX= GetHist(mat.Clone());
double[] dd = cubicSmooth7(list.ToArray(), list.Count());
int len = Convert.ToInt32(dd.Max()).ToString().Length;
int xline = 1;
for (int i = 0; i < len - 2; i++)
{
xline = xline * 10;
}
List maxList = new List() { };
for (int i = 3; i < list.Count() - 1; i++)
{
double Y2 = dd[i];
double Y1 = dd[i - 3];
double angleOfLine = Math.Atan2((Y2 - Y1), 3 * xline) * 180 / Math.PI;
maxList.Add(angleOfLine);
}
for (int i = maxList.Count() - 5; i > 10; i--)
{
double t1 = maxList[i];
double t2 = maxList[i + 1];
if (t1 - t2 < 0)
{
maxX = i;
break;
}
}
maxX = getMax(maxList, maxList.Count() - 15);
for (int i = maxX - 10; i > 10; i--)
{
double def = 0;
for (int j = i; j < i + 5; j++)
{
def = def + (dd[j + 1] - dd[j]);
}
}
//通过斜率计算坡底
List angle = new List() { };
for (int i = maxX - 10; i > 10; i--)
{
double Y2 = dd[i];
double Y1 = dd[i - 3];
double angleOfLine = Math.Atan2((Y2 - Y1), 3 * xline) * 180 / Math.PI;
angle.Add(angleOfLine);
}
int N = 0;
for (int i = 10; i < angle.Count() - 1; i++)
{
double t1 = angle[i];
double t2 = angle[i + 1];
if (t1 < 10 && t1 - t2 < 0.1)
{
N = i;
break;
}
}
//原点
PointF p0 = new PointF(0, 0);
//波峰顶点
PointF p1 = new PointF(maxX, Convert.ToInt32(dd[maxX]));
int pn = 0;
double maxD = 0;
//通过最远距离计算坡底
for (int i = maxX / 2; i < maxX; i++)
{
PointF p = new PointF(i, Convert.ToInt32(dd[i]));
double d = GetMinDistance(p0, p1, p);
if (maxD < d)
{
maxD = d;
pn = i;
}
}
return pn;
}
///
/// 计算隔膜孔隙初始值
///
///
private int GetDefultValueForMem(Mat mat)
{
//配置输出的结果存储的 空间 ,用MatND类型来存储结果
Mat hist = new Mat();
Mat Gaos = new Mat();
Cv2.GaussianBlur(mat, Gaos, new OpenCvSharp.Size(7, 7), 0);
//设置计算直方图的维度
int dims = 1;
//直方图的每一个维度的柱条的数目(就是将数值分组,共有多少组)
int[] histSize = { 255 };
Rangef[] pranges = new Rangef[1];//一个通道,范围
pranges[0].Start = 0.0F;//从0开始(含)
pranges[0].End = 256.0F;//到256结束(不含)
//6--计算直方图
Cv2.CalcHist(new Mat[1] { mat }, new int[] { 0 }, new Mat(), hist, dims, histSize, pranges);
int nHistSize = 256;
float maxY = 0;
int maxX = 0;
List vs = new List() { };
List list = new List() { };
for (int i = 1; i < nHistSize - 1; i++)
{
float y = hist.At(i);
list.Add(y);
if (y > maxY)
{
maxY = y;
maxX = i;
}
}
return maxX;
}
private int getMax(List maxList, int init)
{
int ret = init;
for (int i = init; i > 10; i--)
{
int pre = 0;
int after = 0;
for (int t = i; t < i + 10; t++)
{
if (maxList[t] < 0)
{
pre++;
}
}
for (int t = i; t > i - 10; t--)
{
if (maxList[t] > 0)
{
after++;
}
}
if (pre > 8 && after > 8)
{
ret = i;
break;
}
//double t1 = maxList[i];
//double t2 = maxList[i + 1];
//if (t1>=10&&t2>=10&&t1-t2>0)
//{
// ret = i;
// break;
//}
}
return ret;
}
///
/// 计算单晶初始值
///
///
private int GetDefultValueForCrystal(Mat mat)
{
//配置输出的结果存储的 空间 ,用MatND类型来存储结果
Mat hist = new Mat();
Mat Gaos = new Mat();
//Cv2.GaussianBlur(mat, Gaos, new OpenCvSharp.Size(7, 7), 0);
//设置计算直方图的维度
int dims = 1;
//直方图的每一个维度的柱条的数目(就是将数值分组,共有多少组)
int[] histSize = { 255 };
Rangef[] pranges = new Rangef[1];//一个通道,范围
pranges[0].Start = 0.0F;//从0开始(含)
pranges[0].End = 256.0F;//到256结束(不含)
//6--计算直方图
Cv2.CalcHist(new Mat[1] { mat }, new int[] { 0 }, new Mat(), hist, dims, histSize, pranges);
int nHistSize = 256;
float maxY = 0;
int maxX = 0;
List vs = new List() { };
List list = new List() { };
for (int i = 1; i < nHistSize - 1; i++)
{
float y = hist.At(i);
list.Add(y);
}
//maxX= GetHist(mat.Clone());
double[] dd = cubicSmooth7(list.ToArray(), list.Count());
List maxList = new List() { };
for (int i = 3; i < list.Count() - 1; i++)
{
double Y2 = dd[i];
double Y1 = dd[i - 3];
double angleOfLine = Math.Atan2((Y2 - Y1), 30000) * 180 / Math.PI;
maxList.Add(angleOfLine);
}
for (int i = maxList.Count() - 5; i > 10; i--)
{
double t1 = maxList[i];
double t2 = maxList[i + 1];
if (t1 - t2 < 0)
{
maxX = i;
break;
}
}
int max2 = list.FindIndex(s => s == list.Max());
//波峰
maxX = getMax(maxList, maxList.Count() - 15);
//原点
PointF p0 = new PointF(255, 0);
//波峰顶点
PointF p1 = new PointF(max2, Convert.ToInt32(dd[max2]));
int pn = 0;
double maxD = 0;
if (imageType == 2)
{
//通过最远距离计算坡底
for (int i = max2; i < maxX; i++)
{
PointF p = new PointF(i, Convert.ToInt32(dd[i]));
double d = GetMinDistance(p0, p1, p);
if (maxD < d)
{
maxD = d;
pn = i;
}
}
return pn;
//return pn + (maxX - pn) / 2;
}
else
{
//通过最远距离计算坡底
for (int i = max2; i < 200; i++)
{
PointF p = new PointF(i, Convert.ToInt32(dd[i]));
double d = GetMinDistance(p0, p1, p);
if (maxD < d)
{
maxD = d;
pn = i;
}
}
return pn;
}
////原点
//PointF p0 = new PointF(255, 0);
////波峰顶点
//PointF p1 = new PointF(maxX, Convert.ToInt32(dd[maxX]));
//int pn = 0;
//double maxD = 0;
////通过最远距离计算坡底
//for (int i = maxX; i < 245; i++)
//{
// PointF p = new PointF(i, Convert.ToInt32(dd[i]));
// double d = GetMinDistance(p0, p1, p);
// if (maxD < d)
// {
// maxD = d;
// pn = i;
// }
//}
//return pn;
// return maxX + N;
}
///
/// 计算开裂球初始值
///
///
private int GetDefultValueForBall(Mat mat)
{
//配置输出的结果存储的 空间 ,用MatND类型来存储结果
Mat hist = new Mat();
int dims = 1;
//直方图的每一个维度的柱条的数目(就是将数值分组,共有多少组)
int[] histSize = { 255 };
Rangef[] pranges = new Rangef[1];//一个通道,范围
pranges[0].Start = 0.0F;//从0开始(含)
pranges[0].End = 256.0F;//到256结束(不含)
//6--计算直方图
Cv2.CalcHist(new Mat[1] { mat }, new int[] { 0 }, new Mat(), hist, dims, histSize, pranges);
int nHistSize = 256;
float maxY = 0;
int maxX = 0;
List vs = new List() { };
List list = new List() { };
for (int i = 1; i < nHistSize - 1; i++)
{
float y = hist.At(i);
list.Add(y);
}
//maxX= GetHist(mat.Clone());
double[] dd = cubicSmooth7(list.ToArray(), list.Count());
List maxList = new List() { };
for (int i = 3; i < list.Count() - 1; i++)
{
double Y2 = dd[i];
double Y1 = dd[i - 3];
double angleOfLine = Math.Atan2((Y2 - Y1), 30000) * 180 / Math.PI;
maxList.Add(angleOfLine);
}
for (int i = maxList.Count() - 5; i > 10; i--)
{
double t1 = maxList[i];
double t2 = maxList[i + 1];
if (t1 - t2 < 0)
{
maxX = i;
break;
}
}
int max2 = list.FindIndex(s => s == list.Max());
//波峰
maxX = getMax(maxList, maxList.Count() - 15);
if (maxX > max2)
{
PointF p0 = new PointF(max2, Convert.ToInt32(dd[max2]));
//波峰顶点
PointF p1 = new PointF(maxX, Convert.ToInt32(dd[maxX]));
int pn = 0;
double maxD = 0;
//通过最远距离计算坡底
for (int i = max2; i < maxX; i++)
{
PointF p = new PointF(i, Convert.ToInt32(dd[i]));
double d = GetMinDistance(p0, p1, p);
if (maxD < d)
{
maxD = d;
pn = i;
}
}
return pn + (maxX - pn) / 2;
}
else
{
return maxX - 10;
}
}
/****点到直线的距离***
* 过点(x1,y1)和点(x2,y2)的直线方程为:KX -Y + (x2y1 - x1y2)/(x2-x1) = 0
* 设直线斜率为K = (y2-y1)/(x2-x1),C=(x2y1 - x1y2)/(x2-x1)
* 点P(x0,y0)到直线AX + BY +C =0DE 距离为:d=|Ax0 + By0 + C|/sqrt(A*A + B*B)
* 点(x3,y3)到经过点(x1,y1)和点(x2,y2)的直线的最短距离为:
* distance = |K*x3 - y3 + C|/sqrt(K*K + 1)
*/
public static double GetMinDistance(PointF pt1, PointF pt2, PointF pt3)
{
double dis = 0;
if (pt1.X == pt2.X)
{
dis = Math.Abs(pt3.X - pt1.X);
return dis;
}
double lineK = (pt2.Y - pt1.Y) / (pt2.X - pt1.X);
double lineC = (pt2.X * pt1.Y - pt1.X * pt2.Y) / (pt2.X - pt1.X);
dis = Math.Abs(lineK * pt3.X - pt3.Y + lineC) / (Math.Sqrt(lineK * lineK + 1));
return dis;
}
///
/// 数据平滑
///
///
///
///
private double[] quadraticSmooth5(double[] in1, int N)
{
double[] out1 = new double[in1.Length];
int i;
if (N < 5)
{
for (i = 0; i <= N - 1; i++)
{
out1[i] = in1[i];
}
}
else
{
out1[0] = (31.0 * in1[0] + 9.0 * in1[1] - 3.0 * in1[2] - 5.0 * in1[3] + 3.0 * in1[4]) / 35.0;
out1[1] = (9.0 * in1[0] + 13.0 * in1[1] + 12 * in1[2] + 6.0 * in1[3] - 5.0 * in1[4]) / 35.0;
for (i = 2; i <= N - 3; i++)
{
out1[i] = (-3.0 * (in1[i - 2] + in1[i + 2]) +
12.0 * (in1[i - 1] + in1[i + 1]) + 17 * in1[i]) / 35.0;
}
out1[N - 2] = (9.0 * in1[N - 1] + 13.0 * in1[N - 2] + 12.0 * in1[N - 3] + 6.0 * in1[N - 4] - 5.0 * in1[N - 5]) / 35.0;
out1[N - 1] = (31.0 * in1[N - 1] + 9.0 * in1[N - 2] - 3.0 * in1[N - 3] - 5.0 * in1[N - 4] + 3.0 * in1[N - 5]) / 35.0;
}
return out1;
}
public double[] cubicSmooth7(double[] in1, int N)
{
double[] out1 = new double[in1.Length];
int i;
if (N < 7)
{
for (i = 0; i <= N - 1; i++)
{
out1[i] = in1[i];
}
}
else
{
out1[0] = (39.0 * in1[0] + 8.0 * in1[1] - 4.0 * in1[2] - 4.0 * in1[3] +
1.0 * in1[4] + 4.0 * in1[5] - 2.0 * in1[6]) / 42.0;
out1[1] = (8.0 * in1[0] + 19.0 * in1[1] + 16.0 * in1[2] + 6.0 * in1[3] -
4.0 * in1[4] - 7.0 * in1[5] + 4.0 * in1[6]) / 42.0;
out1[2] = (-4.0 * in1[0] + 16.0 * in1[1] + 19.0 * in1[2] + 12.0 * in1[3] +
2.0 * in1[4] - 4.0 * in1[5] + 1.0 * in1[6]) / 42.0;
for (i = 3; i <= N - 4; i++)
{
out1[i] = (-2.0 * (in1[i - 3] + in1[i + 3]) +
3.0 * (in1[i - 2] + in1[i + 2]) +
6.0 * (in1[i - 1] + in1[i + 1]) + 7.0 * in1[i]) / 21.0;
}
out1[N - 3] = (-4.0 * in1[N - 1] + 16.0 * in1[N - 2] + 19.0 * in1[N - 3] +
12.0 * in1[N - 4] + 2.0 * in1[N - 5] - 4.0 * in1[N - 6] + 1.0 * in1[N - 7]) / 42.0;
out1[N - 2] = (8.0 * in1[N - 1] + 19.0 * in1[N - 2] + 16.0 * in1[N - 3] +
6.0 * in1[N - 4] - 4.0 * in1[N - 5] - 7.0 * in1[N - 6] + 4.0 * in1[N - 7]) / 42.0;
out1[N - 1] = (39.0 * in1[N - 1] + 8.0 * in1[N - 2] - 4.0 * in1[N - 3] -
4.0 * in1[N - 4] + 1.0 * in1[N - 5] + 4.0 * in1[N - 6] - 2.0 * in1[N - 7]) / 42.0;
}
return out1;
}
public double[] quadraticSmooth7(double[] in1, int N)
{
double[] out1 = new double[in1.Length];
int i;
if (N < 7)
{
for (i = 0; i <= N - 1; i++)
{
out1[i] = in1[i];
}
}
else
{
out1[0] = (32.0 * in1[0] + 15.0 * in1[1] + 3.0 * in1[2] - 4.0 * in1[3] -
6.0 * in1[4] - 3.0 * in1[5] + 5.0 * in1[6]) / 42.0;
out1[1] = (5.0 * in1[0] + 4.0 * in1[1] + 3.0 * in1[2] + 2.0 * in1[3] +
in1[4] - in1[6]) / 14.0;
out1[2] = (1.0 * in1[0] + 3.0 * in1[1] + 4.0 * in1[2] + 4.0 * in1[3] +
3.0 * in1[4] + 1.0 * in1[5] - 2.0 * in1[6]) / 14.0;
for (i = 3; i <= N - 4; i++)
{
out1[i] = (-2.0 * (in1[i - 3] + in1[i + 3]) +
3.0 * (in1[i - 2] + in1[i + 2]) +
6.0 * (in1[i - 1] + in1[i + 1]) + 7.0 * in1[i]) / 21.0;
}
out1[N - 3] = (1.0 * in1[N - 1] + 3.0 * in1[N - 2] + 4.0 * in1[N - 3] +
4.0 * in1[N - 4] + 3.0 * in1[N - 5] + 1.0 * in1[N - 6] - 2.0 * in1[N - 7]) / 14.0;
out1[N - 2] = (5.0 * in1[N - 1] + 4.0 * in1[N - 2] + 3.0 * in1[N - 3] +
2.0 * in1[N - 4] + in1[N - 5] - in1[N - 7]) / 14.0;
out1[N - 1] = (32.0 * in1[N - 1] + 15.0 * in1[N - 2] + 3.0 * in1[N - 3] -
4.0 * in1[N - 4] - 6.0 * in1[N - 5] - 3.0 * in1[N - 6] + 5.0 * in1[N - 7]) / 42.0;
}
return out1;
}
///
/// 获取直方图
///
///
private int GetHist(Mat srcImage)
{
Mat hist = new Mat();
Mat Gaos = new Mat();
Cv2.GaussianBlur(srcImage, Gaos, new OpenCvSharp.Size(7, 7), 0);
//设置计算直方图的维度
int dims = 1;
//直方图的每一个维度的柱条的数目(就是将数值分组,共有多少组)
int[] histSize = { 255 };
Rangef[] pranges = new Rangef[1];//一个通道,范围
pranges[0].Start = 0.0F;//从0开始(含)
pranges[0].End = 256.0F;//到256结束(不含)
//6--计算直方图
Cv2.CalcHist(new Mat[1] { Gaos }, new int[] { 0 }, new Mat(), hist, dims, histSize, pranges);
Mat drawImage = Mat.Zeros(new OpenCvSharp.Size(256, 256), MatType.CV_8UC3);
double min = 0;
double max = 0;
Cv2.MinMaxLoc(hist, out min, out max);
for (int i = 0; i < 256; i++)
{
int value = Convert.ToInt32(Math.Round(hist.At(i) * 256 * 0.9 / max, MidpointRounding.AwayFromZero));
Cv2.Line(drawImage, new OpenCvSharp.Point(i, drawImage.Rows - 1), new OpenCvSharp.Point(i, drawImage.Rows - 1 - value), new Scalar(255, 0, 0));
}
//灰度图
Cv2.CvtColor(drawImage, drawImage, ColorConversionCodes.BGR2GRAY);
Mat g_bwImage = new Mat();
//图像二值化
Cv2.Threshold(drawImage, g_bwImage, 0, 255, ThresholdTypes.Binary);
OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
//轮廓
Cv2.FindContours(g_bwImage, out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxNone);
InputArray contoursAll = InputArray.Create(contours[0]);
List outArr = new List();
OutputArray hull = OutputArray.Create(outArr);
Cv2.ConvexHull(contoursAll, hull, true);
int retint = 0;
for (int i = 0; i < outArr.Count; i++)
{
if (outArr[i].X > 230)
{
continue;
}
else if (outArr[i].X < 20)
{
continue;
}
else if (retint < outArr[i].X)
{
retint = outArr[i].X;
}
}
// Cv2.ImShow("【直方图】", drawImage);
return retint;
}
///
/// 获取凸包
///
///
private void convexity_defects(Mat src)
{
Mat src_copy = src.Clone();
Mat threshold_output = new Mat(), src_gray = new Mat();
OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
List hierarchy;
Cv2.CvtColor(src_copy, src_gray, ColorConversionCodes.BGR2GRAY);
Cv2.Threshold(src_gray, threshold_output, 0, 255, ThresholdTypes.Binary);
Cv2.FindContours(threshold_output, out contours, out hierarchyIndex, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple);
List hullsI = new List() { };
List defect = new List() { };
InputArray contoursAll = InputArray.Create(contours[0]);
List outArr = new List();
OutputArray hull = OutputArray.Create(outArr);
OutputArray hulls = OutputArray.Create(hullsI);
OutputArray defects = OutputArray.Create(defect);
Cv2.ConvexHull(contoursAll, hull, false);
// find int type hull
Cv2.ConvexHull(contoursAll, hulls, false);
InputArray hullsi = InputArray.Create(hullsI);
// get convexity defects
Cv2.ConvexityDefects(contoursAll, hullsi, defects);
/// Draw contours + hull results
Mat drawing = Mat.Zeros(threshold_output.Size(), MatType.CV_8UC3);
Scalar color = new Scalar(210, 50, 255);
Cv2.DrawContours(drawing, contours, 0, color, -1);
Cv2.DrawContours(drawing, new OpenCvSharp.Point[][] { outArr.ToArray() }, 0, color, -1);
// draw defects
int count = contours[0].Count();
foreach (var item in defect)
{
int startidx = item[0];
OpenCvSharp.Point ptStart = contours[0][startidx]; // point of the contour where the defect begins
int endidx = item[1];
OpenCvSharp.Point ptEnd = contours[0][endidx]; // point of the contour where the defect ends
int faridx = item[2];
OpenCvSharp.Point ptFar = contours[0][faridx];// the farthest from the convex hull point within the defect
int depth = item[3] / 256; // distance between the farthest point and the convex hull
if (depth > 2 && depth < 500)
{
Cv2.Line(drawing, ptStart, ptFar, new Scalar(0, 255, 0), 2);
Cv2.Line(drawing, ptEnd, ptFar, new Scalar(0, 255, 0), 2);
Cv2.Circle(drawing, ptStart, 4, new Scalar(255, 0, 0), 2);
Cv2.Circle(drawing, ptEnd, 4, new Scalar(255, 0, 0), 2);
Cv2.Circle(drawing, ptFar, 4, new Scalar(100, 0, 255), 2);
}
}
Cv2.ImShow("Hull demo", drawing);
}
#endregion
#region 开裂球
///
/// 忽略开裂球,设为开裂球,设为普通球
///
///
public List> DeleteBall(List pointFs, List KpointFs, List PpointFs)
{
List> data = new List>() { };
ProgressThreadProcClass procClass = new ProgressThreadProcClass();
int itemCount = 100;
Mat newMat = new Mat();
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
System.Threading.ThreadStart copyThreadProc =
delegate ()
{
try
{
action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
action.Lists.Add(new Args() { Key = "imageTypes", Value = 14 });
action.Lists.Add(new Args() { Key = "CreackBallPointFs", Value = pointFs });
action.Lists.Add(new Args() { Key = "CreackBallPointFsK", Value = KpointFs });
action.Lists.Add(new Args() { Key = "CreackBallPointFsP", Value = PpointFs });
newMat = this.PerformProcessGetdata(LunkMat, OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
}
catch (Exception e)
{
}
finally
{
progressEvents.EndOperation(OperationResult.Finished);
}
};
procClass.StartProgressAction(/*currentForm*/parent, itemCount, copyThreadProc, progressEvents, null);
if (bmc != null) { bmc.data = data; bmc.isedit = true; }
if (bc != null) { bc.data = data; bc.isedit = true; }
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.Refresh();
return data;
}
///
/// 绘制轮廓开裂球
///
///
public List> DrwLunKuoLie(List> pointFs, List KaiPointFs, List PuPointFs)
{
lineList_ball = pointFs;
kailie_ball = KaiPointFs;
putong_ball = PuPointFs;
List> data = new List>() { };
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
Mat newMat = new Mat();
ProgressThreadProcClass procClass = new ProgressThreadProcClass();
int itemCount = 100;
ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
System.Threading.ThreadStart copyThreadProc =
delegate ()
{
try
{
newMat = getKong(bitmap, out data);
}
catch (Exception)
{
}
finally
{
progressEvents.EndOperation(OperationResult.Finished);
}
};
procClass.StartProgressAction(/*currentForm*/parent, itemCount, copyThreadProc, progressEvents, null);
// Mat newMat = getKong(bitmap, out data);
if (bmc != null) { bmc.data = data; bmc.isedit = true; }
if (bc != null) { bc.data = data; bc.isedit = true; }
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.Refresh();
return data;
}
///
/// 绘制轮廓开裂球
///
///
public List> DrwLunKuoLie1(List> pointFs, List KaiPointFs, List PuPointFs)
{
lineList_ball = pointFs;
kailie_ball = KaiPointFs;
putong_ball = PuPointFs;
List> data = new List>() { };
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
Mat newMat = ReGetKong(bitmap, out data);
if (bmc != null) { bmc.data = data; bmc.isedit = true; }
if (bc != null) { bc.data = data; bc.isedit = true; }
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.Refresh();
return data;
}
///
/// 选择开裂球
///
///
public void DrwLunKuoLie1Selected(int select)
{
List> data = new List>() { };
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
action.Lists.Add(new Args() { Key = "SelPointFs", Value = select });
Mat newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.Refresh();
}
//所有点
Dictionary> particlePixles = new Dictionary>();
List relit = new List();
Mat g_srcImage = new Mat();
Mat temp = new Mat();
Vec4b vec4B = new Vec4b(255, 0, 0, 255);
Vec4b vec4B1 = new Vec4b(0, 0, 255, 255);
///
/// 获取开裂球
///
///
///
private Mat getKong(Bitmap img, out List> outdata)
{
particlePixles = new Dictionary>();
relit = new List();
g_srcImage = new Mat();
temp = new Mat();
outdata = new List>() { };
Mat M = OpenCvSharp.Extensions.BitmapConverter.ToMat(img);
//M.ConvertTo(g_srcImage, MatType.CV_8UC3);
Cv2.CvtColor(M, g_srcImage, ColorConversionCodes.BGRA2BGR);
if (lineList_ball.Count > 0)
{
for (int line = 0; line < lineList_ball.Count; line++)
{
List pointList = lineList_ball[line];
for (int i = 0; i < pointList.Count - 1; i++)
{
Cv2.Line(g_srcImage, new OpenCvSharp.Point() { X = (int)pointList[i].X, Y = (int)pointList[i].Y }, new OpenCvSharp.Point() { X = (int)pointList[i + 1].X, Y = (int)pointList[i + 1].Y }, new Scalar(0, 0, 0), 5);
}
}
}
//调试方便
// Cv2.Resize(g_srcImage, g_srcImage,new OpenCvSharp.Size(g_srcImage.Cols / 3, g_srcImage.Rows / 3), (0.0), (0.0), OpenCvSharp.InterpolationFlags.Area);
Mat gray = new Mat();
Mat binary = new Mat();
Mat shifted = new Mat(M.Size(), MatType.CV_8UC3);
//均值漂移 滤波
// Cv2.PyrMeanShiftFiltering(g_srcImage, shifted, 21, 51);
Cv2.GaussianBlur(g_srcImage, shifted, new OpenCvSharp.Size(15, 15), 0);
//灰度图
Cv2.CvtColor(shifted, gray, ColorConversionCodes.BGR2GRAY);
//二值化
double otsu = Cv2.Threshold(gray, binary, 100, 200, ThresholdTypes.Binary/*.Otsu*/);
// distance transform
Mat dist = new Mat();
Cv2.DistanceTransform(binary, dist, DistanceTypes.L2, DistanceMaskSize.Mask3);
//归一化数据
Cv2.Normalize(dist, dist, 0, 1, NormTypes.MinMax);
// binary
Cv2.Threshold(dist, dist, 0.4, 1, ThresholdTypes.Binary);
// markers
Mat dist_m = new Mat();
dist.ConvertTo(dist_m, MatType.CV_8UC1);
OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
Cv2.FindContours(dist_m, out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxNone);
// create markers
Mat markers = Mat.Zeros(g_srcImage.Size(), MatType.CV_32SC1);
for (int t = 0; t < contours.Length; t++)
{
Cv2.DrawContours(markers, contours, t, new Scalar(t + 1), -1);
}
// Cv2.ImShow("分割后", markers);
Cv2.Circle(markers, new OpenCvSharp.Point(5, 5), 30, new Scalar(255), -1);
//形体学操作 去掉干扰
InputArray kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3), new OpenCvSharp.Point(-1, -1));
Cv2.MorphologyEx(g_srcImage, g_srcImage, MorphTypes.Erode, kernel);
Cv2.Watershed(g_srcImage, markers);
// 颜色填充与最终显示
int index = 0;
for (int row = 0; row < markers.Rows; row++)
{
for (int col = 0; col < markers.Cols; col++)
{
index = markers.At(row, col);
if (index > 0 && index <= contours.Length)
{
if (particlePixles.ContainsKey(index))
{
particlePixles[index].Add(new OpenCvSharp.Point(col, row));
}
else
{
List Pixles = new List();
Pixles.Add(new OpenCvSharp.Point(col, row));
particlePixles.Add(index, Pixles);
}
}
}
}
int k = 0;
foreach (var item in particlePixles)
{
if (item.Value.Count > 99999)
{
k = item.Key;
break;
}
}
particlePixles.Remove(k);
//temp = Adjust.BaseImage.BaseTools.MergeMatFromMatArr(temp, vec4B);
int q = 0;
int iskailie = 0;
temp = new Mat(g_srcImage.Rows, g_srcImage.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
int index1 = 0;
foreach (var item in particlePixles)
{
// 将轮廓转为矩形框 , 这个最大的矩形为感兴趣的图像
Rect rect = Cv2.BoundingRect(item.Value);
List pixel = item.Value;
Mat particle = g_srcImage[rect];
Mat back = particle.Clone();
//Mat forwrit = M[rect];
//Mat small = forwrit.Clone();
//int n = 30;
//float MaxCG = 5.5f;
//Mat dst1 = myACE(small, n, MaxCG);
//Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
//Cv2.MorphologyEx(dst1, dst1, MorphTypes.BlackHat, element);
//Cv2.GaussianBlur(dst1, dst1, new OpenCvSharp.Size(3, 3), 0);
//Cv2.ImWrite("E://1/" + index1++.ToString() + ".jpg", dst1);
////for (int i = 0; i < small.Cols; i++)
////{
//// for (int j = 0; j < small.Rows; j++)
//// {
//// OpenCvSharp.Point pp = new OpenCvSharp.Point() { X=i+ rect.X, Y=j+ rect.Y };
//// if (pixel.Contains(pp))
//// {
//// continue;
//// }
//// small.Set(j, i, new Vec3b(255, 0, 0));
//// }
////}
//// Cv2.ImWrite("E:/ballcut/test" + index1.ToString() + ".jpg", small);
long aveg = 0;
long aveb = 0;
long aver = 0;
foreach (var pt in pixel)
{
if (kailie_ball.Count > 0)
{
PointF p = new PointF() { X = pt.X, Y = pt.Y };
if (kailie_ball.Contains(p))
{
iskailie = 1;
break;
}
}
if (putong_ball.Count > 0)
{
PointF p = new PointF() { X = pt.X, Y = pt.Y };
if (putong_ball.Contains(p))
{
iskailie = 2;
break;
}
}
aveg += particle.At(pt.Y - rect.Y, pt.X - rect.X)[0];
aveb += particle.At(pt.Y - rect.Y, pt.X - rect.X)[1];
aver += particle.At(pt.Y - rect.Y, pt.X - rect.X)[2];
}
int ret = 0;
if (iskailie == 1)
{
ret = 1;
}
else if (iskailie == 2)
{
ret = 0;
}
else
{
aveg = aveg / pixel.Count;
aveb = aveb / pixel.Count;
aver = aver / pixel.Count;
for (int i = 0; i < back.Cols; i++)
{
for (int j = 0; j < back.Rows; j++)
{
back.Set(j, i, new Vec3b((byte)aveg, (byte)aveb, (byte)aver));
}
}
foreach (var pt in pixel)
{
back.Set(pt.Y - rect.Y, pt.X - rect.X, particle.At(pt.Y - rect.Y, pt.X - rect.X));
}
ret = GetSplit2(back);
relit.Add(ret);
}
if (ret == 1)
{
Cv2.DrawContours(temp, new List>() { item.Value }, 0, new Scalar(0, 0, 255, 255), 2);
}
else if (ret == 0)
{
Cv2.DrawContours(temp, new List>() { item.Value }, 0, new Scalar(255, 0, 0, 255), 2);
}
double area = Cv2.ContourArea(item.Value);
int x = rect.X;
int y = rect.Y;
int width = rect.Width;
int height = rect.Height;
if (kailie_ball.Count > 0)
{
for (int i = 0; i < kailie_ball.Count; i++)
{
double px = kailie_ball[i].X;
double py = kailie_ball[i].Y;
if (px > x && px < (x + width) && py > y && py < (y + height))
{
ret = 1;
relit[index1] = 1;
break;
}
}
}
if (putong_ball.Count > 0)
{
for (int i = 0; i < putong_ball.Count; i++)
{
double px = putong_ball[i].X;
double py = putong_ball[i].Y;
if (px > x && px < (x + width) && py > y && py < (y + height))
{
ret = 0;
relit[index1] = 0;
break;
}
}
}
List po = new List() { x, y, width, height, (int)area, ret };
outdata.Add(po);
index1++;
}
Mat temp1 = new Mat();
Cv2.Erode(temp, temp1, null);
temp = temp - temp1;
return temp;
}
private Mat ReGetKong(Bitmap img, out List> outdata)
{
outdata = new List>() { };
if (particlePixles.Count == 0)
{
return null;
}
temp = new Mat(g_srcImage.Rows, g_srcImage.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
int index = 0;
foreach (var item in particlePixles)
{
// 将轮廓转为矩形框 , 这个最大的矩形为感兴趣的图像
Rect rect = Cv2.BoundingRect(item.Value);
List pixel = item.Value;
Mat particle = g_srcImage[rect];
int ret = relit[index];
double area = Cv2.ContourArea(item.Value);
int x = rect.X;
int y = rect.Y;
int width = rect.Width;
int height = rect.Height;
if (kailie_ball.Count > 0)
{
for (int i = 0; i < kailie_ball.Count; i++)
{
double px = kailie_ball[i].X;
double py = kailie_ball[i].Y;
if (px > x && px < (x + width) && py > y && py < (y + height))
{
ret = 1;
relit[index] = 1;
break;
}
}
}
if (putong_ball.Count > 0)
{
for (int i = 0; i < putong_ball.Count; i++)
{
double px = putong_ball[i].X;
double py = putong_ball[i].Y;
if (px > x && px < (x + width) && py > y && py < (y + height))
{
ret = 0;
relit[index] = 0;
break;
}
}
}
if (selectPointFs != null)
{
double px = selectPointFs.X;
double py = selectPointFs.Y;
if (px == x && py == y)
{
ret = 2;
}
}
index++;
if (ret == 1)
{
Cv2.DrawContours(temp, new List>() { item.Value }, 0, new Scalar(0, 0, 255, 255), 2);
}
else if (ret == 0)
{
Cv2.DrawContours(temp, new List>() { item.Value }, 0, new Scalar(255, 0, 0, 255), 2);
}
else if (ret == 2)
{
Cv2.DrawContours(temp, new List>() { item.Value }, 0, new Scalar(255, 255, 0, 255), 2);
}
List po = new List() { x, y, width, height, (int)area, ret };
outdata.Add(po);
}
Mat temp1 = new Mat();
Cv2.Erode(temp, temp1, null);
temp = temp - temp1;
return temp;
}
private Mat ReGetSelect(Bitmap img)
{
if (particlePixles.Count == 0)
{
return null;
}
temp = new Mat(g_srcImage.Rows, g_srcImage.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
int index = 0;
foreach (var item in particlePixles)
{
// 将轮廓转为矩形框 , 这个最大的矩形为感兴趣的图像
Rect rect = Cv2.BoundingRect(item.Value);
List pixel = item.Value;
Mat particle = g_srcImage[rect];
int ret = relit[index];
double area = Cv2.ContourArea(item.Value);
int x = rect.X;
int y = rect.Y;
int width = rect.Width;
int height = rect.Height;
if (kailie_ball.Count > 0)
{
for (int i = 0; i < kailie_ball.Count; i++)
{
double px = kailie_ball[i].X;
double py = kailie_ball[i].Y;
if (px > x && px < (x + width) && py > y && py < (y + height))
{
ret = 1;
relit[index] = 1;
break;
}
}
}
if (putong_ball.Count > 0)
{
for (int i = 0; i < putong_ball.Count; i++)
{
double px = putong_ball[i].X;
double py = putong_ball[i].Y;
if (px > x && px < (x + width) && py > y && py < (y + height))
{
ret = 0;
relit[index] = 0;
break;
}
}
}
if (selectPointFs != null)
{
double px = selectPointFs.X;
double py = selectPointFs.Y;
if (px == x && py == y)
{
ret = 2;
}
}
index++;
if (ret == 1)
{
Cv2.DrawContours(temp, new List>() { item.Value }, 0, new Scalar(0, 0, 255, 255), 2);
}
else if (ret == 0)
{
Cv2.DrawContours(temp, new List>() { item.Value }, 0, new Scalar(255, 0, 0, 255), 2);
}
else if (ret == 2)
{
Cv2.DrawContours(temp, new List>() { item.Value }, 0, new Scalar(255, 255, 0, 255), 2);
}
}
Mat temp1 = new Mat();
Cv2.Erode(temp, temp1, null);
temp = temp - temp1;
return temp;
}
private int GetSplit2(Mat src)
{
Mat shifted = new Mat(), gray = new Mat(), binary = new Mat(), dist;
//Cv2.GaussianBlur(src, shifted, new OpenCvSharp.Size(3, 3), 0);
Cv2.PyrMeanShiftFiltering(src, shifted, 10, 18); //模糊细节,这个参数由颗粒的大小确定
Cv2.CvtColor(shifted, gray, ColorConversionCodes.BGR2GRAY);
Mat element = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
Cv2.MorphologyEx(gray, gray, MorphTypes.TopHat, element);
Cv2.Threshold(gray, binary, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
Mat element1 = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3));
Cv2.MorphologyEx(binary, binary, MorphTypes.Open, element1);
for (int i = 0; i < 4; i++)
Cv2.MorphologyEx(binary, binary, MorphTypes.Dilate, element1);
int height = src.Rows;
int width = src.Cols;
OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
Cv2.FindContours(binary, out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxSimple, new OpenCvSharp.Point(0, 0));
if (contours.Length == 0)
{
return -1;
}
List arrAll = new List();
for (int t = 0; t < contours.Length; t++)
{
foreach (var item in contours[t])
{
arrAll.Add(item);
}
}
InputArray contoursAll = InputArray.Create(arrAll);
List outArr = new List();
List hullpoint = new List();
OutputArray hull = OutputArray.Create(outArr);
Cv2.ConvexHull(contoursAll, hull, true);
int hullcount = outArr.Count;
OpenCvSharp.Point point0 = outArr[hullcount - 1];
hullpoint.Add(point0);
for (int i = 0; i < hullcount; i++)
{
OpenCvSharp.Point point = outArr[i];
Cv2.Line(binary, point0, point, new Scalar(255, 255, 255));
point0 = point;
hullpoint.Add(point0);
}
bool flag = false;
for (int t = 0; t < contours.Length; t++)
{
int size = contours[t].Length;
if (size < 10)
{
continue;
}
Rect r = Cv2.BoundingRect(contours[t]);
float rcX = r.X + r.Width / 2;
float rcY = r.Y + r.Height / 2;
double d = Cv2.PointPolygonTest(hullpoint, new Point2f(rcX, rcY), true);
if ((d == 0) || (d < 0) || ((d < 15) && (d > 0))) //在凸包边缘上,在凸包的外部,在凸包的内部
{
continue;
}
else
{
flag = true;
break;
}
}
if (flag == true)
{
return 1;
}
return 0;
}
#region 赵天宇算法
public void test(Mat src)
{
Mat dst = new Mat();
//1:因为霍夫圆检测对噪声比较敏感,所以首先对图像做一个中值滤波或高斯滤波(噪声如果没有可以不做)
Mat m1 = new Mat();
Cv2.MedianBlur(src, m1, 3); // ksize必须大于1且是奇数
//2:转为灰度图像
Mat m2 = m1.Clone();
// m1.Release();
Cv2.CvtColor(m1, m2, ColorConversionCodes.BGR2GRAY);
CircleSegment[] cs = Cv2.HoughCircles(m2, HoughMethods.Gradient, 1, 130, 60, 25, 35, 80);
m2.Release();
src.CopyTo(dst);
//大圆
for (int i = 0; i < cs.Count(); i++)
{
//画圆
Cv2.Circle(dst, (int)cs[i].Center.X, (int)cs[i].Center.Y, (int)cs[i].Radius, new Scalar(0, 0, 255), 2, LineTypes.AntiAlias);
//加强圆心显示
Cv2.Circle(dst, (int)cs[i].Center.X, (int)cs[i].Center.Y, 3, new Scalar(0, 0, 255), 2, LineTypes.AntiAlias);
}
using (new Window("OutputImage", WindowMode.Normal, dst))
using (new Window("InputImage", WindowMode.Normal, src))
{
Cv2.WaitKey(0);
}
Mat srcBlack;
int sucessCs = 0;
int badCs = 0;
for (int i = 0; i < cs.Count(); i++)
{
srcBlack = new Mat(src.Height, src.Width, MatType.CV_8UC1, new Scalar(0));//黑色底图
//画圆
Cv2.Circle(dst, (int)cs[i].Center.X, (int)cs[i].Center.Y, (int)cs[i].Radius, new Scalar(0, 0, 255), 2, LineTypes.AntiAlias);
//加强圆心显示
Cv2.Circle(dst, (int)cs[i].Center.X, (int)cs[i].Center.Y, 3, new Scalar(0, 0, 255), 2, LineTypes.AntiAlias);
//画圆
Cv2.Circle(srcBlack, (int)cs[i].Center.X, (int)cs[i].Center.Y, (int)cs[i].Radius, Scalar.White, 1, LineTypes.AntiAlias);
OpenCvSharp.Point[][] contours;
HierarchyIndex[] hierarchy;
Cv2.FindContours(srcBlack, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
Cv2.DrawContours(srcBlack, contours, -1, Scalar.White, -1, LineTypes.Link8, hierarchy, 4, new OpenCvSharp.Point(0, 0));
//取所有的点
List srPoints = new List();
unsafe
{
int rows = srcBlack.Height, cols = srcBlack.Width;
for (int k = 0; k < rows; k++)
{
IntPtr a = srcBlack.Ptr(k);
byte* b = (byte*)a.ToPointer();
for (int j = 0; j < cols; j++)
{
if (b[j] != 0)
{
srPoints.Add(new OpenCvSharp.Point(j, k));
}
}
}
}
for (int j = 0; j < srPoints.Count; j++)
{
int item = src.Get(srPoints[j].Y, srPoints[j].X);
srcBlack.Set(srPoints[j].Y, srPoints[j].X, item);
}
Mat rect = new Mat(srcBlack, Cv2.BoundingRect(contours[0]));
//Cv2.EqualizeHist(rect, dst);
Cv2.GaussianBlur(rect, dst, new OpenCvSharp.Size(3, 3), 0);
//Cv2.MedianBlur(dst, dst, 1);
Mat aa = dst.Threshold(50, 255, ThresholdTypes.BinaryInv);
Cv2.FindContours(aa, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
Point2f center = new Point2f(aa.Cols / 2, aa.Rows / 2);
Mat bb = new Mat(aa.Height, aa.Width, MatType.CV_8UC1, new Scalar(0));//黑色底图
Cv2.Circle(bb, (int)center.X, (int)center.Y, (int)cs[i].Radius - 15, Scalar.White, 1, LineTypes.AntiAlias);
OpenCvSharp.Point[][] contoursCircleLine;
HierarchyIndex[] hierarchyLine;
Cv2.FindContours(bb, out contoursCircleLine, out hierarchyLine, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
List contoursCircleLineOne = new List();
for (int m = 0; m < contoursCircleLine.Count(); m++)
{
for (int n = 0; n < contoursCircleLine[m].Count(); n++)
{
contoursCircleLineOne.Add(contoursCircleLine[m][n]);
}
}
//内缩
Rect bigRect = new Rect(0, 0, rect.Width, rect.Height);
for (int nX = bigRect.X; nX <= bigRect.Right; nX++)
{
for (int nY = bigRect.Y; nY <= bigRect.Bottom; nY++)
{
double localPos = Cv2.PointPolygonTest(contoursCircleLineOne, new Point2f(nX, nY), false);
if (localPos == 1 || localPos == 0)//像素点在多边形内和边缘
{
}
else
{
aa.Set(nX, nY, 0);
}
}
}
Cv2.FindContours(aa, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxNone, null);
Cv2.CvtColor(aa, aa, ColorConversionCodes.RGB2BGR);
List contoursHoleList = contours.OrderByDescending(t => t.Count()).ToList();
if (contoursHoleList.Count == 0)
{
continue;
}
List maxList = new List();
int MaxListCount = 5;
if (contoursHoleList.Count < MaxListCount)
{
MaxListCount = contoursHoleList.Count;
}
for (int g = 0; g < contoursHoleList.Count; g++)
{
maxList.Add(contoursHoleList[g].Count());
if (g == MaxListCount - 1)
{
break;
}
}
for (int k = 0; k < contours.Count(); k++)
{
RotatedRect rectR = Cv2.MinAreaRect(contours[k]); //计算每个轮廓最小外接矩形
Rect rectB = Cv2.BoundingRect(contours[k]);
float width = rectR.Size.Width >= rectR.Size.Height ? rectR.Size.Width : rectR.Size.Height;
float height = rectR.Size.Width < rectR.Size.Height ? rectR.Size.Width : rectR.Size.Height;
height = height == 0 ? 1 : height;
if (maxList.Contains(contours[k].Count()))
{
double distance = 0;
for (int m = 0; m < contours[k].Count(); m++)
{
Point2f centerCoutours = new Point2f(contours[k][m].X, contours[k][m].Y);
distance += centerCoutours.DistanceTo(center);
}
distance = distance / contours[k].Count();
OpenCvSharp.Point[] lineDmax = new OpenCvSharp.Point[2];
RotatedRect minRect;
// double ratio = GetDMax(contours[k], out lineDmax) / GetDMin(contours[k], out minRect);
if (distance > 55)
{
Cv2.DrawContours(aa, contours, k, Scalar.Yellow, -1, LineTypes.Link8, hierarchy, 4, new OpenCvSharp.Point(0, 0));
}
else if (/*ratio > 2 && */Cv2.ArcLength(contours[k], true) < 15)
{
Cv2.DrawContours(aa, contours, k, Scalar.Blue, -1, LineTypes.Link8, hierarchy, 4, new OpenCvSharp.Point(0, 0));
}
else
{
Cv2.DrawContours(aa, contours, k, Scalar.Green, -1, LineTypes.Link8, hierarchy, 4, new OpenCvSharp.Point(0, 0));
}
}
else
{
Cv2.DrawContours(aa, contours, k, Scalar.Red, -1, LineTypes.Link8, hierarchy, 4, new OpenCvSharp.Point(0, 0));
}
}
using (new Window("OutputImage", WindowMode.Normal, rect))
using (new Window("InputImage", WindowMode.Normal, aa))
{
//Cv2.WaitKey(0);
if (MessageBox.Show("当前识别率:" + ((float)sucessCs / (sucessCs + badCs) * 100) + "是否正确?", "识别判断", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
sucessCs += 1;
}
else
{
badCs += 1;
}
}
}
MessageBox.Show("识别准确率: " + ((float)sucessCs / cs.Count() * 100));
}
#endregion
#endregion
#region 单晶
///
/// 筛选单晶
///
///
public List> ForgetCrystal(double pointsize)
{
List> data = new List>() { };
ProgressThreadProcClass procClass = new ProgressThreadProcClass();
int itemCount = 100;
Mat newMat = new Mat();
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
System.Threading.ThreadStart copyThreadProc =
delegate ()
{
try
{
action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
action.Lists.Add(new Args() { Key = "imageTypes", Value = 12 });
action.Lists.Add(new Args() { Key = "pointsize", Value = pointsize });
action.Lists.Add(new Args() { Key = "borderBottom", Value = borderBottom });
action.Lists.Add(new Args() { Key = "border", Value = border });
action.Lists.Add(new Args() { Key = "HW", Value = HW });
action.Lists.Add(new Args() { Key = "AreaRatio", Value = AreaRatio });
action.Lists.Add(new Args() { Key = "isDis", Value = isDis });
action.Lists.Add(new Args() { Key = "isJu", Value = isJu });
string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
string newbitmap = subPath + "\\mask.jpg";
Mat mask = Cv2.ImRead(newbitmap);
newMat = this.PerformProcessGetdata(mask, out data);
//newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitDJ), out data);
}
catch (Exception e)
{
}
finally
{
progressEvents.EndOperation(OperationResult.Finished);
}
};
procClass.StartProgressAction(/*currentForm*/parentSinglCrystal, itemCount, copyThreadProc, progressEvents, null);
if (bmc != null) { bmc.data = data; bmc.isedit = true; }
if (bc != null) { bc.data = data; bc.isedit = true; }
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.Refresh();
return data;
}
///
/// 删除添加单晶
///
///
public List> DeleteCrystal(List pointFs, List> addPoints)
{
List> data = new List>() { };
ProgressThreadProcClass procClass = new ProgressThreadProcClass();
int itemCount = 100;
Mat newMat = new Mat();
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
ProgressThreadProcClass.IFileTransferProgressEvents progressEvents = new ProgressThreadProcClass.IFileTransferProgressEvents();
System.Threading.ThreadStart copyThreadProc =
delegate ()
{
try
{
List> AddPoints = new List>();
if (addPoints.Count > 0)
{
for (int i = 0; i < addPoints.Count; i++)
{
List plist = new List();
addPoints[i].ForEach(p => plist.Add(new OpenCvSharp.Point((int)p.X, (int)p.Y)));
AddPoints.Add(plist);
}
}
action.Lists.Add(new Args() { Key = "SelPointFs", Value = -1 });
action.Lists.Add(new Args() { Key = "imageTypes", Value = 12 });
action.Lists.Add(new Args() { Key = "DelPointFs", Value = pointFs });
action.Lists.Add(new Args() { Key = "AddPontins", Value = AddPoints });
string subPath = System.Configuration.ConfigurationManager.AppSettings["TempPath"];
string newbitmap = subPath + "\\mask.jpg";
Mat mask = Cv2.ImRead(newbitmap);
newMat = this.PerformProcessGetdata(mask, out data);
//newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitDJ), out data);
}
catch (Exception e)
{
}
finally
{
progressEvents.EndOperation(OperationResult.Finished);
}
};
procClass.StartProgressAction(/*currentForm*/parentSinglCrystal, itemCount, copyThreadProc, progressEvents, null);
if (bmc != null) { bmc.data = data; bmc.isedit = true; }
if (bc != null) { bc.data = data; bc.isedit = true; }
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.Refresh();
return data;
}
///
/// 绘制单晶选择
///
///
public void DrwCrystalSelected(int select)
{
List> data = new List>() { };
Bitmap bitmap = this.appWorkspace.DocumentWorkspaces[this.listView1.FocusedItem != null ? this.listView1.FocusedItem.Index : this.listView1.SelectedItems[0].Index].CompositionSurface.CreateAliasedBitmap();
action.Lists.Add(new Args() { Key = "SelPointFs", Value = select });
Mat newMat = this.PerformProcessGetdata(OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap), out data);
documentWorkspace.PhaseModels[0].mat = newMat;
documentWorkspace.Refresh();
}
private Mat getCutback(Bitmap img)
{
Mat mat = OpenCvSharp.Extensions.BitmapConverter.ToMat(img);
Mat g_grayImage = new Mat();
Mat g_dstImage = new Mat();
Mat g_bwImage = new Mat();
Mat dst = new Mat();
//灰度图
Cv2.CvtColor(mat, g_grayImage, ColorConversionCodes.BGR2GRAY);
//图像二值化
Cv2.Threshold(g_grayImage, g_bwImage, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
Cv2.ImShow("g_bwImage", g_bwImage);
OpenCvSharp.Point[][] contours = new OpenCvSharp.Point[][] { };
HierarchyIndex[] hierarchyIndex = new HierarchyIndex[] { };
//轮廓
Cv2.FindContours(g_bwImage, out contours, out hierarchyIndex, RetrievalModes.External, ContourApproximationModes.ApproxNone);
Mat matret = new Mat(mat.Rows, mat.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
for (int i = 0; i < contours.Length; i++)
{
if (Cv2.ContourArea(contours[i]) < 30)
continue;
Cv2.DrawContours(matret, contours, i, new Scalar(255, 144, 30, 255), -1);
}
Cv2.BitwiseAnd(mat, matret, dst);
Cv2.ImShow("dst", dst);
return dst;
}
///
/// 单晶颗粒
///
private void DanJing(Bitmap img)
{
Mat g_srcImage = new Mat();
Mat M = OpenCvSharp.Extensions.BitmapConverter.ToMat(img);
Cv2.CvtColor(M, g_srcImage, ColorConversionCodes.BGRA2BGR);
//调试方便
// Cv2.Resize(g_srcImage, g_srcImage, new OpenCvSharp.Size(g_srcImage.Cols / 3, g_srcImage.Rows / 3), (0.0), (0.0), OpenCvSharp.InterpolationFlags.Area);
int rows = g_srcImage.Rows;
int cols = g_srcImage.Cols;
g_srcImage = g_srcImage[new Rect(0, 0, cols, rows - 50)];
Mat gray = new Mat(), binary = new Mat(), shifted;
Cv2.CvtColor(g_srcImage, gray, ColorConversionCodes.BGR2GRAY);
Mat element = Cv2.GetStructuringElement(MorphShapes.Ellipse, new OpenCvSharp.Size(5, 5), new OpenCvSharp.Point(2, 2));
Cv2.MorphologyEx(gray, gray, MorphTypes.Open, element);//
Cv2.Threshold(gray, binary, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
Cv2.ImShow("二值图像", binary);
Mat labels = new Mat();
int n_comps = Cv2.ConnectedComponents(binary, labels, PixelConnectivity.Connectivity4);
Dictionary> particlePixles = new Dictionary>();
//draw
rows = g_srcImage.Rows;
cols = g_srcImage.Cols;
Mat src_color = new Mat();// = Mat::zeros(imageShold.size(), CV_8UC3);
src_color.Create(rows, cols, MatType.CV_8UC3);
// src_color = Scalar.All(0);
for (int x = 0; x < rows; x++)
{
for (int y = 0; y < cols; y++)
{
int label = labels.At(x, y);//注意labels是CV_16U类型
if (label != 0)
{
if (particlePixles.ContainsKey(label))
{
particlePixles[label].Add(new OpenCvSharp.Point(y, x));
}
else
{
List Pixles = new List();
Pixles.Add(new OpenCvSharp.Point(y, x));
particlePixles.Add(label, Pixles);
}
}
if (label == 0)
{
src_color.Set(x, y, new Vec3b(255, 255, 255));
continue;
}
Vec3b vec3 = new Vec3b((byte)((label * 10 * 10 * 10) % 255), (byte)((label * 10 * 10) % 255), (byte)((label * 10) % 255));
src_color.Set(x, y, vec3);
}
}
int partnum = 0;
int image1 = 0;
foreach (var item in particlePixles)
{
List pixel = item.Value;
Rect rect = Cv2.BoundingRect(pixel);
Mat particle = g_srcImage[rect];
string windowName = string.Format("{0}", image1++) + ".jpg";
int num = TinyParticle(particle, windowName);
// Mat outImage =Cv2.ImRead(windowName);
partnum += num;
// Cv2.AddWeighted(particle, 0, outImage, 1, 0, particle);
}
Cv2.ImShow("原始图像", g_srcImage);
}
int GetNumber(int input)
{
int number = 0;
while (input > 0)
{
if (input != 0)
{
number++;
}
input = input / 10;
}
return number;
}
int TinyParticle(Mat image, string filename)
{
//灰度化,滤波,Canny边缘检测
Mat imageGray = new Mat();
// Cv2.Resize(image, image, new OpenCvSharp.Size(image.Cols / 10, image.Rows / 3), (0.0), (0.0), OpenCvSharp.InterpolationFlags.Area);
Cv2.PyrMeanShiftFiltering(image, image, 20, 48); //模糊细节,这个参数由颗粒的大小确定
Cv2.CvtColor(image, imageGray, ColorConversionCodes.BGR2GRAY);//灰度转换
//区间滤波
for (int i = 0; i < imageGray.Rows; i++)
{
for (int j = 0; j < imageGray.Cols; j++)
{
if (imageGray.At(i, j) > 105 && imageGray.At(i, j) < 130)
{
imageGray.Set