国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

OpenCV書簽 #直方圖算法的原理與相似圖片搜索實驗

這篇具有很好參考價值的文章主要介紹了OpenCV書簽 #直方圖算法的原理與相似圖片搜索實驗。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1. 介紹

直方圖算法(Image Histogram Algorithm) 通過統(tǒng)計圖像中各個顏色值的分布情況來提供關(guān)于圖像顏色特征的信息,它可以用來衡量兩張圖片在顏色分布上的相似度,進而可以用來進行圖像相似度的比較,因此,直方圖算法是一種常用的圖片相似度算法,通常是一個一維的數(shù)組(取決于使用通道的數(shù)量),其中每個元素表示特定顏色或強度值的像素數(shù)量。

關(guān)于直方圖算法的一些概念:

直方圖的定義

直方圖是一個二維數(shù)組,通常是一維的(取決于使用通道的數(shù)量),其中每個元素表示特定顏色或強度值的像素數(shù)量。對于彩色圖像,通常有多個通道,比如藍、綠、紅(BGR),因此可能有多個直方圖。

直方圖的統(tǒng)計

  • 直方圖的統(tǒng)計是通過掃描圖像的每個像素來收集顏色信息的過程。
  • 對于灰度圖像(屬于單通道),每個像素只有一個強度值,因此只有一個通道的直方圖。對于彩色圖像,每個像素有多個通道的值,所以需要分別統(tǒng)計每個通道的直方圖。
  • 關(guān)于單通道更詳細的詳細實驗可見下文:討論1#關(guān)于單通道 [0]

直方圖的用途

  • 直方圖可以用于多種圖像處理任務(wù),包括圖像增強、顏色校正、圖像分割、物體檢測和圖像相似性比較。
  • 通過分析直方圖,可以獲得有關(guān)圖像的顏色分布、對比度、亮度等信息。

直方圖均衡化

  • 直方圖均衡化是一種用于增強圖像對比度的技術(shù),它通過重新分配像素的強度值來拉伸或壓縮直方圖,以使其分布更均勻。這可以使圖像中的細節(jié)更加清晰。

直方圖相似度

  • 直方圖相似度用于比較兩幅圖像的相似程度。通過計算兩個圖像的直方圖之間的差異,可以量化它們的相似性。
  • 常見的直方圖相似度度量包括交叉相關(guān)性(cv2.HISTCMP_INTERSECT)、卡方距離(cv2.HISTCMP_CHISQR)、相關(guān)性(cv2.HISTCMP_CORREL)、巴氏距離(cv2.HISTCMP_BHATTACHARYYA)等。
  • 對于直方圖比較方法的詳細實驗可見下文:討論2#直方圖相似度函數(shù)

顏色直方圖

  • 對于彩色圖像,顏色直方圖通常分別計算每個通道的直方圖。這可以提供關(guān)于不同顏色通道的顏色分布信息,有助于顏色特征的分析。
  • 對于彩色圖像直方圖的詳細實驗可見下文:討論3#彩色圖像直方圖

?

2. 原理

直方圖算法通過統(tǒng)計圖像中不同顏色的像素數(shù)量,并以直方圖的形式呈現(xiàn),進而進行圖像相似度的比較。

關(guān)于 bin

在一個灰度圖像中,像素值的范圍通常從黑色(0)到白色(255)之間變換。如果將圖像的像素值范圍分成 256 個 bin 格子,那么每個 bin 格子則代表一個灰度級別,其灰度值從 0 到 255。直方圖中每個 bin 格子記錄了對應(yīng)灰度級別的像素數(shù)量,通過統(tǒng)計每個 bin 格子中的像素數(shù)量,就可以了解圖像中不同灰度級別的分布情況。

即可看作有你 256 張灰色系色度卡,每一個灰度卡上都統(tǒng)計了灰度圖像中所有該色度的像素數(shù)量,這樣就可以直觀看出灰度圖像的像素在不同色度卡上的分布,然后和其它圖像加以對比分析。

?

3. 魔法

直方圖計算圖片相似度的步驟:

  1. 圖像預(yù)處理: 將目標圖像轉(zhuǎn)換為灰度圖像或彩色圖像,并根據(jù)需要進行尺寸調(diào)整。
  2. 計算直方圖: 對于灰度圖像,直方圖表示不同灰度級別的像素數(shù)量。對于彩色圖像,可以分別計算各個通道(如紅、綠、藍)的直方圖對圖像中的每個像素進行像素值的統(tǒng)計,以確定每個像素值的頻率或數(shù)量。這通常包括遍歷圖像的每個像素,并將其像素值歸類到相應(yīng)的像素值區(qū)間(通常是0到255)。最終,得到一個表示像素值頻率的直方圖。
  3. 直方圖比較: 對于兩張圖片的直方圖,可以使用不同的距離或相似度度量方法來進行比較。常見的度量方法包括相關(guān)性、卡方距離、巴氏距離等。
  4. 相似度評估: 根據(jù)直方圖比較的結(jié)果,計算出兩張圖片之間的相似度得分。

?

4. 實驗

4.1 魔法

第一步:圖像預(yù)處理

將目標圖像轉(zhuǎn)換為灰度圖像或彩色圖像,并根據(jù)需要進行尺寸調(diào)整。
1)讀取原圖: 首先讀取我們要分析的圖像。
2)圖像灰度化: 如果需要計算灰度直方圖,將彩色圖像轉(zhuǎn)換為灰度圖像。這里我們使用 [0],只考慮圖像灰度級別(亮度)信息,結(jié)果是一維數(shù)組。

第二步:計算直方圖

對于灰度圖像,直方圖表示不同灰度級別的像素數(shù)量。

"""
以圖搜圖:圖像直方圖(Image Histogram)查找相似圖像的原理與實現(xiàn)
測試環(huán)境:win10 | python 3.9.13 | OpenCV 4.4.0 | numpy 1.21.1 | matplotlib 3.7.1
實驗時間:2023-10-27
實例名稱:imgHistogram_v1.0.py
"""

