Я работаю над решением, которое позволит улучшить сравнение скриншотов наших компаний. В настоящее время мы наблюдаем множество сбоев из-за различий в пикселях и т. д. Я реализовал решение в OpenCvSharp, которое работает на 90%. Однако некоторые изображения, похоже, дают ложные срабатывания, рисуя контуры (красные рамки) вокруг вещей, которые не изменились. Кажется, это несколько случайно и не связано с каким-либо конкретным типом изображения. Подробности смотрите на изображениях ниже (не обращайте внимания на поля в верхнем левом и правом углах, я сделал это, чтобы скрыть информацию о конкретной компании)
Базовый файл:
Файл различий (после сравнения выполнено) см. маленькую красную рамку вокруг данных графика:
Эта работа направлена на то, чтобы избежать проблем, подобных описанным ниже, но после почти двух недель разработки и настройки кода у меня начинают заканчиваться идеи. Код, который я сейчас использую, приведен ниже:
private static Mat LoadImage(string path)
{
if (!File.Exists(path))
{
throw new FileNotFoundException($"The specified image file was not found at path: {path} - Please ensure the baseline is created.");
}
Mat image = Cv2.ImRead(path, ImreadModes.Color);
// Check if the matrix is empty (indicating a load failure)
if (image.Empty())
{
throw new ImageComparisonException($"Failed to load a valid image from path: {path}. The image might be corrupted or unsupported.");
}
return image;
}
private static Mat ConvertToGrayscale(Mat image)
{
Mat gray = new Mat();
Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY);
Cv2.GaussianBlur(gray, gray, new Size(5, 5), 0);
return gray;
}
Я считаю, что проблема кроется где-то в приведенном ниже коде:
private static bool isSignificantChangesBetweenImages(Mat baselineImage, Mat currentImage, Mat ssimMap, ImageComparisonConfig imageConfig, out Mat filledImage)
{
filledImage = currentImage.Clone();
Mat diff = new Mat();
ssimMap.ConvertTo(diff, MatType.CV_8UC1, 255);
Mat thresh = new Mat();
Cv2.Threshold(diff, thresh, 0, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu);
Point[][] contourDifferencePoints;
HierarchyIndex[] hierarchyIndex;
Cv2.FindContours(thresh, out contourDifferencePoints, out hierarchyIndex, RetrievalModes.List, ContourApproximationModes.ApproxSimple);
return DrawSignificantChanges(baselineImage, contourDifferencePoints, imageConfig, filledImage);
}
private static bool DrawSignificantChanges(Mat baselineImage, Point[][] contours, ImageComparisonConfig imageConfig, Mat filledImage, double minAreaRatio = 0.0001, double maxAreaRatio = 0.1)
{
bool hasSignificantChanges = false;
double totalImageArea = baselineImage.Width * baselineImage.Height;
double minArea = totalImageArea * minAreaRatio;
double maxArea = totalImageArea * maxAreaRatio;
foreach (var contour in contours)
{
double area = Cv2.ContourArea(contour);
if (area < minArea || area > maxArea) continue;
Rect boundingRect = Cv2.BoundingRect(contour);
// Ignore changes near the image border
int borderThreshold = 5;
if (boundingRect.X = baselineImage.Height - borderThreshold)
{
continue;
}
// Check if the difference is significant enough
using (Mat roi = new Mat(baselineImage, boundingRect))
{
Scalar mean = Cv2.Mean(roi);
if (mean.Val0 < int.Parse(imageConfig.GetPixelToleranceSetting())) // Adjust this threshold as needed
{
continue;
}
}
// Draw Rectangle shape in red around the differences
Cv2.Rectangle(filledImage, boundingRect, new Scalar(0, 0, 255), 2);
hasSignificantChanges = true;
}
return hasSignificantChanges;
}
Я попытался настроить значения порога, но снова получил аналогичные результаты. Есть ли кто-нибудь, у кого есть что-то подобное? Как вы можете видеть на изображениях ниже, существенных отличий от человеческого глаза нет. Одна из проблем, с которой я сталкиваюсь, заключается в том, что код сравнения должен улавливать небольшие изменения, такие как процентные изменения графика.
Я работаю над решением, которое позволит улучшить сравнение скриншотов наших компаний. В настоящее время мы наблюдаем множество сбоев из-за различий в пикселях и т. д. Я реализовал решение в OpenCvSharp, которое работает на 90%. Однако некоторые изображения, похоже, дают ложные срабатывания, рисуя контуры (красные рамки) вокруг вещей, которые не изменились. Кажется, это несколько случайно и не связано с каким-либо конкретным типом изображения. Подробности смотрите на изображениях ниже (не обращайте внимания на поля в верхнем левом и правом углах, я сделал это, чтобы скрыть информацию о конкретной компании) Базовый файл: [img]https://i.sstatic.net/JpOWaIx2.jpg[/img]
Файл различий (после сравнения выполнено) см. маленькую красную рамку вокруг данных графика: [img]https://i.sstatic.net/fz5MCr6t.jpg[/img]
Эта работа направлена на то, чтобы избежать проблем, подобных описанным ниже, но после почти двух недель разработки и настройки кода у меня начинают заканчиваться идеи. Код, который я сейчас использую, приведен ниже: [code] public static void CompareImagesForDifferences(string baselineImagePath, Screenshot currentImageScreenshot, string testName, ImageComparisonConfig imageConfig) { string currentImagePath = SaveCurrentImage(currentImageScreenshot, testName, imageConfig);
Mat baselineImage = LoadImage(baselineImagePath); Mat currentImage = LoadImage(currentImagePath);
ResizeImage(baselineImage, currentImage);
Mat baselineGray = ConvertToGrayscale(baselineImage); Mat currentGray = ConvertToGrayscale(currentImage);
double ssimScore = ComputeSSIM(baselineGray, currentGray, out Mat ssimMap);
if (ssimScore >= double.Parse(imageConfig.GetSSIMThresholdSetting())) { // Images are identical Logger.Info("Images are similar. No significant differences detected."); return; }
if (isSignificantChangesBetweenImages(baselineImage, currentImage, ssimMap, imageConfig, out Mat filledImage)) { string diffImagePath = $@"{imageConfig.GetFailuresPath()}\\{testName}_Diff.png"; SaveDiffImage(filledImage, testName, imageConfig, diffImagePath, baselineImagePath); } } [/code] Каждый из соответствующих методов приведен ниже (без учета SaveCurrentImage): [code]private static Mat LoadImage(string path) { if (!File.Exists(path)) { throw new FileNotFoundException($"The specified image file was not found at path: {path} - Please ensure the baseline is created."); }
Mat image = Cv2.ImRead(path, ImreadModes.Color);
// Check if the matrix is empty (indicating a load failure) if (image.Empty()) { throw new ImageComparisonException($"Failed to load a valid image from path: {path}. The image might be corrupted or unsupported."); }
return image; }
private static Mat ConvertToGrayscale(Mat image) { Mat gray = new Mat(); Cv2.CvtColor(image, gray, ColorConversionCodes.BGR2GRAY); Cv2.GaussianBlur(gray, gray, new Size(5, 5), 0); return gray; } [/code] Я считаю, что проблема кроется где-то в приведенном ниже коде: [code]private static bool isSignificantChangesBetweenImages(Mat baselineImage, Mat currentImage, Mat ssimMap, ImageComparisonConfig imageConfig, out Mat filledImage) { filledImage = currentImage.Clone(); Mat diff = new Mat(); ssimMap.ConvertTo(diff, MatType.CV_8UC1, 255);
Mat thresh = new Mat(); Cv2.Threshold(diff, thresh, 0, 255, ThresholdTypes.BinaryInv | ThresholdTypes.Otsu);
Point[][] contourDifferencePoints; HierarchyIndex[] hierarchyIndex; Cv2.FindContours(thresh, out contourDifferencePoints, out hierarchyIndex, RetrievalModes.List, ContourApproximationModes.ApproxSimple);
foreach (var contour in contours) { double area = Cv2.ContourArea(contour); if (area < minArea || area > maxArea) continue;
Rect boundingRect = Cv2.BoundingRect(contour);
// Ignore changes near the image border int borderThreshold = 5; if (boundingRect.X = baselineImage.Height - borderThreshold) { continue; }
// Check if the difference is significant enough using (Mat roi = new Mat(baselineImage, boundingRect)) { Scalar mean = Cv2.Mean(roi); if (mean.Val0 < int.Parse(imageConfig.GetPixelToleranceSetting())) // Adjust this threshold as needed { continue; } }
// Draw Rectangle shape in red around the differences Cv2.Rectangle(filledImage, boundingRect, new Scalar(0, 0, 255), 2); hasSignificantChanges = true; } return hasSignificantChanges; } [/code] Я попытался настроить значения порога, но снова получил аналогичные результаты. Есть ли кто-нибудь, у кого есть что-то подобное? Как вы можете видеть на изображениях ниже, существенных отличий от человеческого глаза нет. Одна из проблем, с которой я сталкиваюсь, заключается в том, что код сравнения должен улавливать небольшие изменения, такие как процентные изменения графика.