圖像相似度算法的C#實現及測評

2023-10-12 00:18

本文主要是介绍圖像相似度算法的C#實現及測評,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://www.cnblogs.com/wuchaodong/archive/2009/04/28/1444792.html

近日逛博客的時候偶然發現了一個有關圖片相似度的Python算法實現。想著很有意思便搬到C#上來了,給大家看看。

閒言碎語

  才疏學淺,只把計算圖像相似度的一個基本算法的基本實現方式給羅列了出來,以至於在最後自己測評的時候也大發感慨,這個算法有點不靠譜。不管怎麼樣,這個算法有時候還是有用的,所以還是列出來跟大家伙一起分享分享~~

  PS:圖像處理這一塊博大精深,個人偶爾發現了點東西拿來分享。說的不好的地方,寫得太糟的地方,諸位准備扔磚頭還望淡定,淡定~~

基本知識介紹

顏色直方圖

                顏色直方圖是在許多圖像檢索系統中被廣泛采用的顏色特征,它所描述的是不同色彩在整幅圖像中所佔的比例,而並不關心每種色彩所處的空間位置,即無法描述圖像中的對象或物體。顏色直方圖特別適用於描述那些難以進行自動分割的圖像。

灰度直方圖

  灰度直方圖是灰度級的函數,它表示圖像中具有每種灰度級的像素的個數,反映圖像中每種灰度出現的頻率。灰度直方圖的橫坐標是灰度級,縱坐標是該灰度級出現的頻率,是圖像的最基本的統計特征。

   本文中即是使用灰度直方圖來計算圖片相似度,關於算法那一塊也不贅言了,畢竟圖像學圖形學,直方圖我是門兒都不懂,我也不准備打腫臉充胖子,只想實現一個最基本的算法,然後從最直觀的角度看看這個算法的有效性,僅此而已。

 

算法實現

                諸位看官休怪筆者囫圇吞棗,淺嘗輒止的學習態度。額畢竟是因興趣而來,於此方面並無半點基礎(當然,除了知道RGB是啥玩意兒——這還幸虧當年計算機圖形學的老師是個Super美女,因此多上了幾節課的緣故),更談不上半點造詣,看官莫怪莫怪,且忍住怒氣,是走是留,小生不敢有半點阻攔~~

大致步驟如下:

1,  將圖像轉換成相同大小,以有利於計算出相像的直方圖來

2,  計算轉化後的灰度直方圖

3,  利用XX公式,得到直方圖相似度的定量度量

4,  輸出這些不知道有用沒用的相似度結果數據

代碼實現

步驟1, 將圖像轉化成相同大小,我們暫且轉化成256 X 256吧。

 

public Bitmap Resize(string imageFile, string newImageFile)

        {

            img = Image.FromFile(imageFile);

            Bitmap imgOutput = new Bitmap(img, 256, 256);

            imgOutput.Save(newImageFile, System.Drawing.Imaging.ImageFormat.Jpeg);

            imgOutput.Dispose();

            return (Bitmap)Image.FromFile(newImageFile);

      }

 

  這部分代碼很好懂,imageFile為原始圖片的完整路徑,newImageFile為強轉大小後的256 X 256圖片的路徑,為了「賽」後可以看到我們轉化出來的圖片長啥樣,所以我就把它保存到了本地了,以至於有了上面略顯丑陋的代碼。

步驟2,計算圖像的直方圖

public int[] GetHisogram(Bitmap img)

        {

            BitmapData data = img.LockBits( new System.Drawing.Rectangle( 0 , 0 , img.Width , img.Height ), ImageLockMode.ReadWrite , PixelFormat.Format24bppRgb );

            int[ ] histogram = new int[ 256 ];

            unsafe

            {

                                byte* ptr = ( byte* )data.Scan0;

                                int remain = data.Stride - data.Width * 3;

                                forint i = 0 ; i < histogram.Length ; i ++ )

                                        histogram[ i ] = 0;

                                forint i = 0 ; i < data.Height ; i ++ )

                                {

                                        forint j = 0 ; j < data.Width ; j ++ )

                                        {

                                                int mean = ptr[ 0 ] + ptr[ 1 ] + ptr[ 2 ];

                                                mean /= 3;

                                                histogram[ mean ] ++;

                                                ptr += 3;

                                        }

                                        ptr += remain;

                                }

            }

                        img.UnlockBits( data ); 

            return histogram;

    }

這段就是驚天地泣鬼神的灰度直方圖計算方法,裡面的彎彎繞還是留給諸位自己去摻和。

步驟3,計算直方圖相似度度量

這一步驟的法寶在於這個:

Sim(G,S)= HowTo其中G,S為直方圖,N 為顏色空間樣點數

為了大家少敲兩行字兒,也給出一堆亂七八糟的代碼:

 

//計算相減後的絕對值

        private float GetAbs(int firstNum, int secondNum)

        {

            float abs = Math.Abs((float)firstNum - (float)secondNum);

            float result = Math.Max(firstNum, secondNum);

            if (result == 0)

                result = 1;

            return abs / result;

        }

 

        //最終計算結果

        public float GetResult(int[] firstNum, int[] scondNum)

        {

            if (firstNum.Length != scondNum.Length)

            {

                return 0;

            }

            else

            {

                float result = 0;

                int j = firstNum.Length;

                for (int i = 0; i < j; i++)

                {

                    result += 1 - GetAbs(firstNum[i], scondNum[i]);

                    Console.WriteLine(i + "----" + result);

                }

                return result/j;

            }

    }

 