import cv2
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

# 目標圖像素材庫文件夾路徑
database_dir = '../../P0_Doc/'
# 文件路徑
img_path = database_dir + 'img_data/car-101.jpg'
font_path = database_dir + 'fonts/chinese_cht.ttf'

# 讀取圖像
img = cv2.imread(img_path)
# 計算直方圖
img_hist = cv2.calcHist([img], [0], None, [256], [0, 256])
print(img_hist)

# 設(shè)置中文字體
font = FontProperties(fname=font_path, size=14)
# 繪制直方圖
plt.plot(img_hist)
plt.title('Histogram(直方圖)', fontproperties=font)
plt.xlabel('Pixel Value(像素值)', fontproperties=font)
plt.ylabel('Frequency(頻率)', fontproperties=font)
# 像素分布可視化
plt.show()

輸出打?。?55個像素亮度

[[   25.]
 [   13.]
 [   13.]
 [   25.]
 [   39.]

......

 [  798.]
 [  779.]
 [ 2034.]]

像素分布可視化效果(直方圖):
OpenCV書簽 #直方圖算法的原理與相似圖片搜索實驗,OpenCV,Python,算法,opencv,直方圖算法,python,圖搜索算法,相似圖片搜索,以圖搜圖
對于彩色圖像,可以分別計算各個通道(如紅、綠、藍)的直方圖。對圖像中的每個像素進行像素值的統(tǒng)計,以確定每個像素值的頻率或數(shù)量。這通常包括遍歷圖像的每個像素,并將其像素值歸類到相應(yīng)的像素值區(qū)間(通常是0到255)。最終,得到一個表示像素值頻率的直方圖。

img_hist = cv2.calcHist([img], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256])

注:彩色直方圖我們下后面詳說。

cv2.calcHist 函數(shù)用于計算圖像的直方圖。以下是它的主要參數(shù)和說明:

  • img:要計算直方圖的圖像。它以方括號的形式傳遞,允許計算多個圖像的直方圖。例如,[img] 表示計算單個圖像的直方圖,[img1, img2] 表示計算兩個圖像的直方圖。
  • channels:指定要考慮的通道。這是一個通道索引列表,用于選擇要計算直方圖的通道。在 OpenCV 中,通常情況下,通道 0 對應(yīng)于藍色(B),通道 1 對應(yīng)于綠色(G),通道2 對應(yīng)于紅色(R)。如果要考慮所有通道,可以使用 [0, 1, 2],而對于單通道,只會考慮圖像的灰度信息,而不考慮顏色信息。使用 [0] 即可表示灰色通道,也可以使用 [1] 或 [2] 表示灰色單通道。B、G、R 單通道的對比效果見下文 討論1#關(guān)于單通道 [0]
  • mask:可選參數(shù),用于指定一個掩碼圖像,以便只計算掩碼中非零元素對應(yīng)的像素值。如果不需要掩碼,可以將其設(shè)置為 None。
    histSize:指定直方圖的 bin 數(shù)量,即要計算的直方圖的維度。它通常以方括號形式傳遞,例如 [256] 表示每個通道有 256 個 bin(256個色卡)。
  • ranges:指定像素值的范圍。通常以方括號形式傳遞,例如 [0, 256] 表示單通道像素值的范圍從 0 到 255。對于彩色圖像,通常設(shè)置為 [0, 256, 0, 256, 0, 256],表示三個通道的范圍。

?

討論1:關(guān)于單通道 [0]

  • 因為通道 0 對應(yīng)的是藍色(B),所以 [0] ,即使用了藍色(B)單通道的灰度圖像,因為灰度圖像中只有一個通道(單通道)。
  • 所以,[1]、[2] 都可以表示單通道的灰度圖像。
  • 同理,[0]、[1]、[2] 雖然都可以表示單通道的灰度圖像,但由于使用的通道分別是 0:藍色(Blue)、1:綠色(Green)、2:紅色(Red),所以,灰度圖像的亮度略有區(qū)別(會影響灰度像素亮度分布)。

效果如下(分別是BGR、RGB、B、G、R):
OpenCV書簽 #直方圖算法的原理與相似圖片搜索實驗,OpenCV,Python,算法,opencv,直方圖算法,python,圖搜索算法,相似圖片搜索,以圖搜圖
示圖代碼:

"""
以圖搜圖:圖像直方圖(Image Histogram)查找相似圖像的原理與實現(xiàn)
測試環(huán)境:win10 | python 3.9.13 | OpenCV 4.4.0 | numpy 1.21.1 | matplotlib 3.7.1
實驗時間:2023-10-27
實例名稱:imgHistogram_v1.2_rgb_split.py
"""

import cv2
import matplotlib.pyplot as plt

# 目標圖像素材庫文件夾路徑
database_dir = '../../P0_Doc/'
# 文件路徑
img_path = database_dir + 'img_data/car-101.jpg'

# 讀取圖像:默認使用BGR加載圖像
img = cv2.imread(img_path)
# 分離通道:將彩色圖像分離成各個通道(R、G、B),然后分別繪制它們的直方圖
img_b, img_g, img_r = cv2.split(img)

# 繪制子圖
plt.figure(figsize=(15, 5))
# 151:表示子圖位于一個 1x5 的網(wǎng)格中的第一個位置。如比第2張圖的位置152,即一行五列第2張圖
# 顯示各通道的圖像
plt.subplot(151)
plt.imshow(img)
plt.title('BGR (Default)')

plt.subplot(152)
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.title('BGR TO RGB')

plt.subplot(153)
plt.imshow(cv2.cvtColor(img_b, cv2.COLOR_BGR2RGB))
plt.title('Blue Channel')

plt.subplot(154)
plt.imshow(cv2.cvtColor(img_g, cv2.COLOR_BGR2RGB))
plt.title('Green Channel')

