圖像相似度算法的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#实现将XML数据自动化地写入Excel文件

《C#实现将XML数据自动化地写入Excel文件》在现代企业级应用中,数据处理与报表生成是核心环节,本文将深入探讨如何利用C#和一款优秀的库,将XML数据自动化地写入Excel文件,有需要的小伙伴可以... 目录理解XML数据结构与Excel的对应关系引入高效工具:使用Spire.XLS for .NETC

C#如何在Excel文档中获取分页信息

《C#如何在Excel文档中获取分页信息》在日常工作中,我们经常需要处理大量的Excel数据,本文将深入探讨如何利用Spire.XLSfor.NET,高效准确地获取Excel文档中的分页信息,包括水平... 目录理解Excel中的分页机制借助 Spire.XLS for .NET 获取分页信息为什么选择 S

C#高效实现在Word文档中自动化创建图表的可视化方案

《C#高效实现在Word文档中自动化创建图表的可视化方案》本文将深入探讨如何利用C#,结合一款功能强大的第三方库,实现在Word文档中自动化创建图表,为你的数据呈现和报告生成提供一套实用且高效的解决方... 目录Word文档图表自动化:为什么选择C#?从零开始:C#实现Word文档图表的基本步骤深度优化:C

在C#中分离饼图的某个区域的操作指南

《在C#中分离饼图的某个区域的操作指南》在处理Excel饼图时,我们可能需要将饼图的各个部分分离出来,以使它们更加醒目,Spire.XLS提供了Series.DataFormat.Percent属性,... 目录引言如何设置饼图各分片之间分离宽度的代码示例:从整个饼图中分离单个分片的代码示例:引言在处理

C#借助Spire.XLS for .NET实现在Excel中添加文档属性

《C#借助Spire.XLSfor.NET实现在Excel中添加文档属性》在日常的数据处理和项目管理中,Excel文档扮演着举足轻重的角色,本文将深入探讨如何在C#中借助强大的第三方库Spire.... 目录为什么需要程序化添加Excel文档属性使用Spire.XLS for .NET库实现文档属性管理Sp

C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解

《C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解》:本文主要介绍C++,C#,Rust,Go,Java,Python,JavaScript性能对比全面... 目录编程语言性能对比、核心优势与最佳使用场景性能对比表格C++C#RustGoJavapythonjav

C# 预处理指令(# 指令)的具体使用

《C#预处理指令(#指令)的具体使用》本文主要介绍了C#预处理指令(#指令)的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录1、预处理指令的本质2、条件编译指令2.1 #define 和 #undef2.2 #if, #el

C#实现将Excel工作表拆分为多个窗格

《C#实现将Excel工作表拆分为多个窗格》在日常工作中,我们经常需要处理包含大量数据的Excel文件,本文将深入探讨如何在C#中利用强大的Spire.XLSfor.NET自动化实现Excel工作表的... 目录为什么需要拆分 Excel 窗格借助 Spire.XLS for .NET 实现冻结窗格(Fro

C# Semaphore与SemaphoreSlim区别小结

《C#Semaphore与SemaphoreSlim区别小结》本文主要介绍了C#Semaphore与SemaphoreSlim区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录一、核心区别概览二、详细对比说明1.跨进程支持2.异步支持(关键区别!)3.性能差异4.API 差

C# List.Sort四种重载总结

《C#List.Sort四种重载总结》本文详细分析了C#中List.Sort()方法的四种重载形式及其实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录1. Sort方法的四种重载2. 具体使用- List.Sort();- IComparable