using OpenCvSharp; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SmartCoalApplication.Base.CommTool { public class DieGouTools { /// /// 判断是否进行图像增强 /// 获取直方图,判断第一个峰的像素个数如果占全图的百分之八十以上,则不增强,否则增强 /// /// /// public static bool CalcEnhanceFlag(Mat gray) { float[] hist_float = HistTools.CalcHist(gray); //直方图平滑 int[] hist_int = HistTools.Smooth(hist_float, 20); List mountainsList = new List(); List mountainsArrList = new List(); List mountainsArrListBackUp = new List(); Tools.FindTopAndBetweenWithOutWT123(hist_int, 0, 255, mountainsList, mountainsArrList, mountainsArrListBackUp, new List(), 15); float sum = 0; for(int i= mountainsArrList[0][0]; i<= mountainsArrList[0][1]; i++) { sum += hist_int[i]; } if(sum / hist_int.Sum() > 0.8) return false; return true; } /// /// 使用两次阈值寻找线 /// /// /// public static List CalcDarkOrLight(Mat gray, Vec4b vec4B) { List SplitListB = new List(); double thresh = Cv2.Threshold(gray, new Mat(), 0, 255, ThresholdTypes.Triangle); Mat mask_dark = new Mat(gray.Size(), gray.Type()); Mat mask_light = new Mat(gray.Size(), gray.Type()); for (int h = 0; h < gray.Height; h++) { for (int w = 0; w < gray.Width; w++) { int v = gray.At(h, w); if (v <= thresh) mask_dark.Set(h, w, 255); if (v >= 105) mask_light.Set(h, w, 255); } } //去碎屑 mask_dark = BinaryTools.SingleChannelDebrisRemoval(mask_dark, 10000); //空洞填充 mask_dark = BinaryTools.SingleChannelHoleFilling(mask_dark, vec4B); //去碎屑 mask_light = BinaryTools.SingleChannelDebrisRemoval(mask_light, 10000); //空洞填充 mask_light = BinaryTools.SingleChannelHoleFilling(mask_light, vec4B); int first = -1, end = -1; for (int i = 0; i < mask_dark.Height - 1; i++) { /*if (mask_dark.Row[i].CountNonZero() == mask_dark.Width) { if (first == -1) first = i; end = i; } if(mask_dark.Row[i].CountNonZero() == 0) { if(first!=-1) SplitListB.Add(first); if (end != -1) SplitListB.Add(end); first = -1; end = -1; }*/ int v1 = mask_dark.At(i, mask_dark.Width / 2); int v2 = mask_dark.At(i + 1, mask_dark.Width / 2); if ((v1 == 255 && v2 == 0) || (v1 == 0 && v2 == 255)) { SplitListB.Add(i); } } //if(SplitListB.Count==0) 如果不加这个条件,会丢失一些线,但是加了会有一些干扰出现 { first = -1; end = -1; Mat labels_light = new Mat(); Mat stats_light = new Mat(); Mat centroids_light = new Mat(); //连通域数量 int num_1 = Cv2.ConnectedComponentsWithStats(mask_light, labels_light, stats_light, centroids_light, PixelConnectivity.Connectivity8); int all = 0; int abc = -1; for (int j = 1; j < stats_light.Height; j++) { int x = stats_light.At(j, 0); int y = stats_light.At(j, 1); int width = stats_light.At(j, 2); int height = stats_light.At(j, 3); int area = stats_light.At(j, 4); if (width == mask_light.Width) { if (abc == -1) abc = j; all++; } } if (all >= 3) mask_light[stats_light.At(abc, 1), stats_light.At(abc, 3) + stats_light.At(abc, 1), stats_light.At(abc, 0), stats_light.At(abc, 2) - 1] *= 0; for (int i = 0; i < mask_light.Height - 1; i++) { /*if (mask_light.Row[i].CountNonZero() == mask_light.Width) { if (first == -1) first = i; end = i; } if (mask_light.Row[i].CountNonZero() == 0) { if (first != -1) SplitListB.Add(first); if (end != -1) SplitListB.Add(end); first = -1; end = -1; }*/ int v1 = mask_light.At(i, mask_light.Width / 2); int v2 = mask_light.At(i + 1, mask_light.Width / 2); if ((v1 == 255 && v2 == 0) || (v1 == 0 && v2 == 255)) { SplitListB.Add(i); } } } SplitListB.Sort(); for (int h = SplitListB.Count - 1; h >= 1; h--) { if (Math.Abs(SplitListB[h] - SplitListB[h - 1]) > 5) { continue; } SplitListB.RemoveAt(h); } //Cv2.ImWrite(@"C:\Users\zyh\Desktop\mask_dark.jpg", mask_dark); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\mask_light.jpg", mask_light); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\a+b.jpg", mask_dark+mask_light); if (!SplitListB.Contains(0)) SplitListB.Insert(0, 0); if (!SplitListB.Contains(gray.Height)) SplitListB.Add(gray.Height); return SplitListB; } public static List LoopMiddlePic(Mat originGray, Mat gray, Vec4b vec4B, int top, int bottom, int i) { List arrs = new List(); //截取中间的,进行再次寻找 var centerA = gray.Width / 2 - 100; Mat temp1 = new Mat(gray, new Rect(centerA, top, 200, bottom - top)); //判断是否是亮的 int mean = (int)Cv2.Mean(temp1); if(mean>120) { temp1 = new Mat(originGray, new Rect(centerA, top, 200, bottom - top)); } /*else { //对比度拉伸 double min, max; Cv2.MinMaxIdx(temp1, out min, out max); for (int h = 0; h < temp1.Height; h++) { for (int w = 0; w < temp1.Width; w++) { temp1.Set(h, w, (byte)((temp1.At(h, w) - min) * 255 / (max - min))); } } }*/ /*Mat edge = new Mat(); Cv2.Canny(temp1, edge, 0, 80); int nums = Cv2.CountNonZero(edge); Cv2.ImWrite(@"C:\Users\zyh\Desktop\edge" + i + ".jpg", edge); if (nums * 1f / (temp1.Width* temp1.Height) < 0.05) continue;*/ Mat mask_temp1 = new Mat(temp1.Size(), temp1.Type(), Scalar.All(0)); Mat mask_temp2 = new Mat(temp1.Size(), temp1.Type(), Scalar.All(0)); double thresh_a = Cv2.Threshold(temp1, new Mat(), 0, 255, ThresholdTypes.Otsu); double thresh_b = Cv2.Threshold(temp1, new Mat(), 0, 255, ThresholdTypes.Triangle); double thresh1 = (thresh_a < thresh_b ? thresh_a : thresh_b) + 1; //对temp1进行加强 temp1 = Tools.adaptEdgeEnhancement(temp1, 11, 0); //InputArray kernel = InputArray.Create(new int[1, 11] { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }); //Cv2.MorphologyEx(temp1, temp1, MorphTypes.Open, kernel, null, 5); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\grayOrigin.jpg", grayOrigin); for (int h = 0; h < temp1.Height; h++) { for (int w = 0; w < temp1.Width; w++) { int v = temp1.At(h, w); if (v <= thresh1) mask_temp1.Set(h, w, 255); if (v > thresh1 + 6) mask_temp2.Set(h, w, 255); } } //去碎屑 mask_temp1 = BinaryTools.SingleChannelDebrisRemoval(mask_temp1, 100); //空洞填充 mask_temp1 = BinaryTools.SingleChannelHoleFilling(mask_temp1, vec4B); //去碎屑 mask_temp2 = BinaryTools.SingleChannelDebrisRemoval(mask_temp2, 100); //空洞填充 mask_temp2 = BinaryTools.SingleChannelHoleFilling(mask_temp2, vec4B); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\temp_origin_" + i + ".jpg", temp1); //Cv2.ImWrite(@"C:\Users\zyh\Desktop\temp_mask_" + i + ".jpg", mask_temp1); //循环所有联通区域,找到边 Mat labels_left_1 = new Mat(); Mat stats_left_1 = new Mat(); Mat centroids_left_1 = new Mat(); //连通域数量 int num_1 = Cv2.ConnectedComponentsWithStats(mask_temp1, labels_left_1, stats_left_1, centroids_left_1, PixelConnectivity.Connectivity8); for (int j = 1; j < stats_left_1.Height; j++) { int x = stats_left_1.At(j, 0); int y = stats_left_1.At(j, 1); int width = stats_left_1.At(j, 2); int height = stats_left_1.At(j, 3); int area = stats_left_1.At(j, 4); //使用均值判断是否是亮的区域 //如果y 或者 y+height 的行或者相近行不为0的数量>180 if (width == mask_temp1.Width) { if (height >= 30) { int first = -1; int end = -1; for (int a = y; a < y + height; a++) { if (mask_temp1.Row[a].CountNonZero() > mask_temp1.Width * 0.95) { if (first == -1) first = a; end = a; } } int ft = first + top; int et = end + top; if (Math.Abs(ft - top) > 14 && Math.Abs(ft - bottom) > 14) arrs.Add(ft); if (Math.Abs(et - top) > 14 && Math.Abs(et - bottom) > 14) arrs.Add(et); /* if(mask_temp1.Row[y+20].CountNonZero()> mask_temp1.Width*0.8) arrs.Add(y + SplitListB[i]); if (mask_temp1.Row[y+ height-20].CountNonZero() > mask_temp1.Width * 0.8) arrs.Add(y + height + SplitListB[i]);*/ } else { int tempV = y + height / 2 + top; if (Math.Abs(tempV-top)>14 && Math.Abs(tempV - bottom)> 14) arrs.Add(y + height / 2 + top); } } } //需要判断是否是不是一个比较亮的,就不需要强行找了 if(mean > 120 && arrs.Count<=1) { Mat temp_light = new Mat(originGray, new Rect(centerA, top, 200, bottom - top)); Mat mask_temp3 = new Mat(temp1.Size(), temp1.Type(), Scalar.All(0)); for (int h = 0; h < temp_light.Height; h++) { for (int w = 0; w < temp_light.Width; w++) { int v = temp_light.At(h, w); if (v <= thresh_a) mask_temp3.Set(h, w, 255); } } //Cv2.ImWrite(@"C:\Users\zyh\Desktop\mask_temp3_" + i + ".jpg", mask_temp3); for (int h=10; h< mask_temp3.Height-10; h++) { if (mask_temp3.Row[h].CountNonZero() > mask_temp3.Width*0.6) { int tempV = h + top; if (Math.Abs(tempV - top) > 14 && Math.Abs(tempV - bottom) > 14) arrs.Add(tempV); } } } /*labels_left_1 = new Mat(); stats_left_1 = new Mat(); centroids_left_1 = new Mat(); int num_2 = Cv2.ConnectedComponentsWithStats(mask_temp2, labels_left_1, stats_left_1, centroids_left_1, PixelConnectivity.Connectivity8); for (int j = 1; j < stats_left_1.Height; j++) { int x = stats_left_1.At(j, 0); int y = stats_left_1.At(j, 1); int width = stats_left_1.At(j, 2); int height = stats_left_1.At(j, 3); int area = stats_left_1.At(j, 4); //如果y 或者 y+height 的行或者相近行不为0的数量>180 if (width == mask_temp2.Width) { if (height >= 30) { first = -1; end = -1; for (int a = y; a < y + height; a++) { if (mask_temp2.Row[a].CountNonZero() > mask_temp2.Width * 0.95) { if (first == -1) first = a; end = a; } } arrs.Add(first + SplitListB[i]); arrs.Add(end + SplitListB[i]); *//* if(mask_temp1.Row[y+20].CountNonZero()> mask_temp1.Width*0.8) arrs.Add(y + SplitListB[i]); if (mask_temp1.Row[y+ height-20].CountNonZero() > mask_temp1.Width * 0.8) arrs.Add(y + height + SplitListB[i]);*//* } else { arrs.Add(y + height / 2 + SplitListB[i]); } } }*/ return arrs; } } }