plt.subplot(155)
plt.imshow(cv2.cvtColor(img_r, cv2.COLOR_BGR2RGB))
plt.title('Red Channel')

plt.show()

代碼對目標圖像進行 R、G、B 通道分離,讀取像素,然后分別繪制它們的直方圖。

下圖中,讀取目標圖像的方式分別是:BGR、RGB、B、G、R,繪畫出來的直方圖灰度像素分布效果如下:
OpenCV書簽 #直方圖算法的原理與相似圖片搜索實驗,OpenCV,Python,算法,opencv,直方圖算法,python,圖搜索算法,相似圖片搜索,以圖搜圖
可以看到,BGR 與 Blue(第1張與第3張)、RGB 與 Red(第2張與第5張)的灰度像素分布趨勢一致。

示圖代碼:

"""
以圖搜圖:圖像直方圖(Image Histogram)查找相似圖像的原理與實現(xiàn)
測試環(huán)境:win10 | python 3.9.13 | OpenCV 4.4.0 | numpy 1.21.1 | matplotlib 3.7.1
實驗時間:2023-10-27
實例名稱:imgHistogram_v1.3_rgb_split.py
"""

import cv2
import matplotlib.pyplot as plt

# 目標圖像素材庫文件夾路徑
database_dir = '../../P0_Doc/'
# 文件路徑
img_path = database_dir + 'img_data/car-101.jpg'

# 讀取圖像:默認使用BGR加載圖像
img = cv2.imread(img_path)
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 分離通道:將彩色圖像分離成各個通道(R、G、B),然后分別繪制它們的直方圖
img_b, img_g, img_r = cv2.split(img)

# 計算各通道的直方圖
hist_bgr = cv2.calcHist([img], [0], None, [256], [0, 256])
hist_rgb = cv2.calcHist([img_rgb], [0], None, [256], [0, 256])
hist_b = cv2.calcHist([img_b], [0], None, [256], [0, 256])
hist_g = cv2.calcHist([img_g], [0], None, [256], [0, 256])
hist_r = cv2.calcHist([img_r], [0], None, [256], [0, 256])

# 繪制線圖子圖展示各通道的直方圖灰度趨勢
plt.subplot(151)
plt.plot(hist_bgr, color='orange')
plt.title('BGR Histogram')

plt.subplot(152)
plt.plot(hist_rgb, color='purple')
plt.title('RGB Histogram')

plt.subplot(153)
plt.plot(hist_b, color='b')
plt.title('Blue Histogram')

plt.subplot(154)
plt.plot(hist_g, color='g')
plt.title('Green Histogram')

plt.subplot(155)
plt.plot(hist_r, color='r')
plt.title('Red Histogram')

plt.show()

如果不好分辨,我們再加上 [0]、[1]、[2] 單通道合成一張直方圖:
OpenCV書簽 #直方圖算法的原理與相似圖片搜索實驗,OpenCV,Python,算法,opencv,直方圖算法,python,圖搜索算法,相似圖片搜索,以圖搜圖
可以清楚看到,合成后的直方圖,只剩下 B、G、R 三通道的灰度像素分布趨勢。

示圖代碼:

"""
以圖搜圖:圖像直方圖(Image Histogram)查找相似圖像的原理與實現(xiàn)
測試環(huán)境:win10 | python 3.9.13 | OpenCV 4.4.0 | numpy 1.21.1 | matplotlib 3.7.1
實驗時間:2023-10-27
實例名稱:imgHistogram_v1.4_rgb_one.py
"""

import cv2
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

# 目標圖像素材庫文件夾路徑
database_dir = '../../P0_Doc/'
# 文件路徑
img_path = database_dir + 'img_data/car-101.jpg'
# 字體路徑
font_path = database_dir + 'fonts/chinese_cht.ttf'

# 讀取圖像
img = cv2.imread(img_path)
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# 分離通道:將彩色圖像分離成各個通道(R、G、B),然后分別繪制它們的直方圖
img_b, img_g, img_r = cv2.split(img)

# 計算各通道的直方圖(依次為 BGR、RGB、0:藍色通道,1:綠色通道,2:紅色通道)
hist_bgr = cv2.calcHist([img], [0], None, [256], [0, 256])
hist_rgb = cv2.calcHist([img_rgb], [0], None, [256], [0, 256])

hist_b = cv2.calcHist([img_b], [0], None, [256], [0, 256])
hist_g = cv2.calcHist([img_g], [0], None, [256], [0, 256])
hist_r = cv2.calcHist([img_r], [0], None, [256], [0, 256])

hist_0 = cv2.calcHist([img], [0], None, [256], [0, 256])
hist_1 = cv2.calcHist([img], [1], None, [256], [0, 256])
hist_2 = cv2.calcHist([img], [2], None, [256], [0, 256])

# 繪制多線線圖,展示各通道的直方圖灰度趨勢
plt.plot(hist_bgr, color='orange', label='BGR')
plt.plot(hist_rgb, color='purple', label='RGB')

plt.plot(hist_b, color='blue', label='Channel Blue')
plt.plot(hist_0, color='blue', label='Channel 0')

plt.plot(hist_g, color='green', label='Channel Green')
plt.plot(hist_1, color='green', label='Channel 1')

plt.plot(hist_r, color='red', label='Channel Red')
plt.plot(hist_2, color='red', label='Channel 2')

# 設(shè)置中文字體
font = FontProperties(fname=font_path, size=14)
plt.title('Histogram(直方圖)', fontproperties=font)
plt.xlabel('Pixel Value(像素值)', fontproperties=font)
plt.ylabel('Frequency(頻率)', fontproperties=font)

# 添加圖例
plt.legend()
# 顯示圖像
plt.show()

