2024-06-11 11:40:47 +08:00
|
|
|
|
using OpenCvSharp;
|
2024-06-28 17:50:44 +08:00
|
|
|
|
using Sunny.UI.Win32;
|
2024-06-11 11:40:47 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Security.Cryptography;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
2024-07-01 11:39:19 +08:00
|
|
|
|
using static System.Net.Mime.MediaTypeNames;
|
2024-06-11 11:40:47 +08:00
|
|
|
|
using Point = OpenCvSharp.Point;
|
|
|
|
|
using Size = OpenCvSharp.Size;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace HisenceYoloDetection
|
|
|
|
|
{
|
2024-06-28 17:50:44 +08:00
|
|
|
|
public static class CheckDiffSciHelper
|
2024-06-11 11:40:47 +08:00
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="path1">标准图像</param>
|
|
|
|
|
/// <param name="path2">要对比的图像</param>
|
|
|
|
|
/// <param name="IfWhiteWord"> 白板黑字为true </param>
|
|
|
|
|
/// <param name="saveDir">存储路径</param>
|
2024-06-27 18:09:39 +08:00
|
|
|
|
public static bool CheckDiffSci(string path1, Mat MatDet, Rect sqlrect, Rect detrect, bool IfWhiteWord, string saveDir)
|
2024-06-11 11:40:47 +08:00
|
|
|
|
{
|
2024-07-01 11:33:35 +08:00
|
|
|
|
// 读取和处理第一张图片。。
|
2024-06-11 11:40:47 +08:00
|
|
|
|
Mat img1 = Cv2.ImRead(path1, ImreadModes.Color);
|
|
|
|
|
if (img1.Empty())
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"Error loading image {path1}");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2024-06-28 17:50:44 +08:00
|
|
|
|
// Cv2.Resize(img1, img1, new Size(550, 270));
|
2024-06-11 11:40:47 +08:00
|
|
|
|
Mat gimg1 = new Mat();
|
|
|
|
|
Cv2.CvtColor(img1, gimg1, ColorConversionCodes.BGR2GRAY);
|
|
|
|
|
Mat thr1 = new Mat();
|
2024-06-27 18:09:39 +08:00
|
|
|
|
|
|
|
|
|
if (IfWhiteWord)
|
2024-06-11 11:40:47 +08:00
|
|
|
|
{
|
2024-06-27 18:09:39 +08:00
|
|
|
|
Cv2.Threshold(gimg1, thr1, 0, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu);
|
2024-06-11 11:40:47 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Cv2.Threshold(gimg1, thr1, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-28 17:50:44 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-06-11 11:40:47 +08:00
|
|
|
|
// 读取和处理第二张图片
|
|
|
|
|
Mat img2 = MatDet.Clone();
|
|
|
|
|
if (img2.Empty())
|
|
|
|
|
{
|
2024-06-28 17:50:44 +08:00
|
|
|
|
// Console.WriteLine($"Error loading image {path2}");
|
2024-06-11 11:40:47 +08:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2024-06-28 17:50:44 +08:00
|
|
|
|
// Cv2.Resize(img2, img2, new Size(550, 270));
|
2024-06-11 11:40:47 +08:00
|
|
|
|
Mat gimg2 = new Mat();
|
|
|
|
|
Cv2.CvtColor(img2, gimg2, ColorConversionCodes.BGR2GRAY);
|
|
|
|
|
Mat thr2 = new Mat();
|
2024-06-28 17:50:44 +08:00
|
|
|
|
//Cv2.Threshold(gimg2, thr2, 0, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu);
|
2024-06-11 11:40:47 +08:00
|
|
|
|
if (IfWhiteWord)
|
|
|
|
|
{
|
|
|
|
|
Cv2.Threshold(gimg2, thr2, 0, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Cv2.Threshold(gimg2, thr2, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-28 17:50:44 +08:00
|
|
|
|
|
|
|
|
|
//Rect area2 = new Rect(148,30,229,222);
|
2024-06-11 11:40:47 +08:00
|
|
|
|
sqlrect.Width += 20;
|
2024-06-28 17:50:44 +08:00
|
|
|
|
sqlrect.Height += 60;
|
2024-06-11 11:40:47 +08:00
|
|
|
|
detrect.Width += 20;
|
2024-06-28 17:50:44 +08:00
|
|
|
|
detrect.Height += 60;
|
2024-06-11 11:40:47 +08:00
|
|
|
|
Mat matCutblack1 = new Mat(thr1, sqlrect);
|
2024-06-28 17:50:44 +08:00
|
|
|
|
if (IfWhiteWord)
|
|
|
|
|
{
|
|
|
|
|
matCutblack1.SetTo(Scalar.Black);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
matCutblack1.SetTo(Scalar.Black);
|
|
|
|
|
}
|
2024-06-11 11:40:47 +08:00
|
|
|
|
Mat matCutblack2 = new Mat(thr2, detrect);
|
2024-06-28 17:50:44 +08:00
|
|
|
|
if (IfWhiteWord)
|
|
|
|
|
{
|
|
|
|
|
matCutblack2.SetTo(Scalar.Black);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
matCutblack2.SetTo(Scalar.Black);
|
|
|
|
|
}
|
2024-06-17 11:02:28 +08:00
|
|
|
|
Cv2.Resize(thr1, thr1, new Size(550, 270));
|
|
|
|
|
Cv2.Resize(thr2, thr2, new Size(550, 270));
|
2024-06-27 18:09:39 +08:00
|
|
|
|
DateTime dt = DateTime.Now;
|
2024-06-28 17:50:44 +08:00
|
|
|
|
string filename = dt.Year.ToString() + dt.Month.ToString() + dt.Day.ToString() + dt.Hour.ToString() + dt.Minute.ToString() + dt.Millisecond.ToString();
|
2024-06-27 18:09:39 +08:00
|
|
|
|
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//string savePath4 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + filename + "_thr1.png");
|
|
|
|
|
//// 保存结果
|
2024-06-28 17:50:44 +08:00
|
|
|
|
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//Cv2.ImWrite(savePath4, thr1);
|
|
|
|
|
//string savePath3 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + filename + "_thr2.png");
|
|
|
|
|
//// 保存结果
|
2024-06-28 17:50:44 +08:00
|
|
|
|
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//Cv2.ImWrite(savePath3, thr2);
|
2024-06-11 11:40:47 +08:00
|
|
|
|
|
2024-06-28 17:50:44 +08:00
|
|
|
|
// 创建卷积核
|
|
|
|
|
Mat filter1 = new Mat(15, 15, MatType.CV_32F, new Scalar(0));
|
|
|
|
|
filter1.Row(7).SetTo(new Scalar(0.025));
|
|
|
|
|
filter1.Col(7).SetTo(new Scalar(0.025));
|
|
|
|
|
|
|
|
|
|
// 应用卷积
|
2024-06-11 11:40:47 +08:00
|
|
|
|
Mat final_result1 = new Mat();
|
2024-06-28 17:50:44 +08:00
|
|
|
|
Cv2.Filter2D(thr1, final_result1, -1, filter1, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
Cv2.Filter2D(final_result1, final_result1, -1, filter1, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
Cv2.Filter2D(final_result1, final_result1, -1, filter1, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
|
2024-06-11 11:40:47 +08:00
|
|
|
|
Mat final_result2 = new Mat();
|
2024-06-28 17:50:44 +08:00
|
|
|
|
Cv2.Filter2D(thr2, final_result2, -1, filter1, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
Cv2.Filter2D(final_result2, final_result2, -1, filter1, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
Cv2.Filter2D(final_result2, final_result2, -1, filter1, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
//裁剪才行
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//string savePath2 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + "_final_result1.png");
|
|
|
|
|
//// 保存结果
|
|
|
|
|
////string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
|
|
|
|
|
//Cv2.ImWrite(savePath2, final_result1);
|
|
|
|
|
//string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + "_final_result2.png");
|
|
|
|
|
//// 保存结果
|
|
|
|
|
////string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
|
|
|
|
|
//Cv2.ImWrite(savePath, final_result2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-06-11 11:40:47 +08:00
|
|
|
|
|
|
|
|
|
// 计算图像差异
|
|
|
|
|
Mat devIMG = new Mat();
|
|
|
|
|
Mat devIMG_ = new Mat();
|
|
|
|
|
Cv2.Subtract(final_result1, final_result2, devIMG);
|
|
|
|
|
Cv2.Subtract(final_result2, final_result1, devIMG_);
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//string savePathd = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + filename + "devIMG.png");
|
|
|
|
|
//// 保存结果
|
2024-06-28 17:50:44 +08:00
|
|
|
|
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//Cv2.ImWrite(savePathd, devIMG);
|
|
|
|
|
//string savePathd1 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + filename + "devIMG_.png");
|
|
|
|
|
//// 保存结果
|
2024-06-11 11:40:47 +08:00
|
|
|
|
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//Cv2.ImWrite(savePathd1, devIMG_);
|
2024-06-11 11:40:47 +08:00
|
|
|
|
// 对差异图像应用阈值
|
2024-06-28 17:50:44 +08:00
|
|
|
|
Cv2.Threshold(devIMG, devIMG, 20, 255, ThresholdTypes.Binary);
|
|
|
|
|
Cv2.Threshold(devIMG_, devIMG_, 20, 255, ThresholdTypes.Binary);
|
2024-06-11 11:40:47 +08:00
|
|
|
|
|
|
|
|
|
// 结合差异
|
|
|
|
|
Mat sumIMG = new Mat();
|
|
|
|
|
Cv2.Add(devIMG, devIMG_, sumIMG);
|
|
|
|
|
|
2024-06-28 17:50:44 +08:00
|
|
|
|
// 应用形态学操作
|
2024-06-11 11:40:47 +08:00
|
|
|
|
Mat kernelCL = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3));
|
|
|
|
|
Mat blackhatImg = new Mat();
|
2024-06-28 17:50:44 +08:00
|
|
|
|
Cv2.Dilate(sumIMG, blackhatImg, kernelCL);
|
2024-06-11 11:40:47 +08:00
|
|
|
|
|
2024-06-28 17:50:44 +08:00
|
|
|
|
// 处理轮廓和保存结果
|
|
|
|
|
Point[][] contours = new Point[10000][];
|
2024-06-11 11:40:47 +08:00
|
|
|
|
Cv2.FindContours(blackhatImg, out contours, out _, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple);
|
|
|
|
|
bool isMatch = true;
|
|
|
|
|
foreach (var contour in contours)
|
|
|
|
|
{
|
2024-06-28 17:50:44 +08:00
|
|
|
|
if (Cv2.ContourArea(contour) <= 500)
|
2024-06-11 11:40:47 +08:00
|
|
|
|
{
|
|
|
|
|
Cv2.DrawContours(blackhatImg, new Point[][] { contour }, -1, Scalar.Black, thickness: Cv2.FILLED);
|
2024-06-28 17:50:44 +08:00
|
|
|
|
// 框选轮廓
|
2024-07-01 11:39:19 +08:00
|
|
|
|
string savePath2 = Path.Combine("D:\\Hisence\\Test\\2\\ng", Path.GetFileNameWithoutExtension(path1) + filename + "_Rect.png");
|
|
|
|
|
// 保存结果
|
|
|
|
|
//string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
|
|
|
|
|
Cv2.ImWrite(savePath2, img2);
|
|
|
|
|
string savePath = Path.Combine("D:\\Hisence\\Test\\2\\ng", Path.GetFileNameWithoutExtension(path1) + filename + "_diff.png");
|
|
|
|
|
// 保存结果
|
|
|
|
|
//string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
|
|
|
|
|
Cv2.ImWrite(savePath, blackhatImg);
|
2024-06-11 11:40:47 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Rect boundingRect = Cv2.BoundingRect(contour);
|
|
|
|
|
Cv2.Rectangle(img2, boundingRect, Scalar.Red, thickness: 2);
|
2024-06-27 18:09:39 +08:00
|
|
|
|
isMatch = false;
|
2024-07-01 11:39:19 +08:00
|
|
|
|
string savePath2 = Path.Combine("D:\\Hisence\\Test\\2\\ok", Path.GetFileNameWithoutExtension(path1) + filename + "_Rect.png");
|
|
|
|
|
// 保存结果
|
|
|
|
|
//string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
|
|
|
|
|
Cv2.ImWrite(savePath2, img2);
|
|
|
|
|
string savePath = Path.Combine("D:\\Hisence\\Test\\2\\ok", Path.GetFileNameWithoutExtension(path1) + filename + "_diff.png");
|
|
|
|
|
// 保存结果
|
|
|
|
|
//string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
|
|
|
|
|
Cv2.ImWrite(savePath, blackhatImg);
|
2024-06-11 11:40:47 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-01 11:39:19 +08:00
|
|
|
|
|
2024-06-11 11:40:47 +08:00
|
|
|
|
return isMatch;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-27 18:09:39 +08:00
|
|
|
|
|
2024-06-28 17:50:44 +08:00
|
|
|
|
|
2024-06-11 11:40:47 +08:00
|
|
|
|
public static Rect strChangeRect(string strrect)
|
|
|
|
|
{
|
2024-06-17 11:02:28 +08:00
|
|
|
|
if (!string.IsNullOrEmpty(strrect))
|
|
|
|
|
{
|
|
|
|
|
string[] rectstr = strrect.Split(",");
|
|
|
|
|
int areaX = int.Parse(rectstr[0]);
|
|
|
|
|
int areaY = int.Parse(rectstr[1]);
|
|
|
|
|
int areaWidth = int.Parse(rectstr[2]);
|
|
|
|
|
int areaHeight = int.Parse(rectstr[3]);
|
|
|
|
|
|
|
|
|
|
Rect rect = new Rect(areaX, areaY, areaWidth, areaHeight);
|
|
|
|
|
return rect;
|
2024-06-28 17:50:44 +08:00
|
|
|
|
}
|
|
|
|
|
else
|
2024-06-17 11:02:28 +08:00
|
|
|
|
{
|
2024-06-28 17:50:44 +08:00
|
|
|
|
return new Rect(0, 0, 0, 0);
|
2024-06-17 11:02:28 +08:00
|
|
|
|
}
|
2024-06-28 17:50:44 +08:00
|
|
|
|
|
2024-06-11 11:40:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-06-28 17:50:44 +08:00
|
|
|
|
public static string rectChangeStr(Rect area)
|
2024-06-11 11:40:47 +08:00
|
|
|
|
{
|
|
|
|
|
string[] rectsql = new string[4];
|
|
|
|
|
rectsql[0] = Convert.ToString(area.X);
|
|
|
|
|
rectsql[1] = Convert.ToString(area.Y);
|
|
|
|
|
rectsql[2] = Convert.ToString(area.Width);
|
|
|
|
|
rectsql[3] = Convert.ToString(area.Height);
|
|
|
|
|
|
|
|
|
|
string strrect = rectsql.Join(",");
|
|
|
|
|
return strrect;
|
|
|
|
|
}
|
2024-06-28 17:50:44 +08:00
|
|
|
|
public static class CheckDiffSciHelper1
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="path1">标准图像</param>
|
|
|
|
|
/// <param name="path2">要对比的图像</param>
|
|
|
|
|
/// <param name="IfWhiteWord"> 白板黑字为true </param>
|
|
|
|
|
/// <param name="saveDir">存储路径</param>
|
|
|
|
|
public static bool CheckDiffSci(string path1, Mat MatDet, Rect sqlrect, Rect detrect, bool IfWhiteWord, string saveDir)
|
|
|
|
|
{
|
|
|
|
|
// 读取和处理第一张图片
|
|
|
|
|
Mat img1 = Cv2.ImRead(path1, ImreadModes.Color);
|
|
|
|
|
if (img1.Empty())
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"Error loading image {path1}");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// Cv2.Resize(img1, img1, new Size(550, 270));
|
|
|
|
|
Mat gimg1 = new Mat();
|
|
|
|
|
Cv2.CvtColor(img1, gimg1, ColorConversionCodes.BGR2GRAY);
|
|
|
|
|
Mat thr1 = new Mat();
|
|
|
|
|
|
|
|
|
|
if (IfWhiteWord)
|
|
|
|
|
{
|
|
|
|
|
Cv2.Threshold(gimg1, thr1, 0, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Cv2.Threshold(gimg1, thr1, 100, 255, ThresholdTypes.Binary );//| ThresholdTypes.Otsu
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 读取和处理第二张图片
|
|
|
|
|
Mat img2 = MatDet.Clone();
|
|
|
|
|
if (img2.Empty())
|
|
|
|
|
{
|
|
|
|
|
// Console.WriteLine($"Error loading image {path2}");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// Cv2.Resize(img2, img2, new Size(550, 270));
|
|
|
|
|
Mat gimg2 = new Mat();
|
|
|
|
|
Cv2.CvtColor(img2, gimg2, ColorConversionCodes.BGR2GRAY);
|
|
|
|
|
Mat thr2 = new Mat();
|
|
|
|
|
//Cv2.Threshold(gimg2, thr2, 0, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu);
|
|
|
|
|
if (IfWhiteWord)
|
|
|
|
|
{
|
|
|
|
|
Cv2.Threshold(gimg2, thr2, 0, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Cv2.Threshold(gimg2, thr2, 100, 255, ThresholdTypes.Binary );//| ThresholdTypes.Otsu
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Rect area2 = new Rect(148,30,229,222);
|
|
|
|
|
sqlrect.Width += 20;
|
|
|
|
|
sqlrect.Height += 20;
|
|
|
|
|
detrect.Width += 20;
|
|
|
|
|
detrect.Height += 20;
|
|
|
|
|
Mat matCutblack1 = new Mat(thr1, sqlrect);
|
|
|
|
|
if (IfWhiteWord)
|
|
|
|
|
{
|
|
|
|
|
matCutblack1.SetTo(Scalar.Black);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
matCutblack1.SetTo(Scalar.Black);
|
|
|
|
|
}
|
|
|
|
|
Mat matCutblack2 = new Mat(thr2, detrect);
|
|
|
|
|
if (IfWhiteWord)
|
|
|
|
|
{
|
|
|
|
|
matCutblack2.SetTo(Scalar.Black);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
matCutblack2.SetTo(Scalar.Black);
|
|
|
|
|
}
|
|
|
|
|
Cv2.Resize(thr1, thr1, new Size(845, 498));
|
|
|
|
|
Cv2.Resize(thr2, thr2, new Size(845, 498));
|
|
|
|
|
DateTime dt = DateTime.Now;
|
|
|
|
|
string filename = dt.Year.ToString() + dt.Month.ToString() + dt.Day.ToString() + dt.Hour.ToString() + dt.Minute.ToString() + dt.Millisecond.ToString();
|
|
|
|
|
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//string savePath4 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + filename + "_thr1.png");
|
|
|
|
|
//// 保存结果
|
2024-06-28 17:50:44 +08:00
|
|
|
|
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//Cv2.ImWrite(savePath4, thr1);
|
|
|
|
|
//string savePath3 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + filename + "_thr2.png");
|
|
|
|
|
//// 保存结果
|
2024-06-28 17:50:44 +08:00
|
|
|
|
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//Cv2.ImWrite(savePath3, thr2);
|
2024-06-28 17:50:44 +08:00
|
|
|
|
|
|
|
|
|
// 创建卷积核
|
|
|
|
|
|
|
|
|
|
Mat filter1 = new Mat(15,15, MatType.CV_32F, new Scalar(0));
|
|
|
|
|
filter1.Row(7).SetTo(new Scalar(0.025));
|
|
|
|
|
filter1.Col(7).SetTo(new Scalar(0.025));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 应用卷积
|
|
|
|
|
Mat final_result1 = new Mat();
|
|
|
|
|
Cv2.Filter2D(thr1, final_result1, -1, filter1, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
Cv2.Filter2D(final_result1, final_result1, -1, filter1, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
Cv2.Filter2D(final_result1, final_result1, -1, filter1, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
|
|
|
|
|
//Cv2.Filter2D(final_result1, final_result1, -1, filter2, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
|
|
|
|
|
Mat final_result2 = new Mat();
|
|
|
|
|
Cv2.Filter2D(thr2, final_result2, -1, filter1, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
Cv2.Filter2D(final_result2, final_result2, -1, filter1, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
Cv2.Filter2D(final_result2, final_result2, -1, filter1, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
|
|
|
|
|
//Cv2.Filter2D(final_result2, final_result2, -1, filter2, anchor: new Point(-1, -1), 0, BorderTypes.Reflect);
|
|
|
|
|
//裁剪才行
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//string savePath2 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + "_final_result1.png");
|
|
|
|
|
//// 保存结果
|
|
|
|
|
////string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
|
|
|
|
|
//Cv2.ImWrite(savePath2, final_result1);
|
|
|
|
|
//string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + "_final_result2.png");
|
|
|
|
|
//// 保存结果
|
|
|
|
|
////string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
|
|
|
|
|
//Cv2.ImWrite(savePath, final_result2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 计算图像差异
|
|
|
|
|
Mat devIMG = new Mat();
|
|
|
|
|
Mat devIMG_ = new Mat();
|
|
|
|
|
Cv2.Subtract(final_result1, final_result2, devIMG);
|
|
|
|
|
Cv2.Subtract(final_result2, final_result1, devIMG_);
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//string savePathd = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + filename + "devIMG.png");
|
|
|
|
|
//// 保存结果
|
2024-06-28 17:50:44 +08:00
|
|
|
|
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//Cv2.ImWrite(savePathd, devIMG);
|
|
|
|
|
//string savePathd1 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + filename + "devIMG_.png");
|
|
|
|
|
//// 保存结果
|
2024-06-28 17:50:44 +08:00
|
|
|
|
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//Cv2.ImWrite(savePathd1, devIMG_);
|
2024-06-28 17:50:44 +08:00
|
|
|
|
// 对差异图像应用阈值
|
|
|
|
|
Cv2.Threshold(devIMG, devIMG, 45, 255, ThresholdTypes.Binary);
|
|
|
|
|
Cv2.Threshold(devIMG_, devIMG_, 45, 255, ThresholdTypes.Binary);
|
|
|
|
|
|
|
|
|
|
// 结合差异
|
|
|
|
|
Mat sumIMG = new Mat();
|
|
|
|
|
Cv2.Add(devIMG, devIMG_, sumIMG);
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//string savePaths = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + filename + "sumIMG.png");
|
|
|
|
|
//// 保存结果
|
2024-06-28 17:50:44 +08:00
|
|
|
|
|
2024-07-01 11:39:19 +08:00
|
|
|
|
//Cv2.ImWrite(savePaths, sumIMG);
|
2024-06-28 17:50:44 +08:00
|
|
|
|
// 应用形态学操作
|
|
|
|
|
Mat kernelCL = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3));
|
|
|
|
|
Mat blackhatImg = new Mat();
|
|
|
|
|
Cv2.Dilate(sumIMG, blackhatImg, kernelCL);
|
|
|
|
|
|
|
|
|
|
// 处理轮廓和保存结果
|
|
|
|
|
Point[][] contours = new Point[10000][];
|
|
|
|
|
Cv2.FindContours(blackhatImg, out contours, out _, RetrievalModes.Tree, ContourApproximationModes.ApproxSimple);
|
|
|
|
|
bool isMatch = true;
|
|
|
|
|
foreach (var contour in contours)
|
|
|
|
|
{
|
|
|
|
|
if (Cv2.ContourArea(contour) <= 100)
|
|
|
|
|
{
|
|
|
|
|
Cv2.DrawContours(blackhatImg, new Point[][] { contour }, -1, Scalar.Black, thickness: Cv2.FILLED);
|
|
|
|
|
// 框选轮廓
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Rect boundingRect = Cv2.BoundingRect(contour);
|
|
|
|
|
Cv2.Rectangle(img2, boundingRect, Scalar.Red, thickness: 2);
|
|
|
|
|
isMatch = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string savePath2 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + filename + "_Rect.png");
|
|
|
|
|
// 保存结果
|
|
|
|
|
//string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
|
|
|
|
|
Cv2.ImWrite(savePath2, img2);
|
|
|
|
|
string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + filename + "_diff.png");
|
|
|
|
|
// 保存结果
|
|
|
|
|
//string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
|
|
|
|
|
Cv2.ImWrite(savePath, blackhatImg);
|
|
|
|
|
return isMatch;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-06-11 11:40:47 +08:00
|
|
|
|
}
|
|
|
|
|
}
|