{"id":6257,"date":"2025-11-22T17:45:55","date_gmt":"2025-11-22T09:45:55","guid":{"rendered":"https:\/\/blog.coolcoding.cn\/?p=6257"},"modified":"2025-11-22T18:06:26","modified_gmt":"2025-11-22T10:06:26","slug":"%e4%bd%bf%e7%94%a8c%e6%84%9f%e7%9f%a5%e5%93%88%e5%b8%8c%e7%ae%97%e6%b3%95%e6%a3%80%e6%9f%a5%e5%9b%be%e7%89%87%e7%9b%b8%e4%bc%bc%e5%ba%a6","status":"publish","type":"post","link":"https:\/\/blog.coolcoding.cn\/?p=6257","title":{"rendered":"\u7528\u611f\u77e5\u54c8\u5e0c\u7b97\u6cd5(C#)\u68c0\u67e5\u56fe\u7247\u76f8\u4f3c\u5ea6"},"content":{"rendered":"\n<p>\u9996\u5148\u5728.net core\u5de5\u7a0b\u6587\u4ef6(.csproj)\u4e2d\uff0c\u6dfb\u52a0\u56fe\u7247\u5e93sixlabors\u7684\u5f15\u7528<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  &lt;ItemGroup&gt;\n\n    ...\n    &lt;Reference Include=\"System.Xml\" \/&gt;\n    &lt;PackageReference Include=\"SixLabors.ImageSharp\" Version=\"3.1.4\" \/&gt;\n  &lt;\/ItemGroup&gt;<\/code><\/pre>\n\n\n\n<p>\u7136\u540e\u6dfb\u52a0\u4e00\u4e2aZefirrat\u7684\u611f\u77e5\u54c8\u5e0c\u7b97\u6cd5\u4ee3\u7801<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>using SixLabors.ImageSharp;\r\nusing SixLabors.ImageSharp.PixelFormats;\r\nusing SixLabors.ImageSharp.Processing;\r\n\r\nnamespace Zefirrat\r\n{\r\n    public class ComparerOpt\r\n    {\r\n        public ComparerOpt(byte Accuracy = AccuracyValues.Medium, double CustomRatio = 0.00005)\r\n        {\r\n            this.Accuracy = Accuracy;\r\n            this.CustomRatio = CustomRatio;\r\n        }\r\n\r\n        public byte Accuracy { get; private set; }\r\n        public double CustomRatio { get; private set; }\r\n        public static class AccuracyValues\r\n        {\r\n            public const byte VeryHigh = 1;\r\n            public const byte High = 20;\r\n            public const byte Medium = 50;\r\n            public const byte Low = 90;\r\n            public const byte VeryLow = byte.MaxValue;\r\n        }\r\n    }\r\n\r\n    public class Zefirrat\r\n    {\r\n        public static double&#91;] ImgToVector(Image image)\r\n        {\r\n            image.Mutate(i => i.Grayscale());\r\n            image.Mutate(i => i.Resize(new Size(16, 16)));\r\n            var result = new List&lt;double>();\r\n            using (var cloned = image.CloneAs&lt;RgbaVector>())\r\n            {\r\n                for (var i = 0; i &lt; cloned.Size.Height; i++)\r\n                {\r\n                    for (var j = 0; j &lt; cloned.Size.Width; j++)\r\n                    {\r\n                        result.Add(cloned&#91;i, j].ToVector4().Length());\r\n                    }\r\n                }\r\n            }\r\n            return result.ToArray();\r\n        }\r\n\r\n        private static bool CompareSimilarity(Image image1, Image image2, ComparerOpt opt)\r\n        {\r\n            var vectors1 = ImgToVector(image1);\r\n            var vectors2 = ImgToVector(image2);\r\n            return CompareSimilarity(vectors1, vectors2, opt);\r\n        }\r\n\r\n        public static bool CompareSimilarity(double&#91;] vectors1, double&#91;] vectors2, ComparerOpt opt)\r\n        {\r\n            var standardDeviation1 =\r\n                CalculateStandardDeviation(vectors1, vectors1.Sum() \/ vectors1.Length, vectors1.Length);\r\n            var standardDeviation2 =\r\n                CalculateStandardDeviation(vectors2, vectors2.Sum() \/ vectors2.Length, vectors2.Length);\r\n            var standardDeviation3 = CalculateStandardDeviation(vectors1.Concat(vectors2)\r\n                    .ToArray(),\r\n                (vectors1.Sum() + vectors2.Sum()) \/ (vectors1.Length + vectors2.Length),\r\n                vectors1.Length + vectors2.Length);\r\n\r\n            var accuracy = opt.CustomRatio * opt.Accuracy;\r\n\r\n            return Math.Abs(standardDeviation3 - standardDeviation1) &lt; accuracy &amp;&amp;\r\n                Math.Abs(standardDeviation3 - standardDeviation2) &lt; accuracy;\r\n        }\r\n\r\n        private static double CalculateStandardDeviation(IEnumerable&lt;double> converted2, double s, int n)\r\n        {\r\n            var tmp = 0.0;\r\n            foreach (var x in converted2)\r\n            {\r\n                tmp += Math.Pow(x - s, 2);\r\n            }\r\n            var sko = Math.Sqrt(tmp \/ n);\r\n            return sko;\r\n        }\r\n\r\n        public static bool AreSimilar(string image1, string image2, ComparerOpt _options)\r\n        {\r\n            using var imageSharp1 = Image.Load(image1);\r\n            using var imageSharp2 = Image.Load(image2);\r\n            return CompareSimilarity(imageSharp1, imageSharp2, _options);\r\n        }\r\n    }\r\n}<\/code><\/pre>\n\n\n\n<p>\u4f7f\u7528\u65b9\u6cd5\u793a\u4f8b<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var opt = new Zefirrat.ComparerOpt(39);\r\nvar ret = Zefirrat.Zefirrat.AreSimilar(\"d:\/1.png\", \"d:\/2.png\", opt);\r\nConsole.WriteLine(ret);<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u9996\u5148\u5728.net core\u5de5\u7a0b\u6587\u4ef6(.csproj)\u4e2d\uff0c\u6dfb\u52a0\u56fe\u7247\u5e93sixlabors\u7684\u5f15\u7528 \u7136\u540e\u6dfb\u52a0\u4e00\u4e2aZefi [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/6257"}],"collection":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6257"}],"version-history":[{"count":4,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/6257\/revisions"}],"predecessor-version":[{"id":6261,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/6257\/revisions\/6261"}],"wp:attachment":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6257"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6257"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}