計算各通道的直方圖(依次為 BGR,RGB,0:藍色通道,1:綠色通道,2:紅色通道):

  • [0]: 使用 cv2.imread(img_path) 的 img、cv2.split(img) 中的 img_b、[0] 獲得到的灰度像素分布趨勢等同
  • [1]: 使用 cv2.split(img) 中的 img_g、[1] 獲得到的灰度像素分布趨勢等同
  • [2]: 使用 cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 的 img_rgb、cv2.split(img) 中的 img_r、[2] 獲得到的灰度像素分布趨勢等同

所以,[0]、[1]、[2] 都可以表示單通道的灰度圖像,但由于使用的通道分別是 藍色(Blue)、綠色(Green)、紅色(Red),所以,灰度圖像的亮度略有區(qū)別(會影響灰度像素亮度分布),體現(xiàn)在直方圖上,則表現(xiàn)為灰度像素的分布趨勢略有差異。

第三步:直方圖比較

對于兩張圖像的直方圖比較,可以使用不同的距離或相似度度量方法來進行比較。常見的度量方法包括相關(guān)性、卡方距離、巴氏距離等。

"""
以圖搜圖:圖像直方圖(Image Histogram)查找相似圖像的原理與實現(xiàn)
測試環(huán)境:win10 | python 3.9.13 | OpenCV 4.4.0
實驗時間:2023-10-27
實例名稱:imgHistogram_v2.1_graySimilarity.py
"""

import cv2

def get_calcHist(img1_path, img2_path):
    # 讀取圖像
    img1 = cv2.imread(img1_path)
    img2 = cv2.imread(img2_path)

    # 計算圖像灰度單通道直方圖
    img1_hist = cv2.calcHist([img1], [0], None, [256], [0, 256])
    img2_hist = cv2.calcHist([img2], [0], None, [256], [0, 256])

    # 計算直方圖相似度
    # cv2.HISTCMP_CORREL: 相關(guān)性比較,值越接近 1 表示顏色分布越相似
    similarity = cv2.compareHist(img1_hist, img2_hist, cv2.HISTCMP_CORREL)
    print("圖像2與圖像1的相似度(HISTCMP_CORREL/相關(guān)性):", similarity)

    # 或者
    # 計算直方圖的重合度
    degree = 0
    for i in range(len(img1_hist)):
        if img1_hist[i] != img2_hist[i]:
            degree = degree + (1 - abs(img1_hist[i] - img2_hist[i]) / max(img1_hist[i], img2_hist[i]))
        else:
            degree = degree + 1
    degree = degree / len(img1_hist)
    print("圖像2與圖像1的重合度:", degree)
    return similarity


# 目標圖像素材庫文件夾路徑
database_dir = '../../P0_Doc/img_data/'
# 文件路徑
img1_path = database_dir + 'car-101.jpg'
img2_path = database_dir + 'car-102.jpg'

print("圖像1路徑:", img1_path)
print("圖像2路徑:", img2_path)

get_calcHist(img1_path, img2_path)

輸出打?。?/p>

圖像1路徑: ../../P0_Doc/img_data/car-101.jpg
圖像2路徑: ../../P0_Doc/img_data/car-102.jpg
圖像2與圖像1的相似度(HISTCMP_CORREL/相關(guān)性): 1.0
圖像2與圖像1的重合度: 1.0

說明:圖像2是圖像1的180度倒置圖。

cv2.compareHistOpenCV 中用于比較直方圖相似度的函數(shù)。用于計算兩個直方圖之間的相關(guān)性(correlation)。img1_hist 和 img2_hist 是兩個直方圖,它們分別代表兩幅圖像的顏色分布。

直方圖的比較方法:

  • cv2.HISTCMP_CORREL(相關(guān)性): 計算兩個直方圖之間的相關(guān)性。相關(guān)性的值越接近1,表示兩幅圖像的顏色分布越相似,值越接近-1表示顏色分布越不相似,值接近0表示中等相似度。但不太適用于顏色直方圖比較。
  • cv2.HISTCMP_CHISQR(卡方距離): 計算卡方距離,用于比較兩個直方圖之間的差異。值越接近 0 表示顏色分布越相似。
  • cv2.HISTCMP_INTERSECT(交集性): 計算兩個直方圖的交集,用于度量它們的相似度。該值越大表示相似度越高。
  • cv2.HISTCMP_BHATTACHARYYA(巴氏距離): 計算兩個直方圖之間的巴氏距離。值越接近 0 表示顏色分布越相似。

?

討論2:直方圖相似度函數(shù)
使用 cv2.compareHist(),不同的直方圖比較方法,對比結(jié)果略有差異。這里,我們使用 [0] 作為灰度通道進行測試實驗。

"""
以圖搜圖:圖像直方圖(Image Histogram)查找相似圖像的原理與實現(xiàn)
測試環(huán)境:win10 | python 3.9.13 | OpenCV 4.4.0
實驗時間:2023-10-27
實例名稱:imgHistogram_v2.3_compareHist.py
"""

import cv2
import os

def get_degreeHist(img1_hist, img2_hist):
    # 計算直方圖的重合度
    degree = 0
    for i in range(len(img1_hist)):
        if img1_hist[i] != img2_hist[i]:
            degree = degree + (1 - abs(img1_hist[i] - img2_hist[i]) / max(img1_hist[i], img2_hist[i]))
        else:
            degree = degree + 1
    degree = degree / len(img1_hist)
    return degree


