在 Fedora Linux 上使用 OpenCV(一)
封面圖片選自文森特·梵高的《星空》,公共領(lǐng)域,通過維基共享資源發(fā)布
技術(shù)世界每天都在變化,對(duì)計(jì)算機(jī)視覺、人工智能和機(jī)器學(xué)習(xí)的需求也在增加。讓計(jì)算機(jī)和手機(jī)能夠看到周圍環(huán)境的技術(shù)被稱為 計(jì)算機(jī)視覺。這個(gè)重新創(chuàng)造人眼的工作始于 50 年代。從那時(shí)起,計(jì)算機(jī)視覺技術(shù)有了長足的發(fā)展。計(jì)算機(jī)視覺已經(jīng)通過不同的應(yīng)用進(jìn)入了我們的手機(jī)。這篇文章將介紹 Fedora Linux 上的 OpenCV。
什么是 OpenCV?
OpenCV(開源計(jì)算機(jī)視覺庫)是一個(gè)開源的計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)軟件庫。OpenCV 的建立是為了給計(jì)算機(jī)視覺應(yīng)用提供一個(gè)通用的基礎(chǔ)設(shè)施,并加速機(jī)器感知在商業(yè)產(chǎn)品中的應(yīng)用。它有超過 2500 種優(yōu)化后的算法,其中包括一套全面的經(jīng)典和最先進(jìn)的計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)算法。這些算法可用于檢測(cè)和識(shí)別人臉、識(shí)別物體、對(duì)視頻中的人類行為進(jìn)行分類,并建立標(biāo)記,將其與增強(qiáng)現(xiàn)實(shí)疊加等等。
在 Fedora Linux 上安裝 OpenCV
要開始使用 OpenCV,請(qǐng)從 Fedora Linux 倉庫中安裝它:
$ sudo dnf install opencv opencv-contrib opencv-doc python3-opencv python3-matplotlib python3-numpy
注意: 在 Fedora Silverblue 或 CoreOS 上,Python 3.9 是核心提交的一部分。用以下方法安裝 OpenCV 和所需工具:
rpm-ostree install opencv opencv-doc python3-opencv python3-matplotlib python3-numpy
接下來,在終端輸入以下命令,以驗(yàn)證 OpenCV 是否已經(jīng)安裝:
$ python
Python 3.9.6 (default, Jul 16 2021, 00:00:00)
[GCC 11.1.1 20210531 (Red Hat 11.1.1-3)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2 as cv
>>> print( cv.__version__ )
4.5.2
>>> exit()
當(dāng)你輸入 print
命令時(shí),應(yīng)該顯示當(dāng)前的 OpenCV 版本,如上圖所示。這表明 OpenCV 和 Python-OpenCV 庫已經(jīng)成功安裝。
此外,如果你想用 Jupyter Notebook 做筆記和寫代碼,并了解更多關(guān)于數(shù)據(jù)科學(xué)工具的信息,請(qǐng)查看早期的 Fedora Magazine 文章:Fedora 中的 Jupyter 和數(shù)據(jù)科學(xué)。
開始使用 OpenCV
安裝完成后,使用 Python 和 OpenCV 庫加載一個(gè)樣本圖像(按 S
鍵以 png 格式保存圖像的副本并完成程序):
$ cp /usr/share/opencv4/samples/data/starry_night.jpg .
$ python starry_night.py
starry_night.py
的內(nèi)容:
import cv2 as cv
import sys
img = cv.imread(cv.samples.findFile("starry_night.jpg"))
if img is None:
sys.exit("Could not read the image.")
cv.imshow("Display window", img)
k = cv.waitKey(0)
if k == ord("s"):
cv.imwrite("starry_night.png", img)
通過在 cv.imread
函數(shù)中添加參數(shù) 0
,對(duì)圖像進(jìn)行灰度處理,如下所示。
img = cv.imread(cv.samples.findFile("starry_night.jpg"),0)
這些是一些可以用于 cv.imread
函數(shù)的第二個(gè)參數(shù)的替代值:
cv2.IMREAD_GRAYSCALE
或0
:以灰度模式加載圖像。cv2.IMREAD_COLOR** 或
1`:以彩色模式載入圖像。圖像中的任何透明度將被移除。這是默認(rèn)的。cv2.IMREAD_UNCHANGED** 或
-1`:載入未經(jīng)修改的圖像。包括 alpha 通道。
使用 OpenCV 顯示圖像屬性
圖像屬性包括行、列和通道的數(shù)量、圖像數(shù)據(jù)的類型、像素的數(shù)量等等。假設(shè)你想訪問圖像的形狀和它的數(shù)據(jù)類型。你可以這樣做:
import cv2 as cv
img = cv.imread(cv.samples.findFile("starry_night.jpg"))
print("Image size is", img.shape)
print("Data type of image is", img.dtype)
Image size is (600, 752, 3)
Data type of image is uint8
print(f"Image 2D numpy array \n {img}")
Image 2D numpy array
[[[0 0 0]
[0 0 0]
[0 0 0]
...
[0 0 0]
[0 0 0]
[0 0 0]]
[[0 0 0]
[0 0 0]
[0 0 0]
...
img.shape
:返回一個(gè)行數(shù)、列數(shù)和通道數(shù)的元組(如果是彩色圖像)。img.dtype
:返回圖像的數(shù)據(jù)類型。
接下來用 Matplotlib 顯示圖像:
import cv2 as cv
import matplotlib.pyplot as plt
img = cv.imread(cv.samples.findFile("starry_night.jpg"),0)
plt.imshow(img)
plt.show()
發(fā)生了什么?
該圖像是作為灰度圖像讀入的,但是當(dāng)使用 Matplotlib 的 imshow
函數(shù)時(shí),它不一定會(huì)以灰度顯示。這是因?yàn)?nbsp;imshow
函數(shù)默認(rèn)使用不同的顏色映射。要指定使用灰度顏色映射,請(qǐng)將 imshow
函數(shù)的第二個(gè)參數(shù)設(shè)置為 cmap='gray'
,如下所示:
plt.imshow(img,cmap='gray')
這個(gè)問題在以彩色模式打開圖片時(shí)也會(huì)發(fā)生,因?yàn)?Matplotlib 期望圖片為 RGB(紅、綠、藍(lán))格式,而 OpenCV 則以 BGR(藍(lán)、綠、紅)格式存儲(chǔ)圖片。為了正確顯示,你需要將 BGR 圖像的通道反轉(zhuǎn)。
import cv2 as cv
import matplotlib.pyplot as plt
img = cv.imread(cv.samples.findFile("starry_night.jpg"),cv.IMREAD_COLOR)
fig, (ax1, ax2) = plt.subplots(1,2)
ax1.imshow(img)
ax1.set_title('BGR Colormap')
ax2.imshow(img[:,:,::-1])
ax2.set_title('Reversed BGR Colormap(RGB)')
plt.show()
分割和合并顏色通道
import cv2 as cv
import matplotlib.pyplot as plt
img = cv.imread(cv.samples.findFile("starry_night.jpg"),cv.IMREAD_COLOR)
b,g,r = cv.split(img)
fig,ax = plt.subplots(2,2)
ax[0,0].imshow(r,cmap='gray')
ax[0,0].set_title("Red Channel");
ax[0,1].imshow(g,cmap='gray')
ax[0,1].set_title("Green Channel");
ax[1,0].imshow(b,cmap='gray')
ax[1,0].set_title("Blue Channel");
# Merge the individual channels into a BGR image
imgMerged = cv.merge((b,g,r))
# Show the merged output
ax[1,1].imshow(imgMerged[:,:,::-1])
ax[1,1].set_title("Merged Output");
plt.show()
cv2.split
:將一個(gè)多通道數(shù)組分割成幾個(gè)單通道數(shù)組。cv2.merge
:將幾個(gè)數(shù)組合并成一個(gè)多通道數(shù)組。所有的輸入矩陣必須具有相同的大小。
注意: 白色較多的圖像具有較高的顏色密度。相反,黑色較多的圖像,其顏色密度較低。在上面的例子中,紅色的密度是最低的。
轉(zhuǎn)換到不同的色彩空間
cv2.cvtColor
函數(shù)將一個(gè)輸入圖像從一個(gè)顏色空間轉(zhuǎn)換到另一個(gè)顏色空間。在 RGB 和 BGR 色彩空間之間轉(zhuǎn)換時(shí),應(yīng)明確指定通道的順序(RGB2BGR
或 BGR2RGB
)。注意,OpenCV 中的默認(rèn)顏色格式通常被稱為 RGB,但它實(shí)際上是 BGR(字節(jié)是相反的)。 因此,標(biāo)準(zhǔn)(24 位)彩色圖像的第一個(gè)字節(jié)將是一個(gè) 8 位藍(lán)色分量,第二個(gè)字節(jié)是綠色,第三個(gè)字節(jié)是紅色。然后第四、第五和第六個(gè)字節(jié)將是第二個(gè)像素(藍(lán)色、然后是綠色,然后是紅色),以此類推。
import cv2 as cv
import matplotlib.pyplot as plt
img = cv.imread(cv.samples.findFile("starry_night.jpg"),cv.IMREAD_COLOR)
img_rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)
plt.imshow(img_rgb)
plt.show()
更多信息
關(guān)于 OpenCV 的更多細(xì)節(jié)可以在在線文檔中找到。
感謝閱讀。