圖像相似度算法的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

相关文章

Go语言如何判断两张图片的相似度

《Go语言如何判断两张图片的相似度》这篇文章主要为大家详细介绍了Go语言如何中实现判断两张图片的相似度的两种方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 在介绍技术细节前,我们先来看看图片对比在哪些场景下可以用得到:图片去重:自动删除重复图片,为存储空间"瘦身"。想象你是一个

C#如何去掉文件夹或文件名非法字符

《C#如何去掉文件夹或文件名非法字符》:本文主要介绍C#如何去掉文件夹或文件名非法字符的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#去掉文件夹或文件名非法字符net类库提供了非法字符的数组这里还有个小窍门总结C#去掉文件夹或文件名非法字符实现有输入字

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式

《C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式》Markdown凭借简洁的语法、优良的可读性,以及对版本控制系统的高度兼容性,逐渐成为最受欢迎的文档格式... 目录为什么要将文档转换为 Markdown 格式使用工具将 Word 文档转换为 Markdown(.

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

C#代码实现解析WTGPS和BD数据

《C#代码实现解析WTGPS和BD数据》在现代的导航与定位应用中,准确解析GPS和北斗(BD)等卫星定位数据至关重要,本文将使用C#语言实现解析WTGPS和BD数据,需要的可以了解下... 目录一、代码结构概览1. 核心解析方法2. 位置信息解析3. 经纬度转换方法4. 日期和时间戳解析5. 辅助方法二、L

使用C#删除Excel表格中的重复行数据的代码详解

《使用C#删除Excel表格中的重复行数据的代码详解》重复行是指在Excel表格中完全相同的多行数据,删除这些重复行至关重要,因为它们不仅会干扰数据分析,还可能导致错误的决策和结论,所以本文给大家介绍... 目录简介使用工具C# 删除Excel工作表中的重复行语法工作原理实现代码C# 删除指定Excel单元

C#使用MQTTnet实现服务端与客户端的通讯的示例

《C#使用MQTTnet实现服务端与客户端的通讯的示例》本文主要介绍了C#使用MQTTnet实现服务端与客户端的通讯的示例,包括协议特性、连接管理、QoS机制和安全策略,具有一定的参考价值,感兴趣的可... 目录一、MQTT 协议简介二、MQTT 协议核心特性三、MQTTNET 库的核心功能四、服务端(BR

C#继承之里氏替换原则分析

《C#继承之里氏替换原则分析》:本文主要介绍C#继承之里氏替换原则,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#里氏替换原则一.概念二.语法表现三.类型检查与转换总结C#里氏替换原则一.概念里氏替换原则是面向对象设计的基本原则之一:核心思想:所有引py

C#实现访问远程硬盘的图文教程

《C#实现访问远程硬盘的图文教程》在现实场景中,我们经常用到远程桌面功能,而在某些场景下,我们需要使用类似的远程硬盘功能,这样能非常方便地操作对方电脑磁盘的目录、以及传送文件,这次我们将给出一个完整的... 目录引言一. 远程硬盘功能展示二. 远程硬盘代码实现1. 底层业务通信实现2. UI 实现三. De