def all_compareHist(img1_path, img2_path):
    img1 = cv2.imread(img1_path)
    img2 = cv2.imread(img2_path)

    img1_hist = cv2.calcHist([img1], [0], None, [256], [0, 256])
    img2_hist = cv2.calcHist([img2], [0], None, [256], [0, 256])

    similarity = get_degreeHist(img1_hist, img2_hist)
    print(f"圖像 {os.path.basename(img2_path)} 與目標圖像 {os.path.basename(img1_path)} 的相似度:", similarity)

    # 計算直方圖相似度
    # cv2.HISTCMP_BHATTACHARYYA: 巴氏距離比較,值越接近 0 表示顏色分布越相似
    similarity = cv2.compareHist(img1_hist, img2_hist, cv2.HISTCMP_BHATTACHARYYA)
    print(f"圖像 {os.path.basename(img2_path)} 與目標圖像 {os.path.basename(img1_path)} 的相似度(HISTCMP_BHATTACHARYYA/巴氏距離):", similarity)

    # cv2.HISTCMP_CHISQR: 卡方比較,值越接近 0 表示顏色分布越相似
    similarity = cv2.compareHist(img1_hist, img2_hist, cv2.HISTCMP_CHISQR)
    print(f"圖像 {os.path.basename(img2_path)} 與目標圖像 {os.path.basename(img1_path)} 的相似度(HISTCMP_CHISQR/卡方比較):", similarity)

    # cv2.HISTCMP_CORREL: 相關(guān)性比較,值越接近 1 表示顏色分布越相似
    similarity = cv2.compareHist(img1_hist, img2_hist, cv2.HISTCMP_CORREL)
    print(f"圖像 {os.path.basename(img2_path)} 與目標圖像 {os.path.basename(img1_path)} 的相似度(HISTCMP_CORREL/相關(guān)性):", similarity)

    # cv2.HISTCMP_INTERSECT: 直方圖交集比較,值越大表示顏色分布越相似
    similarity = cv2.compareHist(img1_hist, img2_hist, cv2.HISTCMP_INTERSECT)
    print(f"圖像 {os.path.basename(img2_path)} 與目標圖像 {os.path.basename(img1_path)} 的相似度(HISTCMP_INTERSECT/交集比較):", similarity)
    return similarity

# 目標圖像素材庫文件夾路徑
database_dir = '../../P0_Doc/img_data/'
# 文件路徑
img1_path = database_dir + 'car-101.jpg'
img2_path = database_dir + 'car-102.jpg'
img2_path = database_dir + 'car-103.jpg'

all_compareHist(img1_path, img2_path)

輸出打?。?/p>

圖像 car-102.jpg 與目標圖像 car-101.jpg 的相似度: 1.0
圖像 car-102.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_BHATTACHARYYA/巴氏距離): 0.0
圖像 car-102.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_CHISQR/卡方比較): 0.0
圖像 car-102.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_CORREL/相關(guān)性): 1.0
圖像 car-102.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_INTERSECT/交集比較): 1232154.0

圖像 car-103.jpg 與目標圖像 car-101.jpg 的相似度: [0.6923658]
圖像 car-103.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_BHATTACHARYYA/巴氏距離): 0.2135487778250319
圖像 car-103.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_CHISQR/卡方比較): 11867327.715396598
圖像 car-103.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_CORREL/相關(guān)性): 0.4266303485505497
圖像 car-103.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_INTERSECT/交集比較): 972986.0

?

討論3:彩色圖像直方圖

"""
以圖搜圖:圖像直方圖(Image Histogram)查找相似圖像的原理與實現(xiàn)
測試環(huán)境:win10 | python 3.9.13 | OpenCV 4.4.0
實驗時間:2023-10-27
實例名稱:imgHistogram_v2.4_rgb_compareHist.py
"""

import cv2
import os

def bgr_compareHist(img1_path, img2_path):
    img1 = cv2.imread(img1_path)
    img2 = cv2.imread(img2_path)

    img1_hist = cv2.calcHist([img1], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256])
    img2_hist = cv2.calcHist([img2], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256])

    # 計算直方圖相似度
    # cv2.HISTCMP_BHATTACHARYYA: 巴氏距離比較,值越接近 0 表示顏色分布越相似
    similarity = cv2.compareHist(img1_hist, img2_hist, cv2.HISTCMP_BHATTACHARYYA)
    print(f"圖像 {os.path.basename(img2_path)} 與目標圖像 {os.path.basename(img1_path)} 的相似度(HISTCMP_BHATTACHARYYA/巴氏距離):", similarity)

    # cv2.HISTCMP_CHISQR: 卡方比較,值越接近 0 表示顏色分布越相似
    similarity = cv2.compareHist(img1_hist, img2_hist, cv2.HISTCMP_CHISQR)
    print(f"圖像 {os.path.basename(img2_path)} 與目標圖像 {os.path.basename(img1_path)} 的相似度(HISTCMP_CHISQR/卡方比較):", similarity)

    # cv2.HISTCMP_CORREL: 相關(guān)性比較,值越接近 1 表示顏色分布越相似
    similarity = cv2.compareHist(img1_hist, img2_hist, cv2.HISTCMP_CORREL)
    print(f"圖像 {os.path.basename(img2_path)} 與目標圖像 {os.path.basename(img1_path)} 的相似度(HISTCMP_CORREL/相關(guān)性):", similarity)

    # cv2.HISTCMP_INTERSECT: 直方圖交集比較,值越大表示顏色分布越相似
    similarity = cv2.compareHist(img1_hist, img2_hist, cv2.HISTCMP_INTERSECT)
    print(f"圖像 {os.path.basename(img2_path)} 與目標圖像 {os.path.basename(img1_path)} 的相似度(HISTCMP_INTERSECT/交集比較):", similarity)
    return similarity
    
# 目標圖像素材庫文件夾路徑
database_dir = '../../P0_Doc/img_data/'
# 文件路徑
img1_path = database_dir + 'car-101.jpg'
img2_path = database_dir + 'car-102.jpg'
img2_path = database_dir + 'car-103.jpg'

bgr_compareHist(img1_path, img2_path)

輸出打?。?/p>

圖像 car-102.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_BHATTACHARYYA/巴氏距離): 0.0
圖像 car-102.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_CHISQR/卡方比較): 0.0
圖像 car-102.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_CORREL/相關(guān)性): 1.0
圖像 car-102.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_INTERSECT/交集比較): 1232154.0

