首頁>技術>

緊接昨天的分享,這是第二部分的教程,我們採用一個示例的方式來介紹 OpenCV 的一些基礎函式。

影象直方圖

直方圖是可以顯示資料在一定範圍內分佈的一種代表性的方式。

對於影象,直方圖表示畫素點的顏色分佈情況,給出了影象中某些顏色出現頻率的機率概念。例如,直方圖可以用於自動影象分割、運動檢測和粒度分析。

在使用 openCV 中,我們有一個 bult-in 函式來為我們完成這項工作:

cv2.calcHist([image], channels, mask, histSize, ranges[, hist[, accumulate]])

image:輸入uint8或 float32型別的圖片,資料放在方括號[]中;channels:也在方括號[]中給出,它是我們計算直方圖的通道索引。例如,如果輸入的影象是灰度影象,它的值是[0]。對於彩色影象,可以透過[0]、[1]或[2]分別計算藍色、綠色和紅色通道的直方圖;mask:如果要找到完整影象的直方圖,我們可以傳遞“None” ,但是如果你想計算一個特定區域的直方圖,它需要一個 Mask 影象來表示這個區域;HistSize:表示繪製的資料的bin的數目。也應該在方括號中給出,對於全部資料,我們傳遞 [256];ranges: 畫素值範圍,通常為[0,256]。

在本教程中,我們將要均衡圖片的(灰度)直方圖,即重新分佈圖像的畫素強度。總之,它提高了影象的對比度。

在 OpenCV 中,我們還有一個函式用於對影象進行均衡,稱為 equalizeHist,它只將影象作為引數進行均衡。現在,透過呼叫影象上的兩個函式,我們可以計算原始影象的直方圖,然後計算均衡影象的直方圖。

import cv2nbins = 256image = cv2.imread("lenna.png", 0)cv2.imshow("Normal", image)hist = cv2.calcHist([image], [0], None, [256], [0,256])cv2.waitKey(0)image = cv2.equalizeHist(image)cv2.imshow("Equalized", image)hist2 = cv2.calcHist([image], [0], None, [nbins], [0,256])cv2.waitKey(0)

原影象

均衡化處理後的影象

我們可能想看看這兩個圖片的直方圖是什麼樣子的。函式 calcHist ()執行的直方圖計算不返回影象,而是返回繪圖表資料。為了繪製直方圖,我們使用 matplotlib 庫。

from  matplotlib import pyplot as plt plt.plot(hist, 'b')plt.plot(hist2, 'r')plt.xlim([0,nbins])plt.show()cv2.waitKey(0)    cv2.destroyAllWindows()

示例:依據直方圖的運動檢測器

現在假設我們有一個連續的場景捕獲,並且我們繼續計算幀的直方圖。如果直方圖改變了,那就意味著有新的東西出現了,如果新的直方圖有很大的不同,我們可以做出假設或者設定警報。

為了解決這個問題,我們將引入攝像頭功能來連續捕捉影象。類似地,所有到目前為止使用的函式,OpenCV 有一個 VideoCapture,然後我們透過此建立物件用於讀取相機的幀,通常用於測試攝像頭。

為了保持從相機捕捉幀,我們要迴圈相機讀取,因此計算其直方圖。為了讓這個問題更容易解決,我們使用了灰度影象,使用 OpenCV 中的函式 cvtColor 將影象從相機中轉換出來。

import cv2 camera = cv2.VideoCapture(0) # parameter 0 for webcam, 1 for second camera etcmaxDist = 2000while True:    #camera.read() returns a bool. If frame is read correctly, it will be True.    #Capture frame-by-frame    return_value, image = camera.read()    if return_value:        gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)        cv2.imshow("image",  gray_image)        H1 = cv2.calcHist( gray_image, [0], None, [256], [0,256])        H2 = cv2.calcHist(gray_image, [0], None, [256], [0,256])

我們此處使用卡方距離比較直方圖,它可以用來衡量兩個直方圖之間的不同。你不需要完全理解這個概念,我們只需要在一個確定的場景中觀察其數值的變化,對於這個度量結果,其值越小,兩個直方圖的匹配越好。

在下面的示例中,我們採用的直方圖差值為2000,對於該示例,2000 的數值可能並不是一個劇烈的變化,但是存在明顯變化。

因此,如果我們計算得到的差異值超過2000,就可以做出一些其他操作。此處為了得到一個明顯的改變,我們實現了一個全白邊框的改變。以下示例僅供參考:

comp = cv2.compareHist(H1, H2, cv2.HISTCMP_CHISQR)                height, width = gray_image.shape        while comp >= maxDist:            for x in range(height):                gray_image[x,0] = 255                gray_image[x, width-1] = 255                        for y in range(width):                gray_image[0,y] = 255                                    gray_image[height-1, y] = 255                        cv2.imshow("image",  gray_image)                        H1 = cv2.calcHist( gray_image, [0], None, [256], [0,256])            H2 = cv2.calcHist(gray_image, [0], None, [256], [0,256])            comp = cv2.compareHist(H1, H2, cv2.HISTCMP_CHISQR)            print(comp)                                     cv2.waitKey(0)                camera.release()        cv2.destroyAllWindows()    else:         camera.release()        break

最後,我們對相機物件進行釋放,使相機可以正確關閉,不會導致程式崩潰。

· END ·

23
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 最簡單的易班打卡指令碼!可以自動打卡了