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;
}
}
}