圖像 car-103.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_BHATTACHARYYA/巴氏距離): 0.25780152883475765
圖像 car-103.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_CHISQR/卡方比較): 981578.8189641015
圖像 car-103.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_CORREL/相關(guān)性): 0.8933747646918704
圖像 car-103.jpg 與目標圖像 car-101.jpg 的相似度(HISTCMP_INTERSECT/交集比較): 911172.0

對比 討論2:直方圖相似度函數(shù) 的輸出結(jié)果,可以看到,相同測試圖像,彩色直方圖的相似度 與 灰度直方圖的相似度 有一點差異,原因就是,通過單通道的灰度直方圖,可以捕捉到圖像的整體亮度和對比度信息,而不受顏色的影響。在相似圖片查找中,通常更關(guān)注圖像的結(jié)構(gòu)和紋理,因此灰度信息更具代表性。

第四步:相似度評估

根據(jù)直方圖比較的結(jié)果(似度得分),進行目標圖像相似度評估。
案例場景:圖像測試素材庫中,查找所有圖像,找出與目標圖像相似值小于等于0.5的圖像。

    ......
    
    for similarity in similarities:
        if (similarity[1] <= 0.5):
            print(f"圖像名稱:{similarity[0]},與目標圖像 {os.path.basename(img_org_path)} 的近似值:{similarity[1]}")

?

4.2 測試

實驗場景

通過 opencv,使用直方圖算法查找目標圖像素材庫中所有符合期望值的相似圖像。

實驗素材

這里,我準備了45張素材圖像,其中14張圖像為水果,其余為不同類型的汽車,但形態(tài)不一。
OpenCV書簽 #直方圖算法的原理與相似圖片搜索實驗,OpenCV,Python,算法,opencv,直方圖算法,python,圖搜索算法,相似圖片搜索,以圖搜圖

實驗代碼

"""
以圖搜圖:圖像直方圖(Image Histogram)查找相似圖像的原理與實現(xiàn)
測試環(huán)境:win10 | python 3.9.13 | OpenCV 4.4.0 | numpy 1.21.1 | matplotlib 3.7.1
實驗場景:圖像測試素材庫中,查找所有圖像,找出與目標圖像相似值小于等于0.7的圖像
實驗時間:2023-10-27
實例名稱:imgHistogram_v3.2_gray_show.py
"""

import os
import time
import cv2
import matplotlib.pyplot as plt

def get_calcHist(org_img_hist, img_path):
    # 讀取圖像:通過OpenCV的imread加載RGB圖像
    img = cv2.imread(img_path)
    # img = cv2.cvtColor(cv2.imread(img_path), cv2.COLOR_BGR2GRAY)
    img_hist = cv2.calcHist([img], [0], None, [256], [0, 256])

    # 計算直方圖相似度
    # cv2.HISTCMP_CORREL: 相關(guān)性比較,值越接近 1 表示顏色分布越相似
    # cv2.HISTCMP_CHISQR: 卡方比較,值越接近 0 表示顏色分布越相似
    # cv2.HISTCMP_BHATTACHARYYA: 巴氏距離比較,值越接近 0 表示顏色分布越相似
    # cv2.HISTCMP_INTERSECT: 直方圖交集比較,值越大表示顏色分布越相似
    similarity = cv2.compareHist(org_img_hist, img_hist, cv2.HISTCMP_BHATTACHARYYA)
    return similarity

def show_similar_images(similar_images, images_per_column=3):
    # 計算總共的圖片數(shù)量
    num_images = len(similar_images)
    # 計算所需的行數(shù)
    num_rows = (num_images + images_per_column - 1) // images_per_column

    # 創(chuàng)建一個子圖,每行顯示 images_per_column 張圖片
    fig, axes = plt.subplots(num_rows, images_per_column, figsize=(12, 15), squeeze=False)
    
    # 遍歷每一行
    for row in range(num_rows):
        # 遍歷每一列
        for col in range(images_per_column):
            # 計算當前圖片在列表中的索引
            index = row * images_per_column + col
            # 檢查索引是否越界
            if index < num_images:
                # 獲取當前相似圖片的路徑和相似度
                image_path = similar_images[index][0]
                similarity = similar_images[index][1]
                
                # 讀取圖片并轉(zhuǎn)換顏色通道
                image = cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2RGB)

                # 在子圖中顯示圖片
                axes[row, col].imshow(image)
                # 設(shè)置子圖標題,包括圖片路徑和相似度
                axes[row, col].set_title(f"Similar Image: {os.path.basename(image_path)} \n Similar Score: {similarity:.4f}")
                # 關(guān)閉坐標軸
                axes[row, col].axis('off')
    # 顯示整個圖
    plt.show()

# ------------------------------------------------ 測試 ------------------------------------------------
if __name__ == '__main__':
    time_start = time.time()

    # 指定測試圖像庫目錄
    img_dir = '../../P0_Doc/img_data/'
    # 指定測試圖像文件擴展名
    img_suffix = ['.jpg', '.jpeg', '.png', '.bmp', '.gif']

    # 獲取當前執(zhí)行腳本所在目錄
    script_dir = os.path.dirname(__file__)
    # 獲取目標測試圖像的全路徑
    img_org_path = os.path.join(script_dir, img_dir, 'apple-101.jpg')
    # 加載要查詢的圖像
    query_image = cv2.imread(img_org_path)
    # query_image = cv2.cvtColor(cv2.imread(img_org_path), cv2.COLOR_BGR2GRAY)

    # 計算查詢圖像的直方圖:灰度直方圖算法
    img_org_hist = cv2.calcHist([query_image], [0], None, [256], [0, 256])
    print(f"目標圖像:{os.path.relpath(img_org_path)}")

    # 獲取測試圖像庫中所有文件
    all_files = os.listdir(os.path.join(script_dir, img_dir))
    # 篩選出指定后綴的圖像文件
    img_files = [file for file in all_files if any(file.endswith(suffix) for suffix in img_suffix)]

    # 存儲相似度值和對應(yīng)的圖像路徑
    img_search_results = []
    # 遍歷測試圖像庫中的每張圖像
    for img_file in img_files:
        # 獲取相似圖像文件路徑
        img_path = os.path.join(script_dir, img_dir, img_file)
        # 獲取相似圖像可識別哈希值(圖像指紋)
        similarity = get_calcHist(img_org_hist, img_path)
        # print(f"圖像名稱:{img_path},與目標圖像 {os.path.basename(img_org_path)} 的近似值:{similarity}")

        if (similarity <= 0.7):
            # 存儲相似度值和對應(yīng)的圖像路徑
            img_search_results.append((os.path.relpath(img_path), similarity))

    # 按相似度升序排序
    img_search_results.sort(key=lambda item: item[1])

    for img_similarity in img_search_results:
        print(f"圖像名稱:{img_similarity[0]},與目標圖像 {os.path.basename(img_org_path)} 的相似值:{img_similarity[1]}")

    time_end = time.time()
    print(f"耗時:{time_end - time_start}")

    # 顯示目標相似圖像
    show_similar_images(img_search_results)

