111
This commit is contained in:
150
Check.Main/Process_Img.cs
Normal file
150
Check.Main/Process_Img.cs
Normal file
@@ -0,0 +1,150 @@
|
||||
using OpenCvSharp;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenCvSharp.Extensions;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading.Tasks;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
public class ProcessImg
|
||||
{
|
||||
// 对单个图像进行模板匹配
|
||||
|
||||
public static (double score, Rect? coords) MatchTemplate(Mat img, string templatePath)
|
||||
{
|
||||
// 确保图像和模板文件存在
|
||||
|
||||
|
||||
// 读取图像和模板
|
||||
|
||||
var template = Cv2.ImRead(templatePath, ImreadModes.Color);
|
||||
|
||||
// 创建一个模板匹配的结果矩阵
|
||||
var result = new Mat();
|
||||
Cv2.MatchTemplate(img, template, result, TemplateMatchModes.CCoeffNormed);
|
||||
|
||||
// 查找最大匹配值
|
||||
Cv2.MinMaxLoc(result, out _, out var maxVal, out _, out var maxLoc);
|
||||
|
||||
// 如果找到的最大匹配值大于阈值
|
||||
double threshold = 0.3; // 可以根据需要调整阈值
|
||||
if (maxVal >= threshold)
|
||||
{
|
||||
// 计算匹配的坐标
|
||||
var topLeft = maxLoc;
|
||||
var rect = new Rect(topLeft.X, topLeft.Y, template.Width, template.Height);
|
||||
|
||||
return (maxVal, rect);
|
||||
}
|
||||
|
||||
return (0, null);
|
||||
}
|
||||
|
||||
// 遍历文件夹中的所有图像文件进行模板匹配,并找到最佳得分图像
|
||||
public static Double ProcessImagesInFolder(string folderPath, Mat img)
|
||||
{
|
||||
// 获取所有图像文件
|
||||
var imageFiles = Directory.GetFiles(folderPath, "*.*", SearchOption.TopDirectoryOnly)
|
||||
.Where(file => file.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) ||
|
||||
file.EndsWith(".png", StringComparison.OrdinalIgnoreCase) ||
|
||||
file.EndsWith(".bmp", StringComparison.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
|
||||
|
||||
|
||||
// 确保输出文件夹存在
|
||||
|
||||
|
||||
// 线程数量
|
||||
int numThreads = 5;
|
||||
|
||||
// 用于存储每个图像的得分和坐标
|
||||
var bestMatch = new ConcurrentBag<(string imagePath, double score, Rect? coords)>();
|
||||
DateTime startTime = DateTime.Now;
|
||||
Stopwatch sw = new Stopwatch();
|
||||
sw.Start();
|
||||
|
||||
Parallel.ForEach(imageFiles, new ParallelOptions { MaxDegreeOfParallelism = numThreads }, picPath =>
|
||||
{
|
||||
DateTime threadStartTime = DateTime.Now;
|
||||
|
||||
var (score, coords) = MatchTemplate(img, picPath);
|
||||
|
||||
|
||||
|
||||
bestMatch.Add((picPath, score, coords));
|
||||
|
||||
|
||||
DateTime threadEndTime = DateTime.Now;
|
||||
TimeSpan threadElapsed = threadEndTime - threadStartTime;
|
||||
Console.WriteLine($"线程处理 {picPath} 耗时: {threadElapsed.TotalMilliseconds}ms");
|
||||
});
|
||||
|
||||
sw.Stop();
|
||||
TimeSpan totalElapsed = sw.Elapsed;
|
||||
Console.WriteLine($"处理完成,耗时: {totalElapsed.TotalSeconds}秒");
|
||||
// 查找最佳得分
|
||||
var best = bestMatch.OrderByDescending(m => m.score).FirstOrDefault();
|
||||
return best.score;
|
||||
//if (best.coords.HasValue)
|
||||
//{
|
||||
// Rect rect = best.coords.Value;
|
||||
// return rect;
|
||||
//}
|
||||
|
||||
//else
|
||||
//{
|
||||
// return new Rect(0, 0, 0, 0);
|
||||
//}
|
||||
|
||||
|
||||
}
|
||||
public static Mat BitmapToMat(Bitmap bitmap)
|
||||
{
|
||||
if (bitmap == null)
|
||||
{
|
||||
throw new ArgumentException("Bitmap is null");
|
||||
}
|
||||
|
||||
// 根据 Bitmap 的宽度、高度和像素格式创建一个与其相对应的 Mat
|
||||
Mat mat = new Mat(bitmap.Height, bitmap.Width, MatType.CV_8UC3); // 假设 Bitmap 是 24-bit RGB
|
||||
|
||||
// 锁定 Bitmap 的内存区域以直接访问它的内存
|
||||
BitmapData bitmapData = bitmap.LockBits(
|
||||
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
|
||||
ImageLockMode.ReadOnly,
|
||||
bitmap.PixelFormat
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
// 使用直接内存拷贝将 Bitmap 的数据拷贝到 Mat
|
||||
unsafe
|
||||
{
|
||||
byte* srcData = (byte*)bitmapData.Scan0;
|
||||
byte* dstData = (byte*)mat.DataPointer;
|
||||
|
||||
int stride = bitmapData.Stride;
|
||||
int width = bitmap.Width * 3; // 24bpp 3个字节一个像素
|
||||
int height = bitmap.Height;
|
||||
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
Buffer.MemoryCopy(srcData + y * stride, dstData + y * mat.Step(), width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
bitmap.UnlockBits(bitmapData);
|
||||
}
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user