using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SmartCoalApplication.Base.CommTool
{
///
/// 防焊的图像预处理
///
public class FangHanTools
{
///
/// 二值化右侧的值
///
public static int rightV = 0;
///
/// 二值化mat
///
public static Mat mat_er, final, mat_er1;
///
/// 颜色
///
public static Vec4b vec4B = new Vec4b(255, 0, 0, 255);
public unsafe static Mat RemoveCircle(Mat srcImage)
{
Mat gray = null;
try
{
Mat clone = srcImage.Clone();
gray = srcImage.CvtColor(ColorConversionCodes.BGR2GRAY);
//计算灰度平均值
Scalar mean_rgb = srcImage.Mean();
Scalar mean = gray.Mean(gray);
//计算直方图
float[] hist_float = HistTools.CalcHist(gray);
List contoursAll = new List();
//循环直方图数据
//for (int i = 0; i < mean[0]; i += 2)
//{
// if (hist_float[i] > 0)
// {
// rightV = i;
// ////进行二值
// //mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
// //gray.ForEachAsByte(GrayForEachAsByte);
// //Cv2.ImWrite(@"C:\Users\54434\Desktop\gray_0\_" + rightV + ".png", mat_er);
// ////去除边界对象
// ////mat_er = BinaryTools.DeleteContours_New(mat_er);
// ////去碎屑
// //mat_er = BinaryTools.DebrisRemoval_New(mat_er);
// ////空洞填充
// //mat_er = BinaryTools.HoleFilling_NewWithView(mat_er, vec4B);
// //Cv2.Dilate(mat_er, mat_er, null, null, 4);
// //mat_er1 = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY);
// //mat_er1 = ~mat_er1;
// ////然后寻找轮廓
// //OpenCvSharp.Point[][] contours;
// //HierarchyIndex[] hierachy;
// //Cv2.FindContours(mat_er1, out contours, out hierachy, RetrievalModes.CComp, ContourApproximationModes.ApproxNone);
// ////然后找近似圆的
// //if (contours.Length > 0)
// //{
// // int p = 0;
// // foreach (OpenCvSharp.Point[] ps in contours)
// // {
// // if (hierachy[p].Parent == -1 && !BinaryTools.WithinContour(contoursAll, ps) && BinaryTools.CalcNodularity(ps) > 0.75)
// // {
// // contoursAll.Add(ps);
// // }
// // p++;
// // }
// //}
// }
//}
//使用轮廓在空白图上绘制并填充,然后腐蚀
mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0));
Cv2.FillPoly(mat_er, contoursAll, new Scalar(255), LineTypes.Link4);
//Cv2.ImWrite(@"C:\Users\54434\Desktop\切片temp\防焊 - 测试图片 另一批\防焊 - 测试图片\undercut沒有開口\1 (2)_2.JPG", mat_er);
mat_er = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY);
//对结果图进行二值提取和空洞填充
//进行二值
final = new Mat(mat_er.Rows, mat_er.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 255));
mat_er.ForEachAsByte(GrayForEachAsByte_final);
//空洞填充
final = BinaryTools.HoleFilling_NewWithView(final, vec4B);
//反色
final = final.CvtColor(ColorConversionCodes.BGR2GRAY);
//膨胀
Cv2.Erode(final, final, null, null, 6);
for (int h = 0; h < final.Height; h++)
{
for (int w = 0; w < final.Width; w++)
{
if (final.At(h, w) < 255)
clone.Set(h, w, new Vec4b((byte)mean_rgb[0], (byte)mean_rgb[1], (byte)mean_rgb[2], 255));
}
}
return clone;
}
catch(Exception)
{
}
finally
{
if(mat_er!=null && !mat_er.IsDisposed)
{
mat_er.Dispose();
mat_er = null;
}
if (final != null && !final.IsDisposed)
{
final.Dispose();
final = null;
}
if (gray != null && !gray.IsDisposed)
{
gray.Dispose();
gray = null;
}
rightV = 0;
System.GC.Collect();
}
return srcImage;
}
public unsafe static Mat RemoveCircle(Mat srcImage, out int mean0, out Scalar mean_rgb)
{
Mat gray = null;
mean0 = 0; mean_rgb = new Scalar();
try
{
Mat clone = srcImage.Clone();
gray = srcImage.CvtColor(ColorConversionCodes.BGR2GRAY);
//计算灰度平均值
/*Scalar */mean_rgb = srcImage.Mean();
Scalar mean = gray.Mean(gray);
//计算直方图
float[] hist_float = HistTools.CalcHist(gray);
List contoursAll = new List();
mean0 = (int)mean[0];
//循环直方图数据
//for (int i = 0; i < mean[0]; i += 2)
//{
// if (hist_float[i] > 0)
// {
// rightV = i;
// ////进行二值
// //mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
// //gray.ForEachAsByte(GrayForEachAsByte);
// //Cv2.ImWrite(@"C:\Users\54434\Desktop\gray_0\_" + rightV + ".png", mat_er);
// ////去除边界对象
// ////mat_er = BinaryTools.DeleteContours_New(mat_er);
// ////去碎屑
// //mat_er = BinaryTools.DebrisRemoval_New(mat_er);
// ////空洞填充
// //mat_er = BinaryTools.HoleFilling_NewWithView(mat_er, vec4B);
// //Cv2.Dilate(mat_er, mat_er, null, null, 4);
// //mat_er1 = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY);
// //mat_er1 = ~mat_er1;
// ////然后寻找轮廓
// //OpenCvSharp.Point[][] contours;
// //HierarchyIndex[] hierachy;
// //Cv2.FindContours(mat_er1, out contours, out hierachy, RetrievalModes.CComp, ContourApproximationModes.ApproxNone);
// ////然后找近似圆的
// //if (contours.Length > 0)
// //{
// // int p = 0;
// // foreach (OpenCvSharp.Point[] ps in contours)
// // {
// // if (hierachy[p].Parent == -1 && !BinaryTools.WithinContour(contoursAll, ps) && BinaryTools.CalcNodularity(ps) > 0.75)
// // {
// // contoursAll.Add(ps);
// // }
// // p++;
// // }
// //}
// }
//}
//使用轮廓在空白图上绘制并填充,然后腐蚀
mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0));
Cv2.FillPoly(mat_er, contoursAll, new Scalar(255), LineTypes.Link4);
//Cv2.ImWrite(@"C:\Users\54434\Desktop\切片temp\防焊 - 测试图片 另一批\防焊 - 测试图片\undercut沒有開口\1 (2)_2.JPG", mat_er);
mat_er = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY);
//对结果图进行二值提取和空洞填充
//进行二值
final = new Mat(mat_er.Rows, mat_er.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 255));
mat_er.ForEachAsByte(GrayForEachAsByte_final);
//空洞填充
final = BinaryTools.HoleFilling_NewWithView(final, vec4B);
//反色
final = final.CvtColor(ColorConversionCodes.BGR2GRAY);
//膨胀
Cv2.Erode(final, final, null, null, 6);
for (int h = 0; h < final.Height; h++)
{
for (int w = 0; w < final.Width; w++)
{
if (final.At(h, w) < 255)
clone.Set(h, w, new Vec4b((byte)mean_rgb[0], (byte)mean_rgb[1], (byte)mean_rgb[2], 255));
}
}
return clone;
}
catch (Exception)
{
}
finally
{
if (mat_er != null && !mat_er.IsDisposed)
{
mat_er.Dispose();
mat_er = null;
}
if (final != null && !final.IsDisposed)
{
final.Dispose();
final = null;
}
if (gray != null && !gray.IsDisposed)
{
gray.Dispose();
gray = null;
}
rightV = 0;
System.GC.Collect();
}
return srcImage;
}
public unsafe static Mat RemoveCircle(Mat srcImage, int mean0, Scalar mean_rgb, out bool foundCircle)
{
Mat gray = null;
foundCircle = false;
//mean0 = 0;
try
{
Mat clone = srcImage.Clone();
gray = srcImage.CvtColor(ColorConversionCodes.BGR2GRAY);
////计算灰度平均值
//Scalar mean_rgb = srcImage.Mean();
//Scalar mean = gray.Mean(gray);
//计算直方图
float[] hist_float = HistTools.CalcHist(gray);
List contoursAll = new List();
//mean0 = (int)mean[0];
//循环直方图数据
for (int i = 0; i < mean0/*mean[0]*/; i += 2)
{
if (hist_float[i] > 0)
{
rightV = i;
//进行二值
mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 0));
gray.ForEachAsByte(GrayForEachAsByte);
//Cv2.ImWrite(@"C:\Users\54434\Desktop\gray_0\_" + rightV + ".png", mat_er);
//去除边界对象
//mat_er = BinaryTools.DeleteContours_New(mat_er);
//去碎屑
mat_er = BinaryTools.DebrisRemoval_New(mat_er);
//空洞填充
mat_er = BinaryTools.HoleFilling_NewWithView(mat_er, vec4B);
Cv2.Dilate(mat_er, mat_er, null, null, 4);
mat_er1 = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY);
mat_er1 = ~mat_er1;
//然后寻找轮廓
OpenCvSharp.Point[][] contours;
HierarchyIndex[] hierachy;
Cv2.FindContours(mat_er1, out contours, out hierachy, RetrievalModes.CComp, ContourApproximationModes.ApproxNone);
//然后找近似圆的
if (contours.Length > 0)
{
int p = 0;
foreach (OpenCvSharp.Point[] ps in contours)
{
if (hierachy[p].Parent == -1 && !BinaryTools.WithinContour(contoursAll, ps) && BinaryTools.CalcNodularity(ps) > 0.75)
{
contoursAll.Add(ps);
}
p++;
}
}
}
}
//使用轮廓在空白图上绘制并填充,然后腐蚀
mat_er = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC4, new Scalar(0));
Cv2.FillPoly(mat_er, contoursAll, new Scalar(255), LineTypes.Link4);
//Cv2.ImWrite(@"C:\Users\54434\Desktop\切片temp\防焊 - 测试图片 另一批\防焊 - 测试图片\undercut沒有開口\1 (2)_2.JPG", mat_er);
mat_er = mat_er.CvtColor(ColorConversionCodes.BGR2GRAY);
//对结果图进行二值提取和空洞填充
//进行二值
final = new Mat(mat_er.Rows, mat_er.Cols, MatType.CV_8UC4, new Scalar(0, 0, 0, 255));
mat_er.ForEachAsByte(GrayForEachAsByte_final);
//空洞填充
final = BinaryTools.HoleFilling_NewWithView(final, vec4B);
//反色
final = final.CvtColor(ColorConversionCodes.BGR2GRAY);
//膨胀
Cv2.Erode(final, final, null, null, 6);
for (int h = 0; h < final.Height; h++)
{
for (int w = 0; w < final.Width; w++)
{
if (final.At(h, w) < 255)
{
if (!foundCircle) foundCircle = true;
break;
//clone.Set(h, w, new Vec4b((byte)mean_rgb[0], (byte)mean_rgb[1], (byte)mean_rgb[2], 255));
}
}
if (foundCircle)
{
break;
}
}
return foundCircle ? final.Clone() : clone;
}
catch (Exception)
{
}
finally
{
if (mat_er != null && !mat_er.IsDisposed)
{
mat_er.Dispose();
mat_er = null;
}
if (final != null && !final.IsDisposed)
{
final.Dispose();
final = null;
}
if (gray != null && !gray.IsDisposed)
{
gray.Dispose();
gray = null;
}
rightV = 0;
System.GC.Collect();
}
return srcImage;
}
private unsafe static void GrayForEachAsByte_final(byte* value, int* position)
{
int y = position[0];
int x = position[1];
byte v = *value;
if (v > 0)
{
final.Set(y, x, vec4B);
}
}
private unsafe static void GrayForEachAsByte(byte* value, int* position)
{
int y = position[0];
int x = position[1];
byte v = *value;
if (v > 0 && v <= rightV)
{
mat_er.Set(y, x, vec4B);
}
/*else
{
mat_er.Set(y, x, new Vec4b(0,0,0,0));
}*/
}
}
}