欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python圖像處理之圖像與視頻處理基礎(chǔ)教程

 更新時間:2023年04月11日 10:22:26   作者:AI technophile  
這篇文章主要介紹了Python圖像處理之圖像與視頻處理基礎(chǔ)教程,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

圖像與視頻處理基礎(chǔ)

0. 前言

圖像處理是指在計算機上使用算法和代碼對圖像進行自動處理、操作和分析,而視頻處理是圖像處理的一種特殊情況(視頻文件或視頻流有連續(xù)的圖像序列構(gòu)成)。圖像和視頻處理在許多領(lǐng)域都有應(yīng)用廣泛的應(yīng)用,如電視、攝影、機器人、遙感、醫(yī)學(xué)診斷和工業(yè)檢查等。
在本節(jié)中,我們將聚焦一些簡單的圖像和視頻處理問題,用于幫助我們理解圖像和視頻的基本概念。在我們開始分析圖像/視頻之前,我們需要使用合適的數(shù)據(jù)結(jié)構(gòu)將圖像加載到內(nèi)存中,并且能夠?qū)⑻幚砗蟮膱D像/視頻保存到文件中;能夠在計算機屏幕上實時可視化(繪制)圖像能夠幫助我們立即觀察到圖像處理算法對圖像的處理結(jié)果。

1. 在 3D 空間中顯示 RGB 圖像顏色通道

1.1 圖像表示

圖像可以抽象為一個函數(shù),并將其可視化,以進行進一步的分析/處理?;叶葓D像可以認(rèn)為是像素位置的二元函數(shù) f ( x , y ) f(x, y) f(x,y), f ( x , y ) f(x, y) f(x,y) 將每個像素映射到其相應(yīng)灰度強度級別( [0, 255] 中的整數(shù)或 [0, 1] 中的浮點數(shù)),即:

對于 RGB 圖像,有三個這樣的函數(shù),可以表示為:

其分別對應(yīng)于每個通道及其色值,我們可以使用 matplotlib 庫的三維繪圖函數(shù)繪制以上函數(shù),使用 Python 代碼在 3D 空間中單獨繪制每個 RGB 通道。

1.2 在 3D 空間中繪制顏色通道

(1) 首先,導(dǎo)入所有必需的包。為了讀取圖像,我們需要 scikit-image 庫的 io 模塊中的 imread() 函數(shù);由于我們將圖像加載為 array 類型,因此需要 Numpy 操作數(shù)據(jù)類型 array;為了顯示圖像,我們將使用 matplotlib.pyplot 函數(shù);對于 3D 圖像的顯示,我們需要使用 mpl_toolkit 庫的 mplt3d 模塊以及 matplotlib 庫中的其他模塊:

from skimage.io import imread
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter

(2) 使用 plot_surface() 函數(shù)繪制通道的像素值,這是繪制 3D 圖像的關(guān)鍵函數(shù):

Axes3D.plot_surface(X, Y, Z, *args, **kwargs)

接下來,我們實現(xiàn) plot_3d() 的函數(shù),在以下代碼中,X 軸和 Y 軸分別用于顯示水平軸和垂直軸,Z 軸用于顯示圖像的深度。需要注意的是,xyz 的尺寸必須相同,cmap 用于顯示不同像素值的顏色映射:

def plot_3d(x, y, z, cmap='Reds', title=''):
    fig = plt.figure(figsize=(15,15))
    ax = fig.gca(projection='3d')
    # 曲面繪制
    surf = ax.plot_surface(x, y, z, cmap=cmap, linewidth=0, antialiased=False, rstride=2, cstride=2, alpha=0.5)
    ax.xaxis.set_major_locator(LinearLocator(10))
    ax.xaxis.set_major_formatter(FormatStrFormatter('%.02f'))
    ax.view_init(elev=10., azim=5)
    ax.set_title(title, size=20)
    plt.show()

