首頁 > 軟體

詳解Python+OpenCV進行基礎的影象操作

2022-02-15 19:01:01

介紹

眾所周知,OpenCV是一個用於計算機視覺和影象操作的免費開源庫。

OpenCV 是用 C++ 編寫的,並且有數千種優化的演演算法和函數用於各種影象操作。很多現實生活中的操作都可以使用 OpenCV 來解決。例如視訊和影象分析、實時計算機視覺、物件檢測、鏡頭分析等。

許多公司、研究人員和開發人員為 OpenCV 的建立做出了貢獻。使用OpenCV 很簡單,而且 OpenCV 配備了許多工具和功能。讓我們使用 OpenCV 來執行有趣的影象操作並檢視結果。

形態變換

形態變換是基於形狀變換影象的影象處理方法。這個過程有助於區域形狀的表現和刻畫。這些轉換使用應用於輸入影象的結構元素,並生成輸出影象。

形態學操作有多種用途,包括從影象中去除噪聲、定點陣影象中的強度凹凸和孔洞,以及連線影象中的不同元素。

有兩種主要的形態學變換型別:腐蝕和膨脹。

腐蝕

腐蝕是為了減小前景物件的大小而執行的形態學操作。異物的邊界被慢慢腐蝕。腐蝕在影象編輯和轉換中有許多應用,腐蝕會縮小影象畫素。物件邊界上的畫素也被刪除。

腐蝕的實現在 Python 中很簡單,可以在核心的幫助下實現。

讓我們開始使用 Python 中的程式碼來實現腐蝕。

首先,我們匯入 Open CV 和 Numpy。

import cv2
import numpy as np

現在我們讀取影象。

image = cv2.imread("image1.jpg")

圖片:

我們建立了一個執行腐蝕操作所需的核心,並使用內建的 OpenCV 函數實現它。

# Creating kernel
kernel = np.ones((5, 5), np.uint8)
# Using cv2.erode() method 
image_erode = cv2.erode(image, kernel)

現在,我們儲存檔案並檢視。

filename = 'image_erode1.jpg'
# Using cv2.imwrite() method
# Saving the image
cv2.imwrite(filename, image_erode)

圖片:

正如我們所看到的,影象現在被腐蝕了,銳度和邊緣都減少了,影象變得模糊了。腐蝕可用於隱藏或刪除影象的某些部分或隱藏影象中的資訊。

讓我們嘗試不同型別的腐蝕。

kernel2 = np.ones((3, 3), np.uint8)
image_erode2 = cv2.erode(image, kernel2, cv2.BORDER_REFLECT)

現在,我們儲存影象檔案。

filename = 'image_erode2.jpg'
# Using cv2.imwrite() method
# Saving the image
cv2.imwrite(filename, image_erode2)

圖片:

現在,讓我們看看什麼是膨脹。

膨脹

膨脹過程與腐蝕相反。影象膨脹時,前景物件不是縮小,而是擴大。影象裡的東西在邊界附近擴張,並形成一個膨脹的物體。

影象中的明亮區域在膨脹後往往會“發光”,這通常會導致影象增強。因此,膨脹用於影象校正和增強。

讓我們使用 Python 程式碼實現 Dilation。

kernel3 = np.ones((5,5), np.uint8)
image_dilation = cv2.dilate(image, kernel, iterations=1)

現在,我們儲存影象。

filename = 'image_dilation.jpg'
# Using cv2.imwrite() method
# Saving the image
cv2.imwrite(filename, image_dilation)

圖片:

正如我們所見,影象現在更亮,強度更高。

建立邊框

為影象新增邊框非常簡單,我們的手機相簿應用程式或編輯應用程式可以非常快速地完成。但是,現在讓我們使用 Python 為影象建立邊框。

## Using cv2.copyMakeBorder() method
image_border1 = cv2.copyMakeBorder(image, 25, 25, 10, 10, cv2.BORDER_CONSTANT, None, value = 0)

現在,讓我們儲存影象。

filename = 'image_border1.jpg'
# Using cv2.imwrite() method
# Saving the image
cv2.imwrite(filename, image_border1)

圖片:

在這裡,我們為影象新增了一個簡單的黑色邊框。現在,讓我們嘗試一些映象邊框。

#making a mirrored border
image_border2 = cv2.copyMakeBorder(image, 250, 250, 250, 250, cv2.BORDER_REFLECT)

現在,我們儲存影象。

filename = 'image_border2.jpg'
# Using cv2.imwrite() method
# Saving the image
cv2.imwrite(filename, image_border2)

圖片:

這很有趣,它看起來像是奇異博士的鏡子維度中的東西。

讓我們試試別的。

