using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using OpenCvSharp; namespace PaintDotNet.ImageCollect.CameraEDOF { class Merge { private Mat ImMer; private Mat[] coll; private Mat[] Coll_Ori; private int dstWidth = 0; //计算景深扩展高度值 private Base.SettingModel.ThreeDataDemoModel threeDataDemo; private List> threedDataList; private List dataValueList; /// /// 返回景深扩展的结果,解决了之前方法内存释放不及时的问题 /// /// 输入Mat集合 /// null 表示成功, ""表示失败但没有返回提示信息, 其他表示失败并且有返回提示信息 /// public static Mat GetMergeMat(Mat [] Coll_Ori, ref String errorMsg) { Merge merge = new Merge(); Mat dst; try { dst = merge.ImMerge(Coll_Ori, ref errorMsg); } catch (Exception) { dst = Coll_Ori[0].Clone(); } return dst; } /// /// 返回景深扩展的结果 /// /// 输入Mat集合 /// private unsafe Mat ImMerge(Mat[] mats, ref String errorMsg) { this.ImMer = new Mat(mats[0].Size(), mats[0].Type()); bool isSameSize = true; for (int index = 1; index < mats.Length; index++) { if (mats[index].Width != ImMer.Width || mats[index].Height != ImMer.Height) { isSameSize = false; break; } } if (!isSameSize)//图像宽高不一致 { errorMsg = ""; System.Windows.Forms.MessageBox.Show(PdnResources.GetString("Menu.noyizhi.Text")); return ImMer; } Mat[] Coll_deal = new Mat[mats.Length]; for (int index = 0; index < mats.Length; index++) { //灰度sobel平滑 Coll_deal[index] = this.Deal(mats[index]); } this.coll = Coll_deal; this.Coll_Ori = mats; dstWidth = coll[0].Width; coll[0].ForEachAsDouble(DefineProfileForEachAsVec4b); if (Coll_deal != null) { foreach (Mat item in Coll_deal) { item.Dispose(); } //Coll_deal[0].Dispose(); } GC.Collect(); errorMsg = null; return ImMer; } private List bitsHeight = new List(); /// /// 返回景深扩展的结果,存储到配置文件中 /// /// 输入Mat集合 /// public static bool GetMergeMatHeight(Mat[] Coll_Ori, ref String errorMsg, List bitsHeight) { Merge merge = new Merge(); merge.bitsHeight.AddRange(bitsHeight); bool dst; try { dst = merge.ImMergeHeight(Coll_Ori, ref errorMsg); } catch (Exception) { dst = false; } return dst; } private unsafe bool ImMergeHeight(Mat[] Coll_Ori, ref String errorMsg) { this.ImMer = new Mat(Coll_Ori[0].Size(), Coll_Ori[0].Type()); bool isSameSize = true; for (int index = 1; index < Coll_Ori.Length; index++) { if (Coll_Ori[index].Width != Coll_Ori[0].Size().Width || Coll_Ori[index].Height != Coll_Ori[0].Size().Height) { isSameSize = false; break; } } if (!isSameSize)//图像宽高不一致 { errorMsg = ""; System.Windows.Forms.MessageBox.Show(PdnResources.GetString("Menu.noyizhi.Text")); return false; } Mat[] Coll_deal = new Mat[Coll_Ori.Length]; for (int index = 0; index < Coll_Ori.Length; index++) { //灰度sobel平滑 Coll_deal[index] = this.Deal(Coll_Ori[index]); } this.coll = Coll_deal; this.Coll_Ori = Coll_Ori; dstWidth = coll[0].Width; int matHeight = coll[0].Height; dataValueList = new List(); threedDataList = new List>(); threeDataDemo = new Base.SettingModel.ThreeDataDemoModel();// Base.CommTool.XmlSerializeHelper.DESerializer(Base.CommTool.FileOperationHelper.ReadStringFromFile(System.Windows.Forms.Application.StartupPath + "\\Config\\" + "Default"/*SettingPrefix*/ + "\\ThreeDataDemo.xml", System.IO.FileMode.Open)); threeDataDemo.size = new Base.SettingModel.ThreeDataDemoModel.Size();//.Height = coll[0].Height; threeDataDemo.size.Height = coll[0].Height; threeDataDemo.size.Width = dstWidth; threeDataDemo.Z_value = new List(); for (int threeD = 0; threeD < dstWidth; threeD++) { List threedData = new List(); for (int indexY = 0; indexY < coll[0].Height; indexY++) threedData.Add(0.0); threedDataList.Add(threedData); } coll[0].ForEachAsDouble(DefineProfileForEachAsVec4bForHeight); if (this.ImMer != null) { Mat matGray = this.ImMer.CvtColor(ColorConversionCodes.BGR2GRAY); for (int index_x = 0; index_x < threedDataList.Count; index_x++) { List threedData = threedDataList[index_x]; for (int index_y = 0; index_y < matHeight; index_y++) {//高度与颜色相乘 byte vec = matGray.At(index_y, index_x); threedData[index_y] = 1.6 * threedData[index_y];// * vec / 255.0; } threeDataDemo.Z_value.Add(string.Join(",", threedData.ToArray())); } } //if (dataValueList.Count > 0) //{ //} threeDataDemo.Z_level = "16.000000,0.000000"; if (threeDataDemo.Dyeing == null || threeDataDemo.Dyeing.Count == 0) threeDataDemo.Dyeing = new List(); //threeDataDemo.Dyeing.Add("100.00,0.00,100.00"); threeDataDemo.Dyeing.Add("255.00,0.00,0.00"); threeDataDemo.Dyeing.Add("0.00,255.00,0.00"); string filePath = System.Windows.Forms.Application.StartupPath/* + "\\Config\\" + "Default"*//*SettingPrefix*/ + "\\ThreeDataDemo_temp.xml"; string toolbarXml = Base.CommTool.XmlSerializeHelper.XmlSerialize(threeDataDemo); if (Base.CommTool.FileOperationHelper.WriteStringToFile(toolbarXml, filePath, System.IO.FileMode.Create)) errorMsg = "配置文件保存成功"; //System.Windows.Forms.MessageBox.Show("配置文件保存成功"); else errorMsg = "配置文件保存成功"; //System.Windows.Forms.MessageBox.Show("配置文件保存失败"); if (Coll_deal != null) { foreach (Mat item in Coll_deal) { item.Dispose(); } //Coll_deal[0].Dispose(); } GC.Collect(); string filePath_ImMer = System.Windows.Forms.Application.StartupPath/* + "\\Config\\" + "Default"*//*SettingPrefix*/ + "\\ThreeDataDemo_temp.bmp"; Cv2.ImWrite(filePath_ImMer, this.ImMer); errorMsg = null; return true; } /// /// 返回景深扩展的结果,硬件调用实现 /// /// 输入Mat集合 /// public static Mat GetMergeMatForCamera(Mat[] Coll_Ori) { Merge merge = new Merge(); Mat dst; try { dst = merge.ImMergeForCamera(Coll_Ori); } catch (Exception) { dst = Coll_Ori[0].Clone(); } return dst; } /// /// 返回景深扩展的结果 /// /// 输入Mat集合 /// private unsafe Mat ImMergeForCamera(Mat[] Coll_Ori) { this.ImMer = new Mat(Coll_Ori[0].Size(), Coll_Ori[0].Type()); bool isSameSize = true; for (int index = 1; index < Coll_Ori.Length; index++) { if (Coll_Ori[index].Width != ImMer.Width || Coll_Ori[index].Height != ImMer.Height) { isSameSize = false; break; } } if (!isSameSize)//图像宽高不一致 { //System.Windows.MessageBox.Show("导入图片大小不一致,无法融合"); return ImMer; } Mat[] Coll_deal = new Mat[Coll_Ori.Length]; for (int index = 0; index < Coll_Ori.Length; index++) { //灰度sobel平滑 Coll_deal[index] = this.Deal(Coll_Ori[index]); } this.coll = Coll_deal; this.Coll_Ori = Coll_Ori; dstWidth = coll[0].Width; coll[0].ForEachAsDouble(DefineProfileForEachAsVec3b); //Mat col0 = coll[0]; //double* pixels2 = (double*)col0.Data; //for (int i = 0; i < col0.Rows; i++) //{ // for (int j = 0; j < col0.Cols; j++) // { // int index_y = i;// position[0]; // int index = j;// position[1]; // double G1 = pixels2[i * dstWidth + j]; // int numIdx = 0; // for (int num = 1; num < coll.Length; num++) // { // double* pixels3 = (double*)coll[num].Data; // double G2 = pixels3[i * dstWidth + j]; // if (G1 <= G2) // { // G1 = (double)G2; // numIdx = num; // } // } // Vec3b* pixels4 = (Vec3b*)Coll_Ori[numIdx].Data; // ImMer.Set(index_y, index, pixels4[index_y * dstWidth + index]); // } //} if (Coll_deal != null) { foreach (Mat item in Coll_deal) { item.Dispose(); } //Coll_deal[0].Dispose(); } GC.Collect(); return ImMer; } /// /// 灰度sobel平滑 /// /// /// private Mat Deal(Mat ImIn) { Mat mat_gray = new Mat(); Cv2.CvtColor(ImIn, mat_gray, ColorConversionCodes.BGR2GRAY); Mat X = new Mat(); Mat Y = new Mat(); //sobel边缘 //-----------这里开始转变为16位运算------------- Cv2.Sobel(mat_gray, X, MatType.CV_16S, 1, 0, 3, 1, 0, BorderTypes.Replicate); Cv2.Sobel(mat_gray, Y, MatType.CV_16S, 0, 1, 3, 1, 0, BorderTypes.Replicate); //-------double型数据的对应像素深度是64F--------- var output = new Mat(X.Size(), MatType.CV_64F); Mat ZZ = (X.Pow(2) + Y.Pow(2)); ZZ.ConvertTo(output, MatType.CV_64F); Cv2.Sqrt(output, output); Cv2.GaussianBlur(output, output, new OpenCvSharp.Size(31, 31), 11); if (mat_gray != null) mat_gray.Dispose(); if (X != null) X.Dispose(); if (Y != null) Y.Dispose(); if (ZZ != null) ZZ.Dispose(); return output; } /// /// 获取ID标识并进行赋值 /// /// /// private unsafe void DefineProfileForEachAsVec4b(double* value, int* position) { int index_y = position[0]; int index = position[1]; double G1 = *value; int numIdx = 0; for (int num = 1; num < coll.Length; num++) { double* pixels3 = (double*)coll[num].Data; double G2 = pixels3[position[0] * dstWidth + position[1]]; if (G1 <= G2) { G1 = (double)G2; numIdx = num; } } Vec4b* pixels4 = (Vec4b*)Coll_Ori[numIdx].Data; ImMer.Set(index_y, index, pixels4[index_y * dstWidth + index]); } /// /// 获取ID标识并进行赋值高度 /// /// /// private unsafe void DefineProfileForEachAsVec4bForHeight(double* value, int* position) { int index_y = position[0]; int index = position[1]; double G1 = *value; //double G111 = *value; ////if (threeDataDemo.Dyeing == null || threeDataDemo.Dyeing.Count == 0) //// threeDataDemo.Dyeing = new List(); ////threeDataDemo.Dyeing.Add("100.00,0.00,100.00"); //string filePath = Application.StartupPath + "\\Config\\" + "Default"/*SettingPrefix*/ + "\\ThreeDataDemo_5.xml"; //string toolbarXml = XmlSerializeHelper.XmlSerialize(threeDataDemo); //if (FileOperationHelper.WriteStringToFile(toolbarXml, filePath, FileMode.Create)) // MessageBox.Show("配置文件保存成功"); //else // MessageBox.Show("配置文件保存失败"); ////foreach (var item in threeDataDemo.Size) ////{ //// string item11 = item + ""; ////} int numIdx = 0; for (int num = 1; num < coll.Length; num++) { double* pixels3 = (double*)coll[num].Data; double G2 = pixels3[position[0] * dstWidth + position[1]]; if (G1 < G2) { G1 = (double)G2; numIdx = num; } //else if (G1 - G2 < 5) //{ // G1 = (double)G2; // numIdx = num; //} ////if (G111 > G2) //// G111 = (double)G2; } if (this.bitsHeight.Count > numIdx) threedDataList[index][index_y] = (double)this.bitsHeight[numIdx];// + G1;// / 1000.0; //{ // threedDataList[index][index_y] = 3.6 * (double)(0/*38*/ + this.bitsHeight[numIdx]);// + G1 * 0.5;// + G1;// / 1000.0; // if (!dataValueList.Contains((double)this.bitsHeight[numIdx])) // { // dataValueList.Add((double)this.bitsHeight[numIdx]); // } //} else threedDataList[index][index_y] = G1; Vec4b* pixels4 = (Vec4b*)Coll_Ori[numIdx].Data; ImMer.Set(index_y, index, pixels4[index_y * dstWidth + index]); } /// /// 获取ID标识并进行赋值 /// /// /// private unsafe void DefineProfileForEachAsVec3b(double* value, int* position) { int index_y = position[0]; int index = position[1]; double G1 = *value; int numIdx = 0; for (int num = 1; num < coll.Length; num++) { double* pixels3 = (double*)coll[num].Data; double G2 = pixels3[position[0] * dstWidth + position[1]]; if (G1 <= G2) { G1 = (double)G2; numIdx = num; } } Vec3b* pixels4 = (Vec3b*)Coll_Ori[numIdx].Data; ImMer.Set(index_y, index, pixels4[index_y * dstWidth + index]); } } }