(3) 從磁盤讀取 RGB 圖像,并使用 scikit-imageio 模塊的 imread() 函數(shù)將其加載到內(nèi)存中:

skimage.io.imread(fname, as_gray=False, plugin=None, flatten=None, **plugin_args)

使用 imread() 函數(shù)從文件加載圖像:

im = imread('1.jpg')

(4) 然后,使用 Numpy 庫的 arange()meshbrid() 函數(shù)創(chuàng)建像素坐標(biāo) ( x , y ) (x, y) (x,y) 的二維網(wǎng)格:

y = np.arange(im.shape[0])
x = np.arange(im.shape[1])
x, y = np.meshgrid(x, y)

(5) 最后,將圖像的紅色、綠色和藍色通道分別分配給相應(yīng)變量,這些通道使用 plot_3D() 函數(shù)以 3D 方式顯示:

z1 = im[...,0]
z2 = im[...,1]
z3 = im[...,2]

(6)3D 空間中可視化圖像,使用 plot_3d() 函數(shù)可視化 RGB 圖像的顏色通道。使用 Z 軸作為深度軸,并從圖像的高度中減去 y 軸值,以便將坐標(biāo)原點從左上角移動到左側(cè)中心點處。使用函數(shù) plot_3d() 可視化紅色通道:

plot_3d(z1, x, im.shape[1]-y, cmap='Reds', title='3D plot for the Red Channel')

紅色通道的 3D 繪圖結(jié)果如下所示:

從以上繪圖結(jié)果可以看出,每個通道中的顏色深度和 3D 繪圖結(jié)果在視覺上與原始 2D 圖像類似。

2. 使用 scikit-video 讀/寫視頻文件

2.1 scikit-video 庫

在本節(jié)中,我們將學(xué)習(xí)如何使用 scikit-video 庫函數(shù)從磁盤加載視頻,該庫使用 FFmpeg 軟件執(zhí)行視頻 I/O,因此首先需要安裝 FFmpeg 后再安裝 scikit-video 模塊:

pip3 install scikit-video

2.2 讀/寫視頻文件

首先導(dǎo)入所有必需的包:

import skvideo.io
import numpy as np
import matplotlib.pyplot as plt

接下來,使用 FFmpegReader() 函數(shù)從磁盤讀取視頻文件,并隨機顯示視頻中的一些圖像幀。函數(shù) FFmpegReader() 的用法如下:

skvideo.io.FFmpegReader(*args, **kwargs)

使用 FFmpeg 讀取視頻幀:

inputparameters = {}
outputparameters = {}
reader = skvideo.io.FFmpegReader('example.mp4',
                inputdict=inputparameters,
                outputdict=outputparameters)

2.3 提取視頻文件屬性

使用 getShape() 方法以及 FFmpegReader() 函數(shù)返回的對象獲取視頻的幀數(shù)、高度、寬度和通道數(shù)等屬性:

# 讀取視頻文件屬性
num_frames, height, width, num_channels = reader.getShape()
print(num_frames, height, width, num_channels)

2.4 讀取并保存視頻

使用 nextFrame() 方法從視頻中讀取幀。通過使用 NumPyrandom.choice() 函數(shù)隨機選擇四個幀,并顯示這些幀:

plt.figure(figsize=(20,10))

frame_list = np.random.choice(num_frames, 4)
i, j = 0, 1
for frame in reader.nextFrame():
    if i in frame_list:
        plt.subplot(2,2,j)
        plt.imshow(frame)
        plt.title("Frame {}".format(i), size=20)
        plt.axis('off')
        j += 1
    i += 1
plt.show()