步驟4,輸出

  這個……諸位愛怎麼輸出就怎麼輸出吧。直接Console也好,七彩命令行輸出也罷,亦或者保存到文本文件中留作紀念啦啦,諸位「好自為之」~~

算法測評

  真對不住大家,忘了跟大家說,我也不是一個專業的算法測評人員,但是作為一個半拉子測試人員免不了手癢癢想要看看這個算法到底有多大能耐,就拿出幾張圖片出來驗驗貨吧。

以下是算法測評結果。以下部分內容話帶調侃,絕無惡意,開開玩笑,娛樂大眾~~

 

路人甲

路人乙

圖像相似度

惡搞點評

小白

小白

100%

裡面什麼都沒有!?

恭喜你,如果你看不出來這是兩張白底圖片,那麼你還真是小白,因為你連自家人都認不出來啊~~

小黑

小黑

100%

天下烏鴉一般黑,這個算法在這一點上立場還算堅定,表現不錯~

Win7

win7

100%

碰到Win7也不動心,意志堅定地給出了100%的正確答案。

 

這算法比我意志堅定多了,我可是win7剛出來個7000就裝了,還一直用到現在,不過確實好用~~

我

你

88.84%

明明很不一樣的「我」跟「你」擺在那裡,怎麼就相似度這麼高咧??

 

難道,「我」,「你」都認不出來??

 

哦,我忘了,這兩張圖片的大背景是一樣的,難怪……

win7

Mac

16.08%

MS跟Apple這麼水火不相容?

【均使用默認桌面~~】

Rose

Jack

50.64%

終於了解了Jack跟Rose不能在一起的真正原因:

不是愛的不夠深,也不是泰坦尼克號沉了,用老媽的話說「沒有『夫妻』相」

—— 還是老媽這個過來人老道~~

小黑

小白

99.21%

哇,太不可思議了,竟然是這樣。

這算法這樣「黑」「白」不分??

 

我得向Jack跟Rose的忠實Fans道歉了,上面的話是一時失言~~祝他們倆白頭偕老,下輩子千萬別做船了,坐船也不出海,出海也不去北極,……

 

 

  經過我略顯玩世不恭的測評活動,說實話,我對這個算法是相當的失望,尤其是最後一次對比中的結果,目前情緒低落中。這倒不是說這算法的一無是處,應該是我或者某些前輩用錯了地方,個人覺得算法使用的局限性太大,也或許是我的期望值太高了吧。

後記

  開始看到這玩意兒的時候覺得這玩意兒很簡單啊,可是一想不對勁,沒有這麼容易的事情,要不Google,MS這些大牛們做了這麼久還沒有像樣的玩意兒出來。果不其然,為了多了解一點相關的內容,我不得不Google了一下,覺得那些術語完全不知所雲,看不懂啊;看來我得祭出我一般不使用的大殺器了——百度一搜。嘿,還真找出來了一堆東西,比Google上面的看起來容易多了,可是打開鏈接進去瞅瞅,發現還是非我當前能力之所及。沒學到東西,但是好歹還是了解了一點皮毛上的皮毛。

全文完

  諸位看官若覺得講得沒有意義,浪費了你的時間,那就權當作冷笑話聽聽緩解一下緊張的神經~~




这篇关于圖像相似度算法的C#實現及測評的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/191869

相关文章

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

c# checked和unchecked关键字的使用

《c#checked和unchecked关键字的使用》C#中的checked关键字用于启用整数运算的溢出检查,可以捕获并抛出System.OverflowException异常,而unchecked... 目录在 C# 中,checked 关键字用于启用整数运算的溢出检查。默认情况下,C# 的整数运算不会自

C#实现获得某个枚举的所有名称

《C#实现获得某个枚举的所有名称》这篇文章主要为大家详细介绍了C#如何实现获得某个枚举的所有名称,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... C#中获得某个枚举的所有名称using System;using System.Collections.Generic;usi

C# 读写ini文件操作实现

《C#读写ini文件操作实现》本文主要介绍了C#读写ini文件操作实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录一、INI文件结构二、读取INI文件中的数据在C#应用程序中,常将INI文件作为配置文件,用于存储应用程序的

C#实现获取电脑中的端口号和硬件信息

《C#实现获取电脑中的端口号和硬件信息》这篇文章主要为大家详细介绍了C#实现获取电脑中的端口号和硬件信息的相关方法,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 我们经常在使用一个串口软件的时候,发现软件中的端口号并不是普通的COM1,而是带有硬件信息的。那么如果我们使用C#编写软件时候,如

C#中图片如何自适应pictureBox大小

《C#中图片如何自适应pictureBox大小》文章描述了如何在C#中实现图片自适应pictureBox大小,并展示修改前后的效果,修改步骤包括两步,作者分享了个人经验,希望对大家有所帮助... 目录C#图片自适应pictureBox大小编程修改步骤总结C#图片自适应pictureBox大小上图中“z轴

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

C#实现WinForm控件焦点的获取与失去

《C#实现WinForm控件焦点的获取与失去》在一个数据输入表单中,当用户从一个文本框切换到另一个文本框时,需要准确地判断焦点的转移,以便进行数据验证、提示信息显示等操作,本文将探讨Winform控件... 目录前言获取焦点改变TabIndex属性值调用Focus方法失去焦点总结最后前言在一个数据输入表单