#making a mirrored border
image_border3 = cv2.copyMakeBorder(image, 300, 250, 100, 50, cv2.BORDER_REFLECT)

現在,我們儲存影象。

filename = 'image_border3.jpg'
# Using cv2.imwrite() method
# Saving the image
cv2.imwrite(filename, image_border3)

圖片:

強度變換

通常,由於各種原因,影象會發生強度變換。這些是在空間域中直接在影象畫素上完成的。影象閾值處理和對比度處理等操作是使用強度轉換完成的。

對數變換

對數變換是一種強度變換操作,其中影象中的畫素值被替換為它們的對數值。

對數變換用於使影象變亮或增強影象,因為它將影象中較暗的畫素擴大到較高的畫素值。

讓我們實現對數變換。

# Apply log transform.
c = 255/(np.log(1 + np.max(image)))
log_transformed = c * np.log(1 + image)
# Specify the data type.
log_transformed = np.array(log_transformed, dtype = np.uint8)

現在,我們儲存影象。

cv2.imwrite('log_transformed.jpg', log_transformed)

圖片:

影象變得非常明亮。

線性變換

我們將對影象應用分段線性變換。這種變換也是在空間域上完成的。此方法用於為特定目的修改影象。它被稱為分段線性變換,因為它只有一部分是線性的。最常用的分段線性變換是對比拉伸。

通常,如果在低光照條件下單擊影象並且周圍照明不佳,則生成的影象對比度較低。對比度拉伸會增加影象中強度級別的範圍,並且對比度拉伸函數會單調增加,從而保持畫素強度的順序。

現在,讓我們實現對比度拉伸。

def pixelVal(pix, r1, s1, r2, s2):
    if (0 <= pix and pix <= r1):
        return (s1 / r1)*pix
    elif (r1 < pix and pix <= r2):
        return ((s2 - s1)/(r2 - r1)) * (pix - r1) + s1
    else:
        return ((255 - s2)/(255 - r2)) * (pix - r2) + s2
# Define parameters.
r1 = 70
s1 = 0
r2 = 140
s2 = 255
# Vectorize the function to apply it to each value in the Numpy array.
pixelVal_vec = np.vectorize(pixelVal)
# Apply contrast stretching.
contrast_stretch = pixelVal_vec(image, r1, s1, r2, s2)
# Save edited image.
cv2.imwrite('contrast_stretch.jpg', contrast_stretch)

圖片:

在這裡,影象得到了改善,並且可以觀察到更高的對比度。

去噪彩色影象

去噪訊號或影象意味著去除不必要的訊號和資訊以獲得有用的訊號和資訊。去噪以去除不需要的噪聲,並更好地分析和處理影象。

讓我們用 Python 對彩色影象進行去噪。

denoised_image = cv2.fastNlMeansDenoisingColored(image, None, 15, 8, 8, 15)

現在,我們儲存影象。

# Save edited image.
cv2.imwrite('denoised_image.jpg', denoised_image)

圖片:

我們可以看到很多想要的東西,比如背景和天空已經被刪除了。

使用直方圖分析影象

在任何形式的分析中,直方圖都是必不可少的視覺效果。影象的直方圖是理解全域性描述的一種令人興奮的方式,直方圖可用於對影象進行定量分析。影象直方圖表示影象中灰度級的出現。

我們可以使用直方圖來了解數位影像的畫素強度分佈,也可以使用直方圖來了解主色。

讓我們繪製一個直方圖。

from matplotlib import pyplot as plt
histr = cv2.calcHist([image],[0],None,[256],[0,256])
plt.plot(histr)

輸出:

# alternative way to find histogram of an image
plt.hist(image.ravel(),256,[0,256])
plt.show()

輸出:

該圖顯示了影象上 0 到 255 顏色範圍內的畫素數。我們可以看到,所有型別的顏色都有良好的分佈。

現在,讓我們將影象轉換為黑白並生成直方圖。

grey_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
histogram = cv2.calcHist([grey_image], [0], None, [256], [0, 256])
plt.plot(histogram, color='k')

輸出:

這個分佈和之前的分佈有很大的不同。這主要是因為影象被轉換為灰度,然後進行分析。

現在,我們執行顏色直方圖。

for i, col in enumerate(['b', 'g', 'r']):
    hist = cv2.calcHist([image], [i], None, [256], [0, 256])
    plt.plot(hist, color = col)
    plt.xlim([0, 256])
plt.show()

輸出:

我們可以看到藍色和綠色的畫素數量遠高於紅色。這很明顯,因為影象中有很多藍色和綠色區域。

所以我們可以看到,繪製影象直方圖是理解影象強度分佈的好方法。

到此這篇關於詳解Python+OpenCV進行基礎的影象操作的文章就介紹到這了,更多相關Python OpenCV影象操作內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com