二值圖像是只有兩個不同灰度值(黑色和白色)的圖像,二值圖像處理通常是圖像處理應(yīng)用程序的主要過程之一,例如,形態(tài)學(xué)圖像處理算法通常需要輸入二值圖像開始。要計算二值圖像,最簡單的方法是使用閾值算法,高于閾值的像素變?yōu)榘咨?,低于閾值的像素均變?yōu)楹谏?br />filters 模塊中的 threshold_otsu() 函數(shù)能夠?qū)σ曨l中的幀進行閾值處理,threshold_otsu() 函數(shù)能夠?qū)⒒叶葓D像轉(zhuǎn)換為二值圖像(在之后的學(xué)習(xí)中,我們會對其進行詳細(xì)介紹)。
對每個顏色通道應(yīng)用閾值以從圖像幀中獲得二值圖像幀。使用 FFmpegWriter() 函數(shù)保存二值化視頻,方法是按讀取視頻幀順序依次疊加二值圖像幀:

from skimage.color import rgb2gray
from skimage.filters import threshold_otsu

writer = skvideo.io.FFmpegWriter("r2_binary.mp4", outputdict={})
for frame in skvideo.io.vreader("r3.mp4"):
    frame = rgb2gray(frame)
    thresh = threshold_otsu(frame)
    binary = np.zeros((frame.shape[0], frame.shape[1], 3), dtype=np.uint8)
    binary[...,0] = binary[...,1] = binary[...,2] = 255*(frame > thresh).astype(np.uint8)
    writer.writeFrame(binary)
writer.close()

最后,讀取剛剛保存的二進制視頻,然后顯示一些隨機幀:

plt.figure(figsize=(20,10))

reader = skvideo.io.FFmpegReader("example_binary.mp4")
num_frames, height, width, num_channels = reader.getShape()
frame_list = np.random.choice(num_frames, 4)
i, j = 0, 1
for frame in reader.nextFrame():
    if i in frame_list:
        plt.subplot(2,2,j)
        plt.imshow(frame)
        plt.title("Frame {}".format(i), size=20)
        plt.axis('off')
        j += 1
    i += 1
plt.show()

3. 使用 OpenCV 從相機捕獲實時視頻

在本節(jié)中,我們將學(xué)習(xí)如何使用 OpenCV 庫捕獲視頻并提取圖像幀,同時我們將捕獲攝像機(例如,筆記本電腦的內(nèi)置網(wǎng)絡(luò)攝像頭或 USB 攝像頭)錄制的實時視頻流。

(1) 首先導(dǎo)入所需的庫:

import cv2
import matplotlib.pyplot as plt

(2) 要使用 OpenCV 捕獲視頻,我們需要創(chuàng)建一個 VideoCapture 對象,它的參數(shù)可以是設(shè)備索引(實時視頻)或視頻文件的名稱(本地文件):

vc = cv2.VideoCapture(0)
plt.ion()
if vc.isOpened(): # 讀取第一幀
    is_capturing, frame = vc.read()    
    webcam_preview = plt.imshow(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))    
else:
    is_capturing = False

設(shè)備索引是指定攝像機的整數(shù)數(shù)字,通常,如果只有一臺相機連接到計算機,只需傳遞 0 作為參數(shù)即可,如果有兩臺相機,則可以通過傳遞 1 來選擇第二臺相機,依次類推。
我們可以使用 isOpened() 方法檢查 VideoCapture 對象是否正確初始化,如果正確初始化則返回 true。如果返回 true,那么我們可以使用函數(shù) read() 讀取第一幀以及所有后續(xù)幀。
read() 函數(shù)是從設(shè)備捕獲數(shù)據(jù)的最方便的方法,它返回捕獲的視頻幀。如果沒有捕獲到任何幀(攝像機已斷開連接,或者視頻文件中沒有更多幀),則該方法返回 false;使用布爾變量 is_capturing 確定是否可以捕獲幀。

(3) 一旦第一幀被正確讀取,我們就可以在 while 循環(huán)中逐幀捕獲,直到視頻的最后一幀。最后,一定要調(diào)用 VideoCapture 對象上的 release() 函數(shù)來釋放設(shè)備。以下代碼演示了如何捕獲實時視頻流的前十幀。需要注意的是,OpenCV 使用 BGR 顏色格式,要顯示具有真實 RGB 顏色的視頻幀,必須使用轉(zhuǎn)換函數(shù) cv2.cvtColor(frame, cv2.color_BGR2RGB)

