hisence-yolo-detection/HisenceYoloDetection/CheckDiffSciHelper.cs
2024-06-27 18:02:33 +08:00

342 lines
14 KiB
C#

using OpenCvSharp;
using Sunny.UI.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Point = OpenCvSharp.Point;
using Size = OpenCvSharp.Size;
namespace HisenceYoloDetection
{
public static class CheckDiffSciHelper
{
/// <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, 0, 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, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
}
//Rect area2 = new Rect(148,30,229,222);
sqlrect.Width += 20;
detrect.Width += 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(550, 270));
Cv2.Resize(thr2, thr2, new Size(550, 270));
DateTime dt= DateTime.Now;
string filename = dt.Year.ToString() + dt.Month.ToString() + dt.Day.ToString() + dt.Hour.ToString() + dt.Minute.ToString() + dt.Millisecond.ToString();
string savePath4 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + filename + "_thr1.png");
// 保存结果
Cv2.ImWrite(savePath4, thr1);
string savePath3 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path1) + filename + "_thr2.png");
// 保存结果
Cv2.ImWrite(savePath3, thr2);
// 创建卷积核
Mat filter1 = new Mat(5, 5, MatType.CV_32F, new Scalar(0));
filter1.Row(2).SetTo(new Scalar(0.025));
filter1.Col(2).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);
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);
//裁剪才行
//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_);
// 对差异图像应用阈值
Cv2.Threshold(devIMG, devIMG, 50, 255, ThresholdTypes.Binary);
Cv2.Threshold(devIMG_, devIMG_, 50, 255, ThresholdTypes.Binary);
// 结合差异
Mat sumIMG = new Mat();
Cv2.Add(devIMG, devIMG_, sumIMG);
// 应用形态学操作
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;
}
public static Rect strChangeRect(string strrect)
{
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;
}else
{
return new Rect(0,0,0, 0);
}
}
public static string rectChangeStr(Rect area)
{
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;
}
//public static void CheckDiffSci(string path1, string path2, bool IfWhiteWord, string saveDir)
//{
// // 读取和处理第一张图片
// Mat img1 = Cv2.ImRead(path1, ImreadModes.Color);
// if (img1.Empty())
// {
// Console.WriteLine($"Error loading image {path1}");
// return;
// }
// 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, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
// }
// string savePath4 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_thr1.png");
// // 保存结果
// //string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
// Cv2.ImWrite(savePath4, thr1);
// // 读取和处理第二张图片
// Mat img2 = Cv2.ImRead(path2, ImreadModes.Color);
// if (img2.Empty())
// {
// Console.WriteLine($"Error loading image {path2}");
// return;
// }
// 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, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
// }
// // Cv2.Threshold(gimg2, thr2, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
// string savePath3 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_thr2.png");
// // 保存结果
// //string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
// Cv2.ImWrite(savePath3, thr2);
// // 创建卷积核
// Mat filter1 = new Mat(17, 17, MatType.CV_32F, new Scalar(0));
// filter1.Row(8).SetTo(new Scalar(0.025));
// filter1.Col(8).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);
// 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);
// // 计算图像差异
// Mat devIMG = new Mat();
// Mat devIMG_ = new Mat();
// Cv2.Subtract(final_result1, final_result2, devIMG);
// Cv2.Subtract(final_result2, final_result1, devIMG_);
// // 对差异图像应用阈值
// Cv2.Threshold(devIMG, devIMG, 50, 255, ThresholdTypes.Binary);
// Cv2.Threshold(devIMG_, devIMG_, 50, 255, ThresholdTypes.Binary);
// // 结合差异
// Mat sumIMG = new Mat();
// Cv2.Add(devIMG, devIMG_, sumIMG);
// // 应用形态学操作
// 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);
// 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);
// }
// }
// string savePath2 = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_Rect.png");
// // 保存结果
// //string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
// Cv2.ImWrite(savePath2, img2);
// string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
// // 保存结果
// //string savePath = Path.Combine(saveDir, Path.GetFileNameWithoutExtension(path2) + "_diff.png");
// Cv2.ImWrite(savePath, blackhatImg);
//}
}
}