123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- 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
- {
- /// <summary>
- /// 判断是否进行图像增强
- /// 获取直方图,判断第一个峰的像素个数如果占全图的百分之八十以上,则不增强,否则增强
- /// </summary>
- /// <param name="gray"></param>
- /// <returns></returns>
- public static bool CalcEnhanceFlag(Mat gray)
- {
- float[] hist_float = HistTools.CalcHist(gray);
- //直方图平滑
- int[] hist_int = HistTools.Smooth(hist_float, 20);
- List<int> mountainsList = new List<int>();
- List<int[]> mountainsArrList = new List<int[]>();
- List<int[]> mountainsArrListBackUp = new List<int[]>();
- Tools.FindTopAndBetweenWithOutWT123(hist_int, 0, 255, mountainsList, mountainsArrList, mountainsArrListBackUp, new List<string>(), 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;
- }
- /// <summary>
- /// 使用两次阈值寻找线
- /// </summary>
- /// <param name="gray"></param>
- /// <returns></returns>
- public static List<int> CalcDarkOrLight(Mat gray, Vec4b vec4B)
- {
- List<int> SplitListB = new List<int>();
-
- 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<byte>(h, w);
- if (v <= thresh)
- mask_dark.Set<byte>(h, w, 255);
- if (v >= 105)
- mask_light.Set<byte>(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<byte>(i, mask_dark.Width / 2);
- int v2 = mask_dark.At<byte>(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<int>(j, 0);
- int y = stats_light.At<int>(j, 1);
- int width = stats_light.At<int>(j, 2);
- int height = stats_light.At<int>(j, 3);
- int area = stats_light.At<int>(j, 4);
- if (width == mask_light.Width)
- {
- if (abc == -1) abc = j;
- all++;
- }
- }
- if (all >= 3) mask_light[stats_light.At<int>(abc, 1), stats_light.At<int>(abc, 3) + stats_light.At<int>(abc, 1),
- stats_light.At<int>(abc, 0), stats_light.At<int>(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<byte>(i, mask_light.Width / 2);
- int v2 = mask_light.At<byte>(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<int> LoopMiddlePic(Mat originGray, Mat gray, Vec4b vec4B, int top, int bottom, int i)
- {
- List<int> arrs = new List<int>();
- //截取中间的,进行再次寻找
- 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<byte>(h, w, (byte)((temp1.At<byte>(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<int>(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<byte>(h, w);
- if (v <= thresh1)
- mask_temp1.Set<byte>(h, w, 255);
- if (v > thresh1 + 6)
- mask_temp2.Set<byte>(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<int>(j, 0);
- int y = stats_left_1.At<int>(j, 1);
- int width = stats_left_1.At<int>(j, 2);
- int height = stats_left_1.At<int>(j, 3);
- int area = stats_left_1.At<int>(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<byte>(h, w);
- if (v <= thresh_a)
- mask_temp3.Set<byte>(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<int>(j, 0);
- int y = stats_left_1.At<int>(j, 1);
- int width = stats_left_1.At<int>(j, 2);
- int height = stats_left_1.At<int>(j, 3);
- int area = stats_left_1.At<int>(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;
- }
- }
- }
|