frame_index = 1
while is_capturing:
    if frame_index > 10: break

    is_capturing, frame = vc.read()
    image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    webcam_preview.set_data(image)
    plt.title('Frame {0:d} '.format(frame_index))
    plt.draw()
    frame_index += 1
    try:    # 避免由 plt.pause 引起的 NotImplementedError
        plt.pause(2)
    except Exception:
        Pass
vc.release()

如果連接到計算機的相機設(shè)備可以正常工作,那么運行以上代碼時,就可以看到相機捕獲到的實時圖像。此外, cv2.VideoCapture() 函數(shù)也可用于從磁盤讀取視頻文件,相對應(yīng)的,可以使用 cv2.VideoWriter() 函數(shù)可將視頻文件保存到本地磁盤文件中。

4. 實現(xiàn) Gotham 圖像濾鏡

4.1 Gotham 圖像濾鏡

在本節(jié)中,我們將學(xué)習(xí)如何實現(xiàn) Gotham 圖像濾鏡用于增強圖像效果,用于加強理解如何操作圖像像素并執(zhí)行插值操作。下圖顯示了我們將用于實現(xiàn)圖像濾鏡的輸入圖像:

首先,導(dǎo)入所需的庫。在本節(jié)中,我們將使用 PIL 庫實現(xiàn)圖像處理函數(shù):

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

im = Image.open('images/Img_01_03.jpg')
print(np.max(im))

創(chuàng)建 Gotham 濾波器需要在輸入圖像上應(yīng)用中間色調(diào)(紅色)對比度增強,這需要通過使用 Numpy 庫的 interp() 函數(shù)完成的,利用 該函數(shù)實現(xiàn)通道插值。接下來,我們首先了解 NumPy 插值在一維情況空間中的工作原理。

4.2 一維線性插值

當(dāng)圖像按縮放因子調(diào)整大小時,需要執(zhí)行一些像素插值,以便在現(xiàn)有像素之間填充新像素值,我們可以使用 NumPy interp() 函數(shù)執(zhí)行插值操作。從 NumPy 文檔中可以看到,interp() 函數(shù)的一維線性插值基本用法如下:

numpy.interp(x, left=None, right=None, period=None)

interp() 會返回具有給定離散數(shù)據(jù)點的函數(shù)的一維分段線性插值:

x_p = np.linspace(0, 2*np.pi, 10) # 在間隔[0,2π]中生成10個均勻間隔的數(shù)字序列
y_p = np.cos(x_p)
x = np.linspace(0, 2*np.pi, 50) # 在間隔[0,2π]中生成50個均勻間隔的數(shù)字序列
y = np.cos(x)
y_interp = np.interp(x, x_p, y_p)

plt.figure(figsize=(20,10))
plt.plot(x_p, y_p, 'o', label='reference points')
plt.plot(x, y_interp, '-x', label='interpolated')
plt.plot(x, y, '--', label='true')
plt.legend(prop={'size': 16})
plt.show()

假設(shè)我們希望(線性)插值區(qū)間 [ 0 , 2 π ] [0, 2π] [0,2π] 中余弦函數(shù)的值,最初區(qū)間中僅包含十個參考點。我們可以使用 interp() 函數(shù)計算剩余點處函數(shù)的值,從給定點處函數(shù)值開始,然后應(yīng)用線性插值。橙色曲線表示由 interp() 函數(shù)估計的曲線,綠色曲線顯示真實的余弦曲線:

4.3 圖像插值

可以以類似的方式擴展以上代碼,使用 interp() 函數(shù)計算 R (紅色)通道的通道內(nèi)插值結(jié)果,由于圖像的紅色通道值本質(zhì)上是一個 2D 陣列(矩陣),因此在將該函數(shù)應(yīng)用于通道之前,需要執(zhí)行以下操作:

  • 2D 陣列展平為 1D 陣列(使用 NumPyravel() 函數(shù))
  • 使用 interp() 函數(shù)應(yīng)用通道插值
  • 1D 陣列重新整形為圖像矩陣(使用 NumPy 的整形函數(shù))