多圖相似查找效果顯示,實驗代碼使用的是巴氏距離比較,值越接近 0 表示顏色分布越相似:
OpenCV書簽 #直方圖算法的原理與相似圖片搜索實驗,OpenCV,Python,算法,opencv,直方圖算法,python,圖搜索算法,相似圖片搜索,以圖搜圖

輸出打印:

目標圖像:..\..\P0_Doc\img_data\apple-101.jpg
圖像名稱:..\..\P0_Doc\img_data\apple-101.jpg,與目標圖像 apple-101.jpg 的相似值:0.0
圖像名稱:..\..\P0_Doc\img_data\apple-104.jpg,與目標圖像 apple-101.jpg 的相似值:0.0
圖像名稱:..\..\P0_Doc\img_data\car-109.jpg,與目標圖像 apple-101.jpg 的相似值:0.6158102157213413
圖像名稱:..\..\P0_Doc\img_data\car-103.jpg,與目標圖像 apple-101.jpg 的相似值:0.662176197294615
圖像名稱:..\..\P0_Doc\img_data\car-101.jpg,與目標圖像 apple-101.jpg 的相似值:0.6813075243521007
圖像名稱:..\..\P0_Doc\img_data\car-102.jpg,與目標圖像 apple-101.jpg 的相似值:0.6813075243521007
圖像名稱:..\..\P0_Doc\img_data\Q3-09.jpg,與目標圖像 apple-101.jpg 的相似值:0.6844184531149912
圖像名稱:..\..\P0_Doc\img_data\car-108.jpg,與目標圖像 apple-101.jpg 的相似值:0.6861940450661771
圖像名稱:..\..\P0_Doc\img_data\X3-09.jpg,與目標圖像 apple-101.jpg 的相似值:0.692340714053627
圖像名稱:..\..\P0_Doc\img_data\apple-114.jpg,與目標圖像 apple-101.jpg 的相似值:0.6932278615425139
圖像名稱:..\..\P0_Doc\img_data\apple-112.jpg,與目標圖像 apple-101.jpg 的相似值:0.6959175186621991
圖像名稱:..\..\P0_Doc\img_data\pear-201.jpg,與目標圖像 apple-101.jpg 的相似值:0.6997766670329476
耗時:1.0362038612365723

?

5. 總結(jié)

總體來說,直方圖算法屬于一種傳統(tǒng)外觀相似算法,適用于一些簡單的圖像相似性比較問題,但直方圖反應(yīng)的是圖像灰度值得概率分布,并沒有圖像的空間位置信息在里面,因此,可能會出現(xiàn)誤判。比如紋理結(jié)構(gòu)相同,但明暗不同的圖像,應(yīng)該相似度很高,但實際結(jié)果是相似度很低,而紋理結(jié)構(gòu)不同,但明暗相近的圖像,相似度卻很高。

優(yōu)點

  1. 簡單直觀: 直方圖是一種簡單直觀的圖像表達方式,易于理解和實現(xiàn)。
  2. 快速計算: 直方圖的計算相對快速,特別是對于小尺寸的圖像。
  3. 顏色不變性: 直方圖在某種程度上對顏色的變化具有不變性,因此可以在一定程度上應(yīng)對圖像的輕微變形。
  4. 對光照變化有一定的魯棒性: 直方圖可以在一定程度上處理圖像的光照變化。

缺點

  1. 不考慮空間信息: 直方圖方法忽略了圖像的空間信息,對于圖像的排列、結(jié)構(gòu)等方面的變化較為敏感。
  2. 受噪聲影響: 如果圖像受到噪聲的影響,直方圖會受到一定程度的干擾。
  3. 灰度信息有限: 灰度直方圖只考慮了像素的灰度信息,對于顏色信息較為有限。
  4. 無法處理形狀變化: 直方圖方法難以處理圖像中物體的形狀變化。

?

6. 系列書簽

OpenCV書簽 #均值哈希算法的原理與相似圖片搜索實驗
OpenCV書簽 #感知哈希算法的原理與相似圖片搜索實驗
OpenCV書簽 #差值哈希算法的原理與相似圖片搜索實驗
OpenCV書簽 #直方圖算法的原理與相似圖片搜索實驗文章來源地址http://www.zghlxwxcb.cn/news/detail-817666.html