(1) 使用 np.interp() 函數(shù),用 11 個參考點拉伸紅色通道直方圖:

r, g, b = im.split() # 分割圖像通道為R、G和B
r_old = np.linspace(0,255,11)   # 參考點
r_new = [0., 12.75, 25.5, 51., 76.5, 127.5, 178.5, 204., 229.5, 242.25, 255.] # 參考點的新值

r1 = Image.fromarray((np.reshape(np.interp(np.array(r).ravel(), r_old, r_new),
                                 (im.height, im.width))).astype(np.uint8), mode='L')

(2) 然后,繪制圖像和紅色通道直方圖:

plt.figure(figsize=(20,15))
plt.subplot(221)
plt.imshow(im)
plt.title('original', size=20)
plt.axis('off')
plt.subplot(222)
im1 = Image.merge('RGB', (r1, g, b))
plt.imshow(im1)
plt.axis('off')
plt.title('with red channel interpolation', size=20)
plt.subplot(223)
plt.hist(np.array(r).ravel())
plt.subplot(224)
plt.hist(np.array(r1).ravel())
plt.show()

下圖顯示了插值變換前后的圖像:

(3) 通過使用以下代碼,令黑色更接近藍色值,我們將藍色值增加了 7.65,并且使用函數(shù) np.clip() 來確保新值保持在 0255 區(qū)間內(nèi):

plt.figure(figsize=(20,10))
plt.subplot(121)
plt.imshow(im1)
plt.title('last image', size=20)
plt.axis('off')
b1 = Image.fromarray(np.clip(np.array(b) + 7.65, 0, 255).astype(np.uint8))
im1 = Image.merge('RGB', (r1, g, b1))
plt.subplot(122)
plt.imshow(im1)
plt.axis('off')
plt.title('with transformation', size=20)
plt.tight_layout()
plt.show()

其中,matplotlib 庫的 subplot 模塊用于顯示子圖,向當(dāng)前圖像中添加子圖:

subplot(nrows, ncols, index, **kwargs)

如上圖所示,使用 plt.subplot(121) 創(chuàng)建具有一行和兩列子圖的圖像,并使用索引參數(shù) index 指定繪圖位置。

(4) 通過使用 PIL 庫的 ImageEnhance 類中的 Enhance() 方法對圖像執(zhí)行較小的銳化:

class PIL.ImageEnhance.Sharpness(image)

ImageEnhance 類可用于調(diào)整圖像的清晰度,

from PIL.ImageEnhance import Sharpness

plt.figure(figsize=(20,10))
plt.subplot(121)
plt.imshow(im1)
plt.title('last image', size=20)
plt.axis('off')
im2 = Sharpness(im1).enhance(3.0)
plt.subplot(122)
plt.imshow(im2)
plt.axis('off')
plt.title('with transformation', size=20)
plt.tight_layout()
plt.show()

(5) 減少藍色通道的色調(diào)值,我們同樣使用通道插值完成,但這次需要在 RGB 圖像的藍色通道上進行:

blue_old = np.linspace(0,255,17) # 參考點的像素值
blue_new = [0., 11.985, 30.09, 64.005, 81.09, 99.96, 107.1, 111.945, 121.125, 143.055, 147.9, 159.885, 171.105,
               186.915, 215.985, 235.875, 255.] # 參考點的新像素值

b2 = Image.fromarray((np.reshape(np.interp(np.array(b1).ravel(), blue_old, blue_new),
                                 (im.height, im.width))).astype(np.uint8), mode='L')

繪制圖像以及藍色通道直方圖如下:

plt.figure(figsize=(20,15))
plt.subplot(221)
plt.imshow(im2)
plt.title('last image', size=20)
plt.axis('off')
plt.subplot(222)
im3 = Image.merge('RGB', (r1, g, b2))
plt.imshow(im3)
plt.axis('off')
plt.title('with blue channel interpolation', size=20)
plt.subplot(223)
plt.hist(np.array(b1).ravel(), normed=True)
plt.subplot(224)
plt.hist(np.array(b2).ravel(), normed=True)
plt.show()

(5) 最后,我們展示應(yīng)用 Gotham 濾鏡生成的最終輸出圖像:

plt.figure(figsize=(20,15))
plt.imshow(im3)
plt.axis('off')
plt.show()

小結(jié)

圖像和視頻是大數(shù)據(jù)時代重要的交流媒介,圖像和視頻處理是當(dāng)今人工智能技術(shù)重點的研究領(lǐng)域。在本節(jié)中,我們學(xué)習(xí)了如何使用 Python 執(zhí)行基本的圖像/視頻處理,我們首先學(xué)習(xí)在 3D 空間可視化 RGB 圖像的三個通道;然后,介紹了如何捕獲視頻并提取圖像幀;最后,我們展示了如何實現(xiàn)一種流形的圖像濾鏡 Gotham,用于理解如何操作圖像像素并執(zhí)行插值操作。

到此這篇關(guān)于Python圖像處理之圖像與視頻處理基礎(chǔ)教程的文章就介紹到這了,更多相關(guān)Python圖像處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python自動化測試工具Helium使用示例

    python自動化測試工具Helium使用示例

    大家好,本篇文章主要講的是python自動化測試工具Helium使用示例,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下哦
    2021-12-12
  • Python?json模塊常用方法小結(jié)

    Python?json模塊常用方法小結(jié)

    本文主要介紹了Python?json模塊常用方法小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Python中collections模塊的基本使用教程

    Python中collections模塊的基本使用教程

    collections是Python內(nèi)建的一個集合模塊,提供了許多有用的集合類。下面這篇文章主要給大家介紹了關(guān)于Python中collections模塊的基本使用,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-12-12
  • tensorflow pb to tflite 精度下降詳解

    tensorflow pb to tflite 精度下降詳解

    這篇文章主要介紹了tensorflow pb to tflite 精度下降詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • python3 深淺copy對比詳解

    python3 深淺copy對比詳解

    這篇文章主要介紹了python3 深淺copy對比詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • 深入了解Python的類與模塊化

    深入了解Python的類與模塊化

    這篇文章主要介紹了Python中的面向?qū)ο缶幊谭妒揭约澳K化思想,并給出相應(yīng)的實戰(zhàn)示例及解釋,對我們的學(xué)習(xí)和工作都有一定的價值,感興趣的小伙伴可以了解一下
    2021-12-12
  • python基于pdfminer庫提取pdf文字代碼實例

    python基于pdfminer庫提取pdf文字代碼實例

    這篇文章主要介紹了python 提取pdf文字代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • 淺析python 內(nèi)置字符串處理函數(shù)的使用方法

    淺析python 內(nèi)置字符串處理函數(shù)的使用方法

    這篇文章主要介紹了python 內(nèi)置字符串處理函數(shù)的使用方法,需要的朋友可以參考下
    2014-06-06
  • Python實現(xiàn)復(fù)雜對象轉(zhuǎn)JSON的方法示例

    Python實現(xiàn)復(fù)雜對象轉(zhuǎn)JSON的方法示例

    這篇文章主要介紹了Python實現(xiàn)復(fù)雜對象轉(zhuǎn)JSON的方法,結(jié)合具體實例形式分析了Python針對json轉(zhuǎn)換的相關(guān)操作技巧,需要的朋友可以參考下
    2017-06-06
  • pytorch 權(quán)重weight 與 梯度grad 可視化操作

    pytorch 權(quán)重weight 與 梯度grad 可視化操作

    這篇文章主要介紹了pytorch 權(quán)重weight 與 梯度grad 可視化操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06

最新評論