到了這里,關(guān)于OpenCV書簽 #直方圖算法的原理與相似圖片搜索實驗的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 基于直方圖相似性的圖像分類算法FPGA實現(xiàn),包括tb測試文件和MATLAB輔助驗證

    基于直方圖相似性的圖像分類算法FPGA實現(xiàn),包括tb測試文件和MATLAB輔助驗證

    目錄 1.算法運行效果圖預(yù)覽 2.算法運行軟件版本 3.部分核心程序 4.算法理論概述 5.算法完整程序工程 MATLAB測試結(jié)果: FPGA測試結(jié)果: 上述仿真圖中,紅色XX表示圖像讀取完畢。因此輸出XX。當圖像輸出完成之后,最下面的相似性指標 same1輸出為11226,same2輸出為67584.即圖1和圖

    2024年04月09日
    瀏覽(22)
  • 【OpenCV學習筆記30】- OpenCV 中的直方圖 - 直方圖 - 4:直方圖反投影

    【OpenCV學習筆記30】- OpenCV 中的直方圖 - 直方圖 - 4:直方圖反投影

    這是對于 OpenCV 官方文檔中 圖像處理 的學習筆記。學習筆記中會記錄官方給出的例子,也會給出自己根據(jù)官方的例子完成的更改代碼,同樣彩蛋的實現(xiàn)也會結(jié)合多個知識點一起實現(xiàn)一些小功能,來幫助我們對學會的知識點進行結(jié)合應(yīng)用。 如果有喜歡我筆記的請麻煩幫我關(guān)注

    2024年03月26日
    瀏覽(29)
  • OpenCV10-圖像直方圖:直方圖繪制、直方圖歸一化、直方圖比較、直方圖均衡化、直方圖規(guī)定化、直方圖反射投影

    圖像直方圖就是統(tǒng)計圖像中每個灰度值的個數(shù),之后將灰度值作為橫軸,以灰度值個數(shù)或者灰度值所占比率作為縱軸的統(tǒng)計圖。通過直方圖,可以看出圖像中哪些灰度值數(shù)目較多,哪些較少,可以通過一定的方法將灰度值較為集中的區(qū)域映射到較為稀疏的區(qū)域,從而使圖像在

    2024年01月16日
    瀏覽(23)
  • 【OpenCV ? c++】自定義直方圖 | 灰度直方圖均衡 | 彩色直方圖均衡

    ??直方圖廣泛應(yīng)用于很多計算機視覺處理當中。通過標記幀與幀之間顯著的邊緣和顏色的變化,可以檢測視頻中的場景變化。在每個興趣點設(shè)置一個有相似特征的直方圖所構(gòu)成的“標簽”,可以用來標記各種不同的事情,比如圖像的色彩分布,物體邊緣梯度模板等等。是計

    2024年02月08日
    瀏覽(20)
  • 【OpenCV ? c++】直方圖計算 | 繪制 H-S 直方圖 | 繪制一維直方圖 | 繪制 RGB 三色直方圖

    ??直方圖廣泛應(yīng)用于很多計算機視覺處理當中。通過標記幀與幀之間顯著的邊緣和顏色的變化,可以檢測視頻中的場景變化。在每個興趣點設(shè)置一個有相似特征的直方圖所構(gòu)成的“標簽”,可以用來標記各種不同的事情,比如圖像的色彩分布,物體邊緣梯度模板等等。是計

    2024年02月09日
    瀏覽(18)
  • Baumer工業(yè)相機堡盟工業(yè)相機如何聯(lián)合BGAPISDK和OpenCV實現(xiàn)圖像的直方圖算法增強(C++)

    Baumer工業(yè)相機堡盟工業(yè)相機如何聯(lián)合BGAPISDK和OpenCV實現(xiàn)圖像的直方圖算法增強(C++)

    Baumer工業(yè)相機堡盟相機是一種高性能、高質(zhì)量的工業(yè)相機,可用于各種應(yīng)用場景,如物體檢測、計數(shù)和識別、運動分析和圖像處理。 Baumer的萬兆網(wǎng)相機擁有出色的圖像處理性能,可以實時傳輸高分辨率圖像。此外,該相機還具有快速數(shù)據(jù)傳輸、低功耗、易于集成以及高度可擴

    2024年02月01日
    瀏覽(21)
  • 【opencv】教程代碼 —Histograms_Matching(2)計算直方圖、直方圖比較、直方圖均衡、模板匹配...

    【opencv】教程代碼 —Histograms_Matching(2)計算直方圖、直方圖比較、直方圖均衡、模板匹配...

    計算直方圖 直方圖比較 圖像進行直方圖均衡化處理 模板匹配 1.?calcHist_Demo.cpp?計算直方圖 這段代碼的功能是加載圖像,分離圖像的三個顏色通道,然后分別計算這三個通道的直方圖,繪制出來并顯示結(jié)果。直方圖是圖像中像素值分布的圖形表示,可以用于圖像分析或圖像處

    2024年04月11日
    瀏覽(21)
  • opencv直方圖

    在OpenCV中,直方圖是一個重要的圖像分析工具,它可以提供關(guān)于圖像亮度分布的詳細信息。OpenCV提供了多種方法來計算和操作圖像的直方圖。 基本概念 直方圖是一個離散函數(shù),它將圖像中的像素值映射到一個連續(xù)的區(qū)間上,并計算每個區(qū)間內(nèi)像素的數(shù)量。對于灰度圖像,直

    2024年04月28日
    瀏覽(21)
  • 【OpenCV--直方圖】

    【OpenCV--直方圖】

    目錄 一、直方圖是什么? 1.描述: 2.相關(guān)術(shù)語: 二、直方圖的計算和繪制 三、掩膜的應(yīng)用 四、直方圖均衡化: 五、自適應(yīng)的直方圖均衡化 1.描述: 1直方圖是對數(shù)據(jù)進行統(tǒng)計的一種方法,并且將統(tǒng)計值組織到一系列實現(xiàn)定義好的bin(直條/組距)當中。bin的數(shù)值可以是梯度、方

    2024年02月05日
    瀏覽(24)
  • opencv-2D直方圖

    opencv-2D直方圖

    cv2.calcHist() 是 OpenCV 中用于計算直方圖的函數(shù)。它可以計算一維或多維直方圖,用于分析圖像中像素值的分布。 基本的語法如下: 參數(shù)說明: images : 輸入圖像, 可以是單通道或多通道圖像 。在計算多通道圖像的直方圖時,要將通道分別傳遞給 channels 參數(shù)。 channels : 要考慮

    2024年02月20日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包