主頁 >  其他 > Python 大白從零開始 OpenCV 學習課-7. 空間域影像濾波

Python 大白從零開始 OpenCV 學習課-7. 空間域影像濾波

2021-12-07 10:39:50 其他

Python 大白從零開始 OpenCV 學習課-7. 空間域影像濾波

本系列面向小白,從零開始實戰解說 OpenCV 專案實戰,
影像濾波是在盡可能保留影像細節特征的條件下對目標影像的噪聲進行抑制,是常用的影像預處理操作,
空間域影像增強的方法很多,各有不同的特點和作用,本節介紹空間域濾波的平滑(低通濾波)和銳化(高通濾波)方法,常用的平滑演算法有高斯平滑、均值平滑、中值平滑、雙邊濾波、導向濾波等;常用的銳化演算法有鈍化掩蔽、拉普拉斯算子、Sobel梯度算子和 Scharr 梯度算子,
本文提供上述各種演算法的完整例程和運行結果,并通過一個應用案例示范綜合使用多種影像增強方法,


文章目錄

  • Python 大白從零開始 OpenCV 學習課-7. 空間域影像濾波
    • 1. 影像的相關與卷積運算
      • 1.1 相關與卷積運算
      • 1.2 影像的邊界擴充
      • 例程 1.65:影像的邊界擴充
      • 1.3 Scipy 實作二維離散卷積(sp.convolve2d)
      • 例程 1.66:scipy.signal 實作影像的二維卷積
      • 1.4 cv2 實作二維離散卷積(flip 和 filter2D)
      • 例程 1.67:cv2 實作影像的二維卷積
      • 1.5 可分離卷積核
      • 例程 1.68:可分離核的卷積操作
      • 例程 1.69:可分離核的影像卷積
    • 2. 空間域平滑濾波(低通濾波)
      • 2.1 低通盒式濾波器
      • 例程 1.70:影像的低通濾波—盒式濾波器
      • 2.2 低通高斯濾波器
      • 例程 1.71:影像的低通濾波—高斯濾波器
      • 2.3 非線性濾波—中值濾波(Median filter)
      • 例程 1.73:影像的非線性濾波—中值濾波器
      • 2.4 非線性濾波—雙邊濾波(Bilateral filter)
      • 例程 1.74:影像的非線性濾波—雙邊濾波器
      • 2.5 非線性濾波—聯合雙邊濾波(Joint bilateral filter)
      • 2.6 非線性濾波—導向濾波(Guided filter)
    • 3. 空間域銳化濾波(高通濾波)
      • 3.1 影像的梯度算子
      • 3.2 鈍化掩蔽
      • 例程 1.77:影像銳化: 鈍化掩蔽
      • 3.3 拉普拉斯卷積核(Laplacian)
      • 例程 1.78:影像銳化:Laplacian 算子
      • 3.4 Sobel 梯度算子
      • 例程 1.79:影像銳化:Sobel 算子
      • 3.5 Scharr 算子
      • 例程 1.80:影像銳化:Scharr 算子
    • 4. 低通、高通、帶阻、帶通
    • 5. 空間域影像增強技術的綜合應用


1. 影像的相關與卷積運算

濾波通常是指對影像中特定頻率的分量進行過濾或抑制,影像濾波是在盡可能保留影像細節特征的條件下對目標影像的噪聲進行抑制,是常用的影像預處理操作,

資料采集都會帶有一定的噪聲,影像的噪聲可以理解為灰度值的隨機變化,對影像在空間域存在的隨機噪聲,可以通過平滑技術進行抑制或去除,稱為空間域影像濾波,

頻率域濾波是通過傅里葉變換方法實作的,而空間域濾波則是通過相關與卷積運算實作,常用的平滑處理演算法有基于二維離散卷積的高斯平滑、均值平滑,基于統計方法的中值平滑,保留邊緣資訊的雙邊濾波、導向濾波等,

空間濾波器是由鄰域和定義的操作構成的,濾波器規定了濾波時采用的鄰域形狀及該區域內像素值的處理方法,濾波器也被稱為 “核”、“模板”、“視窗”、“掩模”、“算子”,一般在信號處理中稱為 “濾波器”,在數學領域稱為 “核”,線性濾波器就是指基于線性核的濾波,也就是卷積運算,


1.1 相關與卷積運算

濾波器核是指像素周圍某一大小的矩形鄰域,也稱為模板、滑動視窗,

**相關運算(Correlation operation)**是利用模板對影像進行鄰域操作:將濾波器模板的中心移動到待處理的像素點,對模板區域的各點加權相乘后求和,

大小為 m*n 的核(模板) w 與影像 f(x,y) 的相關運算 ( w ? f ) ( x , y ) (w \diamond f)(x,y) (w?f)(x,y) 的數學描述為:

( w ? f ) ( x , y ) = ∑ s = ? a a ∑ t = ? b b w ( s , t ) ? f ( x + s , y + t ) (w \diamond f)(x,y) = \sum_{s=-a}^a \sum_{t=-b}^b w(s,t) * f(x+s,y+t) (w?f)(x,y)=s=?aa?t=?bb?w(s,t)?f(x+s,y+t)
相關運算的計算步驟如下:

(1)將模板在影像中逐點移動,模板中心移動到被處理的像素點上;
(2)將模板區域中的各點的系數(權值)與影像的像素值相乘,對乘積求和,即加權求和;
(3)將加權求和結果賦值給模板中心的像素,

注意, “相關運算” 中的 “相關” 不是 “有關的”,而是一種特定的數學運算方式,

**卷積運算(Convolution operation)**也是利用模板對影像進行鄰域操作,只是把相關運算的模板旋轉了 180度,

大小為 m*n 的核(模板) w 與影像 f(x,y) 的卷積運算 ( w ★ f ) ( x , y ) (w \bigstar f)(x,y) (wf)(x,y) 的數學描述為:
( w ★ f ) ( x , y ) = ∑ s = ? a a ∑ t = ? b b w ( s , t ) ? f ( x ? s , y ? t ) (w \bigstar f)(x,y) = \sum_{s=-a}^a \sum_{t=-b}^b w(s,t) * f(x-s,y-t) (wf)(x,y)=s=?aa?t=?bb?w(s,t)?f(x?s,y?t)

卷積運算子合交換律、結合律和分配律,即:
f ★ g = g ★ f f ★ ( g ★ h ) = ( f ★ g ) ★ h f ★ ( g + h ) = ( f ★ g ) + ( f ★ h ) f \bigstar g = g \bigstar f \\ f \bigstar (g \bigstar h) = (f \bigstar g) \bigstar h \\ f \bigstar (g + h) = (f \bigstar g) + (f \bigstar h) fg=gff(gh)=(fg)hf(g+h)=(fg)+(fh)

在這里插入圖片描述
(本圖片來自 “小黑鴨” 《OpenCV學習+常用函式記錄②:影像卷積與濾波》,特此致謝,)


1.2 影像的邊界擴充

相關和卷積運算都要對影像的邊界點要進行特殊處理,就需要將邊界進行適當擴充,

函式說明:

OpenCV 中提供了函式 cv.copyMakeBorder 進行邊界擴充方式,也可以為影像設定邊框,

cv.copyMakeBorder(src, top, bottom, left, right, borderType[, dst[, value]]) → dst

引數說明:

  • src:進行邊界擴充的影像
  • top, bottom, left, right:上側、下側、左側、右側邊界擴充的的寬度(像素數)
  • value:當 borderType 為 BORDER_CONSTANT 時,以常量(value)填充擴充的邊界,默認值為 (0,0,0)
  • borderType 邊界擴充的型別
    • cv2.BORDER_REPLICATE:復制,復制最邊緣像素進行填充(aa | abcdefg | gg),中值濾波采用復制法
    • cv2.BORDER_REFLECT:對稱法,以影像邊緣為軸進行對稱填充(cba| abcdefg | gfe)
    • cv2.BORDER_REFLECTT_101:倒映法,以影像最邊緣像素為軸進行對稱填充(dcb| abcdefg | fed),函式 filter2D, blur, GaussianBlur, bilateralFilter 中默認的邊界處理方法
    • cv2.BORDER_WRAP:用另一側元素來填充這一側的擴充邊界(efg| abcdefg | ab)
    • cv2.BORDER_CONSTANT:以常數(value)作為像素值進行擴充(vv | abcdefg | vv)

例程 1.65:影像的邊界擴充

    # 1.65 影像的邊界擴充
    img = cv2.imread("../images/imgRose1.jpg")  # 讀取彩色影像(BGR)

    top = bottom = left = right = 50
    imgReplicate = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_REPLICATE)
    imgReflect = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_REFLECT)
    imgReflect101 = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_REFLECT_101)
    imgWrap = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_WRAP)
    imgConstant = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=(200,200,200))

    plt.figure(figsize=(9, 6))
    plt.subplot(231), plt.axis([-50,562,-50,562]), plt.title('ORIGINAL'), plt.axis('off')
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.subplot(232), plt.axis('off'), plt.title('REPLICATE')
    plt.imshow(cv2.cvtColor(imgReplicate, cv2.COLOR_BGR2RGB))
    plt.subplot(233), plt.axis('off'), plt.title('REFLECT')
    plt.imshow(cv2.cvtColor(imgReflect, cv2.COLOR_BGR2RGB))
    plt.subplot(234), plt.axis('off'), plt.title('REFLECT_101')
    plt.imshow(cv2.cvtColor(imgReflect101, cv2.COLOR_BGR2RGB))
    plt.subplot(235), plt.axis('off'), plt.title('WRAP')
    plt.imshow(cv2.cvtColor(imgWrap, cv2.COLOR_BGR2RGB))
    plt.subplot(236), plt.axis('off'), plt.title('CONSTANT')
    plt.imshow(cv2.cvtColor(imgConstant, cv2.COLOR_BGR2RGB))
    plt.show()

在這里插入圖片描述


1.3 Scipy 實作二維離散卷積(sp.convolve2d)

Scipy 中提供了函式 sp.convolve2d 實作二維離散卷積的計算,

對于二維離散卷積的運算,Python的科學計算包Scipy提供了函式實作該功能:

    convolve2d(in1, in2, mode="full", boundary="fill", fillvalue=0) → dst

引數說明:

  • in1:進行卷積運算的影像,二維陣列——只能處理單通道影像,如灰度影像
  • in2:卷積操作的模板(卷積核),二維陣列
  • mode:卷積型別,‘full’、‘valid’、‘same’,默認值為 ‘full’
  • boundary:邊界擴充方式,‘fill’、‘wrap’、‘symm’,默認值為 ‘fill’
    • ‘fill’:以常數(fillvalue)作為像素值進行擴充(vv | abcdefg | vv)
    • ‘symm’:對稱法,以影像邊緣為軸進行對稱填充(cba| abcdefg | gfe)
    • ‘wrap’:用另一側元素來填充這一側的擴充邊界(efg| abcdefg | ab)
  • fillvalue:當 boundary=‘fill’ 時,以以常數(fillvalue)作為像素值進行擴充

例程 1.66:scipy.signal 實作影像的二維卷積

    # 1.66 scipy.signal 實作影像的二維卷積
    img = cv2.imread("../images/imgLena.tif", flags=0)  # # flags=0 讀取為灰度影像
    kernel = np.array([[-3-3j,0-10j,+3-3j], [-10+0j,0+0j,+10+0j], [-3+3j,0+10j,+3+3j]])  # Gx + j*Gy

    # scipy.signal 實作卷積運算
    from scipy import signal
    convFull = signal.convolve2d(img, kernel, boundary='symm', mode='full')  # full 卷積
    convValid = signal.convolve2d(img, kernel, boundary='symm', mode='valid')  # valid 卷積
    convSame = signal.convolve2d(img, kernel, boundary='symm', mode='same')  # same 卷積
    print(img.shape, convFull.shape, convValid.shape, convSame.shape)  # 輸出影像大小有區別

    plt.figure(figsize=(9, 6))
    plt.subplot(131), plt.axis('off'), plt.title('Original'), plt.axis('off')
    plt.imshow(img, cmap='gray', vmin=0, vmax=255)
    plt.subplot(132), plt.axis('off'), plt.title('Convolve (full)')
    plt.imshow(np.absolute(convFull), cmap='gray', vmin=0, vmax=255)
    plt.subplot(133), plt.axis('off'), plt.title('Convolve (same)')
    plt.imshow(np.absolute(convSame), cmap='gray', vmin=0, vmax=255)
    plt.tight_layout()
    plt.show()

注意事項:

  1. signal.convolve2d 只能對二維矩陣進行卷積操作,因此只能處理灰度影像,如果需要處理彩色影像,可以分別對每一通道進行卷積操作來實作,

  2. signal.convolve2d 選擇不同卷積型別 ‘full’、‘valid’、‘same’ 時,影像卷積效果的差別并不明顯,但影像尺寸大小有區別,這與不同型別時采用不同的邊界處理方式有關,

img.shape: (512, 512)
convFull.shape: (514, 514)
convValid.shape: (510, 510)
convSame.shape: (512, 512)

在這里插入圖片描述


1.4 cv2 實作二維離散卷積(flip 和 filter2D)

使用 OpenCV 中的 cv.flip 和 cv.filter2D 函式也可以實作影像的卷積運算,

函式 cv.flip 實作圍繞軸線翻轉二維陣列,將影像沿軸線進行軸對稱變換,可以將影像沿水平方向、垂直方向、或水平/垂直方向同時進行翻轉,例程 1.38 介紹了影像的翻轉(鏡像)的使用方法,

函式 cv.filter2D 對影像與核(模板)進行相關計算,與函式 cv.flip 共同實作卷積運算,

函式說明:

cv.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]]) → dst

引數說明:

  • src:卷積處理的輸入影像,可以是灰度影像,也可以是多通道的彩色影像
  • dst:卷積處理的輸出影像,大小和型別與 src 相同
  • ddepth:目標影像每個通道的深度(資料型別),ddepth=-1 表示與輸入影像的資料型別相同
  • kernel:卷積操作的模板(卷積核),二維實型陣列
  • anchor:卷積核的錨點位置,默認值 (-1, -1) 表示以卷積核的中心為錨點
  • delta:輸出影像的偏移量,可選項,默認值為 0
  • borderType:邊界擴充的型別

cv.filter2D 可以處理灰度影像,也可以直接處理彩色影像,不需要對每一色彩通道分別操作,


例程 1.67:cv2 實作影像的二維卷積

    # 1.67:cv2 實作影像的二維卷積
    img = cv2.imread("../images/imgGaia.tif", flags=0)  # # flags=0 讀取為灰度影像

    kernel = np.array([[-1, -1, -1], [-1, 9, -1], [-1, -1, -1]])  # Gx + j*Gy

    kFlip = cv2.flip(kernel, -1)  # 將卷積核旋轉180度
    # 使用函式filter2D算出same卷積
    imgConv1 = cv2.filter2D(img, -1, kFlip,
               anchor=(0,0), borderType=cv2.BORDER_CONSTANT)
    imgConv2 = cv2.filter2D(img, -1, kFlip,
               anchor=(0,0), borderType=cv2.BORDER_REFLECT)

    plt.figure(figsize=(9, 6))
    plt.subplot(131), plt.axis('off'), plt.title('Original'), plt.axis('off')
    plt.imshow(img, cmap='gray', vmin=0, vmax=255)
    plt.subplot(132), plt.axis('off'), plt.title('cv2.filter2D (BORDER_CONSTANT)')
    plt.imshow(np.absolute(imgConv1), cmap='gray', vmin=0, vmax=255)
    plt.subplot(133), plt.axis('off'), plt.title('cv2.filter2D (BORDER_REFLECT)')
    plt.imshow(np.absolute(imgConv2), cmap='gray', vmin=0, vmax=255)
    plt.tight_layout()
    plt.show()

在這里插入圖片描述



1.5 可分離卷積核

如果卷積核 w 可以被分解為兩個或多個較小尺寸卷積核 w1、w2…,即: w = w 1 ★ w 2 w = w1 \bigstar w2 w=w1w2,則成為可分離卷積核,

秩為 1 的矩陣可以分解為一個列向量與一個行向量的乘積,因此秩為 1 的卷積核是可分離卷積核,

可分離卷積核 w 與影像 f 的卷積(same 卷積),等于先用 f 與 w1 卷積,再用 w2 對結果進行卷積:
w ★ f = ( w 1 ★ w 2 ) ★ f = w 2 ★ ( w 1 ★ f ) = ( w 1 ★ f ) ★ w 2 w \bigstar f = (w_1 \bigstar w_2)\bigstar f = w_2 \bigstar (w_1 \bigstar f) = (w_1 \bigstar f)\bigstar w_2 wf=(w1?w2?)f=w2?(w1?f)=(w1?f)w2?
隨著影像尺寸與卷積核尺寸的增大,用分離的卷積核依次對影像進行卷積操作,可以有效地提高運算速度,因此,在二維影像處理中,經常將一個可分離卷積核分解為一維水平核 kernalX 和一維垂直核 kernalY 的乘積,

函式 sepFilter2D 實作可分離核(模板)對影像進行線性濾波,

函式說明:

cv.sepFilter2D(	src, ddepth, kernelX, kernelY[, dst[, anchor[, delta[, borderType]]]]) → dst  # OpenCV4

該函式先用一維水平核 kernalX 對影像的行進行濾波,再用一維垂直核 kernalY 對影像的列進行濾波,

引數說明:

  • src:卷積處理的輸入影像,可以是灰度影像,也可以是多通道的彩色影像
  • dst:卷積處理的輸出影像,大小和型別與 src 相同
  • ddepth:目標影像每個通道的深度(資料型別),ddepth=-1 表示與輸入影像的資料型別相同
  • kernelX:水平卷積核向量,一維實型陣列
  • kernelY:垂直卷積核向量,一維實型陣列
  • anchor:卷積核的錨點位置,默認值 (-1, -1) 表示以卷積核的中心為錨點
  • delta:輸出影像的偏移量,可選項,默認值為 0
  • borderType:邊界擴充的型別

例程 1.68:可分離核的卷積操作

    # 1.68:可分離核的卷積操作
    imgList = list(range(0, 36))
    imgTest = np.array(imgList).reshape(6, 6)

    # 可分離卷積核: kernXY = kernX * kernY
    kernX = np.array([[-1, 3, -1]], np.float32)  # (1,3)
    kernY = np.transpose(kernX)  # (3,1)
    kernXY = kernX * kernY
    print(kernX.shape, kernY.shape, kernXY.shape)

    from scipy import signal
    # 二維卷積核直接對影像進行卷積操作
    imgConv_XY = signal.convolve2d(imgTest, kernXY, mode='same', boundary='fill')
    # 可分離卷積核分解為一維水平核 kernalX 和一維垂直核 kernalY 分別進行卷積操作
    imgConv_X = signal.convolve2d(imgTest, kernX, mode='same', boundary='fill')
    imgConv_X_Y = signal.convolve2d(imgConv_X, kernY, mode='same', boundary='fill')

    print("\n比較 imgConv_XY 與 imgConv_X_Y 是否相等:\t", (imgConv_XY == imgConv_X_Y).all())
    print("\nimgConv_kernXY:\n", imgConv_XY)
    print("\nimgConv_kernX_kernY:\n", imgConv_X_Y)

運行結果如下:

(1, 3) (3, 1) (3, 3)

比較 imgConv_XY 與 imgConv_X_Y 是否相等:	 True

imgConv_kernXY:
 [[-14.  -4.  -2.   0.   2.  10.]
 [ 11.   7.   8.   9.  10.  23.]
 [ 23.  13.  14.  15.  16.  35.]
 [ 35.  19.  20.  21.  22.  47.]
 [ 47.  25.  26.  27.  28.  59.]
 [130.  68.  70.  72.  74. 154.]]

imgConv_kernX_kernY:
 [[-14.  -4.  -2.   0.   2.  10.]
 [ 11.   7.   8.   9.  10.  23.]
 [ 23.  13.  14.  15.  16.  35.]
 [ 35.  19.  20.  21.  22.  47.]
 [ 47.  25.  26.  27.  28.  59.]
 [130.  68.  70.  72.  74. 154.]]

例程 1.69:可分離核的影像卷積

    # 1.69:可分離核的影像卷積
    img = cv2.imread("../images/imgGaia.tif", flags=1) 
    
    # 可分離卷積核: kernXY = kernX * kernY
    kernX = np.array([[-1, 3, -1]], np.float32)  # (1,3)
    kernY = np.transpose(kernX)  # (3,1)
    kernXY = kernX * kernY

    # (1) 可分離卷積核分解為一維水平核 kernalX 和一維垂直核 kernalY 分步進行卷積操作
    imgConvY = cv2.filter2D(img, -1, kernY,
               anchor=(0,0), borderType=cv2.BORDER_CONSTANT)
    imgConv_X_Y = cv2.filter2D(imgConvY, -1, kernX,
               anchor=(0,0), borderType=cv2.BORDER_CONSTANT)
    # (2) 二維卷積核 kernXY 直接對影像進行卷積操作
    imgConv_XY = cv2.filter2D(img, -1, kernXY,
                    anchor=(0, 0), borderType=cv2.BORDER_CONSTANT)
    # (3) 一維水平核 kernalX 和一維垂直核 kernalY 進行可分離卷積核的卷積操作
    imgConvSep_XY = cv2.sepFilter2D(img, -1, kernX, kernY,
                    anchor=(0,0), borderType=cv2.BORDER_CONSTANT)

    print("\n比較 imgConv_XY 與 imgConv_X_Y 是否相等:\t", (imgConv_XY == imgConv_X_Y).all())
    print("\n比較 imgConvSep_XY 與 imgConv_XY 是否相等:\t", (imgConvSep_XY == imgConv_XY).all())

    plt.figure(figsize=(9, 6))
    plt.subplot(131), plt.axis('off'), plt.title('cv2.filter2D(kernXY)')
    plt.imshow(cv2.cvtColor(imgConv_XY, cv2.COLOR_BGR2RGB))
    plt.subplot(132), plt.axis('off'), plt.title('cv2.filter2D (kernX->kernY)')
    plt.imshow(cv2.cvtColor(imgConv_X_Y, cv2.COLOR_BGR2RGB))
    plt.subplot(133), plt.axis('off'), plt.title('cv2.sepFilter2D(kernX,kernY)')
    plt.imshow(cv2.cvtColor(imgConvSep_XY, cv2.COLOR_BGR2RGB))
    plt.tight_layout()
    plt.show()

運行結果如下:

比較 imgConv_XY 與 imgConv_X_Y 是否相等:	 False
比較 imgConvSep_XY 與 imgConv_XY 是否相等:	 True

在這里插入圖片描述



2. 空間域平滑濾波(低通濾波)

影像濾波是在盡可能保留影像細節特征的條件下對目標影像的噪聲進行抑制,是常用的影像預處理操作,

平滑濾波也稱為低通濾波,可以抑制影像中的灰度突變,使影像變得模糊,是低頻增強的空間域濾波技術,平滑濾波常用于:

  • 模糊影像和影像降噪,
  • 在影像重取樣前平滑影像以減少混淆
  • 減少影像中無關的細節
  • 平滑因灰度級不足所導致的影像的偽輪廓

線性空間濾波是指影像與濾波器核(卷積核)進行卷積計算,平滑卷積核與影像的卷積類似于積分運算,對影像的鄰域進行加權求和,可以實作空間域平滑濾波,


2.1 低通盒式濾波器

盒式核是最簡單的可分離低通濾波器核,盒式核的模板區域中各像素點的系數相同,因此也是可分離核,

盒式濾波器結構簡單,便于快速實作和實驗,但盒式濾波器對透鏡模糊特性的近似能力較差,而且往往會沿垂直方向模糊影像,

OpenCV 提供了 cv.blur 函式和 cv.boxFilter 函式實作盒式濾波器核低通濾波,

函式說明:

cv.blur(src, ksize[, dst[, anchor[, borderType]]]) → dst

函式 cv.blur 使用的濾波器核的運算式為:
K = 1 k s i z e . w i d t h ? k s i z e . h e i g h t [ 1 1 ? 1 1 1 ? 1 ? ? ? ? 1 1 ? 1 ] K= \frac{1}{ksize.width * ksize.height} \begin{bmatrix} 1 & 1 &\cdots &1\\ 1 & 1 &\cdots &1\\ \vdots &\vdots &\vdots &\vdots\\ 1 & 1 &\cdots &1 \end{bmatrix} K=ksize.width?ksize.height1???????11?1?11?1??????11?1???????

引數說明:

  • src:低通濾波輸入影像,可以是灰度影像,也可以是多通道的彩色影像
  • dst:低通濾波輸出影像,大小和型別與 src 相同
  • ksize:模糊核的大小,元組 (width, height),寬度、高度應設為正奇數
  • anchor:卷積核的錨點位置,默認值 (-1, -1),表示以卷積核的中心為錨點
  • borderType:邊界擴充的型別

函式說明:

cv.boxFilter(src, ddepth, ksize[, dst[, anchor[, normalize[, borderType]]]]) → dst

函式 cv.blur 使用的濾波器核的運算式為:
K = α [ 1 1 ? 1 1 1 ? 1 ? ? ? ? 1 1 ? 1 ] α = { 1 k s i z e . w i d t h ? k s i z e . h e i g h t , if normalize=True 1 , if normalize=False K= \alpha \begin{bmatrix} 1 & 1 &\cdots &1 \\1 & 1 &\cdots &1\\ \vdots &\vdots &\vdots &\vdots\\ 1 & 1 &\cdots &1 \end{bmatrix}\\ \alpha = \begin{cases} \frac{1}{ksize.width * ksize.height}&, \text{if normalize=True}\\ 1 &, \text{if normalize=False}\\ \end{cases} K=α??????11?1?11?1??????11?1???????α={ksize.width?ksize.height1?1?,if normalize=True,if normalize=False?

顯然,當 normalize=True 時,函式 cv.blur() 等價于函式 cv.boxFilter(normalize=True) ,

引數說明:

  • src:低通濾波輸入影像,可以是灰度影像,也可以是多通道的彩色影像
  • dst:低通濾波輸出影像,大小和型別與 src 相同
  • ddepth:輸出影像每個通道的深度(資料型別),ddepth=-1 表示與輸入影像的資料型別相同
  • ksize:模糊核的大小,元組 (width, height),寬度、高度應設為正奇數
  • anchor:卷積核的錨點位置,默認值 (-1, -1),表示以卷積核的中心為錨點
  • normalize:歸一化選項,默認值 normalize=True 時進行歸一化,否則不作歸一化處理
  • borderType:邊界擴充的型別

例程 1.70:影像的低通濾波—盒式濾波器

    # 1.70:影像的低通濾波 (盒式濾波器核)
    img = cv2.imread("../images/Fig0515a.tif", flags=0)  # # flags=0 讀取為灰度影像

    kSize = (5, 5)
    kernel1 = np.ones(kSize, np.float32) / (kSize[0]*kSize[1])  # 生成歸一化盒式核
    imgConv1 = cv2.filter2D(img, -1, kernel1)  # cv2.filter2D 方法
    imgConv2 = cv2.blur(img, kSize)  # cv2.blur 方法
    imgConv3 = cv2.boxFilter(img, -1, kSize)  # cv2.boxFilter 方法 (默認normalize=True)
    
    print("比較 cv2.filter2D 與 cv2.blur 方法結果相同嗎?\t", (imgConv1 == imgConv2).all())
    print("比較 cv2.blur 與 cv2.boxFilter 方法結果相同嗎?\t", (imgConv2 == imgConv3).all())

    kSize = (11, 11)
    imgConv11 = cv2.blur(img, kSize)  # cv2.blur 方法

    plt.figure(figsize=(9, 6))
    plt.subplot(131), plt.axis('off'), plt.title("Original")
    plt.imshow(img, cmap='gray', vmin=0, vmax=255)
    plt.subplot(132), plt.axis('off'), plt.title("cv2.blur (kSize=[5,5])")
    plt.imshow(imgConv2, cmap='gray', vmin=0, vmax=255)
    plt.subplot(133), plt.axis('off'), plt.title("cv2.blur (kSize=[11,11])")
    plt.imshow(imgConv11, cmap='gray', vmin=0, vmax=255)
    plt.tight_layout()
    plt.show()

運行結果如下:

比較 cv2.filter2D 與 cv2.blur 方法結果相同嗎?  True
比較 cv2.blur 與 cv2.boxFilter 方法結果相同嗎?  True

在這里插入圖片描述


2.2 低通高斯濾波器

實際應用中要求卷積核是各向同性的(圓對稱),其回應與方向無關,高斯核是唯一可分離的圓對稱核,因此非常適合影像處理,對于去除影像中的隨機噪聲非常有效,

高斯核的數學運算式為:
w ( s , t ) = G ( s , t ) = 1 2 π σ 2 e ? r 2 / 2 σ 2 w(s,t) = G(s,t) = \frac{1}{2\pi\sigma^2} e^{- {r^2}/{2\sigma ^2}} w(s,t)=G(s,t)=2πσ21?e?r2/2σ2
兩個一維高斯函式 f 和 g 的乘積和卷積的均值與標準差如下:
m f × g = m f σ g 2 + m g σ f 2 σ g 2 + σ f 2 , σ f × g = σ f 2 ? σ g 2 σ g 2 + σ f 2 m f ? g = m f + m g , σ f ? g 2 = σ f 2 + σ g 2 \begin{aligned} m_{f \times g} &= \frac{m_f \sigma _g^2 + m_g \sigma _f^2}{\sigma _g^2 + \sigma _f^2} &,\sigma_{f \times g} &= \frac{\sigma _f^2 * \sigma _g^2}{\sigma _g^2 + \sigma _f^2}\\ m_{f \star g} &= m_f + m_g &,\sigma_{f \star g} ^2 &= \sigma _f^2 + \sigma _g^2 \end{aligned} mf×g?mf?g??=σg2?+σf2?mf?σg2?+mg?σf2??=mf?+mg??,σf×g?,σf?g2??=σg2?+σf2?σf2??σg2??=σf2?+σg2??

OpenCV 提供了 cv.GaussianBlur 函式實作高斯核低通濾波器,cv.getGaussianKernel 函式可以計算一維高斯濾波器的系數,

函式說明:

cv.GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]]) → dst
cv.getGaussianKernel(ksize, sigma[, ktype]) → retval

引數說明:

  • src:低通濾波輸入影像,可以是灰度影像,也可以是多通道的彩色影像
  • dst:低通濾波輸出影像,大小和型別與 src 相同
  • ksize:模糊核的大小,元組 (width, height),寬度、高度應設為正奇數
  • sigmaX:x 軸方向的高斯核標準差
  • sigmaY:y 軸方向的高斯核標準差,可選項
  • borderType:邊界擴充的型別
  • sigma:高斯核的標準差
  • retval:回傳值,高斯濾波器的系數

注意事項:

  1. sigmaY 預設時 sigmaY=sigmaX;sigmaY=sigmaX=0 時,由 ksize 自動計算并設定 sigmaY, sigmaX 的值,

  2. 如 sigma 為負值,由 ksize 自動計算并設定 sigma 的值:sigma = 0.3*((ksize-1)/2 - 1) + 0.8


例程 1.71:影像的低通濾波—高斯濾波器

    # 1.71:影像的低通濾波 (高斯濾波器核)
    img = cv2.imread("../images/imgLena.tif", flags=1)

    kSize = (5, 5)
    imgGaussBlur1 = cv2.GaussianBlur(img, (5,5), sigmaX=10)
    imgGaussBlur2 = cv2.GaussianBlur(img, (11,11), sigmaX=20)

    # 計算高斯核
    gaussX = cv2.getGaussianKernel(5, 0)
    gaussXY = gaussX * gaussX.transpose(1, 0)
    print("gaussX:\n", gaussX)
    print("gaussXY:\n", gaussXY)
    
    plt.figure(figsize=(9, 6))
    plt.subplot(131), plt.axis('off'), plt.title("Original")
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.subplot(132), plt.axis('off'), plt.title("ksize=5, sigma=10")
    plt.imshow(cv2.cvtColor(imgGaussBlur1, cv2.COLOR_BGR2RGB))
    plt.subplot(133), plt.axis('off'), plt.title("ksize=11, sigma=20")
    plt.imshow(cv2.cvtColor(imgGaussBlur2, cv2.COLOR_BGR2RGB))
    plt.tight_layout()
    plt.show()

運行結果如下:

gaussX:
 [[0.0625]
 [0.25  ]
 [0.375 ]
 [0.25  ]
 [0.0625]]
 
gaussXY:
 [[0.00390625 0.015625   0.0234375  0.015625   0.00390625]
 [0.015625   0.0625     0.09375    0.0625     0.015625  ]
 [0.0234375  0.09375    0.140625   0.09375    0.0234375 ]
 [0.015625   0.0625     0.09375    0.0625     0.015625  ]
 [0.00390625 0.015625   0.0234375  0.015625   0.00390625]]

在這里插入圖片描述


2.3 非線性濾波—中值濾波(Median filter)

中值濾波是一種非線性濾波方法,是基于統計排序方法的濾波器 ,中值濾波法將像素點的鄰域內的所有像素點灰度值的中值作為該像素點的灰度值,

注意中值不是平均值,而是按大小排序的中間值,由于需要排序操作,中值濾波消耗的運算時間很長,

中值濾波處理后像素點的灰度值,可能保持不變,也可能改變為鄰域內其它像素點的灰度值,

中值濾波對于消除影像中的椒鹽噪聲非常有效,椒鹽噪聲也稱為脈沖噪聲,是隨機出現的白點或者黑點,通常是由于影像訊號受到干擾而產生,如脈沖干擾、影像掃描,

OpenCV 提供了 cv.medianBlur 函式實作中值濾波演算法,

函式說明:

cv.medianBlur(src, ksize[, dst]) → dst

引數說明:

  • src:輸入影像,可以是灰度影像,也可以是多通道的彩色影像
  • dst:輸出影像,大小和型別與 src 相同
  • ksize:模糊核的線性大小,大于 1 的奇數

例程 1.73:影像的非線性濾波—中值濾波器

    # 1.73:影像的非線性濾波 (中值濾波器)
    img = cv2.imread("../images/Fig0335a.tif", flags=1)

    imgMedianBlur1 = cv2.medianBlur(img, 3)
    imgMedianBlur2 = cv2.medianBlur(img, 7)

    plt.figure(figsize=(9, 6))
    plt.subplot(131), plt.axis('off'), plt.title("Original")
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.subplot(132), plt.axis('off'), plt.title("cv2.medianBlur(size=3)")
    plt.imshow(cv2.cvtColor(imgMedianBlur1, cv2.COLOR_BGR2RGB))
    plt.subplot(133), plt.axis('off'), plt.title("cv2.medianBlur(size=7)")
    plt.imshow(cv2.cvtColor(imgMedianBlur2, cv2.COLOR_BGR2RGB))
    plt.tight_layout()
    plt.show()

在這里插入圖片描述


2.4 非線性濾波—雙邊濾波(Bilateral filter)

雙邊濾波是一種非線性濾波方法,是結合影像的空間鄰近度和像素值相似度的一種折衷處理,同時考慮空域資訊和灰度相似性,在去除噪聲的同時有效地保持邊緣清晰銳利,對于人像處理具有美顏功能,

邊緣的灰度變化較大,高斯濾波會明顯地模糊邊緣,對于高頻細節的保護較弱,雙邊濾波器在空間中也采用高斯濾波器,但增加了一個反映像素強度差異的高斯方差 σ d \sigma_d σd? ,在邊緣附近離的較遠的像素對邊緣上的像素值影響很小,從而保證了邊緣附近的像素值,實作邊緣保存(edge preserving),雙邊濾波器的權值是空間臨近度權值和像素值相似度權值的乘積,因此輸出像素依賴于當前被卷積像素的鄰域,又取決于被卷積像素的灰度值和鄰域像素的灰度值的差,

雙邊濾波器核的數學運算式為:
g ( i , j ) = ∑ f ( k , l ) w ∑ w w = w s ? w r w s = e ? [ ( i ? k ) 2 + ( j ? l ) 2 ] / 2 σ s 2 w r = e ? ∥ ( f ( i , j ) ? f ( k , l ) ∥ 2 / 2 σ r 2 g(i,j) = \frac{\sum f(k,l) w}{\sum w}\\ w = ws * wr\\ ws = e^{- [{(i-k)^2+(j-l)^2}]/{2\sigma _s^2}}\\ wr = e^{- \lVert {(f(i,j)-f(k,l)} \rVert ^2/{2\sigma _r^2}} g(i,j)=wf(k,l)w?w=ws?wrws=e?[(i?k)2+(j?l)2]/2σs2?wr=e?(f(i,j)?f(k,l)2/2σr2?

雙邊濾波器對于低頻資訊的濾波效果較好,但不能干凈地過濾彩色影像里的高頻噪聲,

OpenCV 提供了 cv. bilateralFilter 函式可以實作影像的雙邊濾波,

函式說明:

cv.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]]) → dst

引數說明:

  • src:輸入影像,可以是灰度影像,也可以是多通道的彩色影像
  • dst:輸出影像,大小和型別與 src 相同
  • d:濾波核的像素鄰域直徑,如 d<=0 ,則由從 sigmaSpace 計算得到,
  • sigmaColor:濾波器核在顏色空間的方差,反映產生顏色影響的顏色強度區間的大小
  • sigmaSpace:濾波器核在坐標空間的方差,反映產生顏色影響的影響空間的大小
  • borderType:邊界擴充的型別

例程 1.74:影像的非線性濾波—雙邊濾波器

    # 1.74:影像的非線性濾波—雙邊濾波器
    img = cv2.imread("../images/imgFabricNoise.png", flags=1)

    imgBiFilter = cv2.bilateralFilter(img, d=0, sigmaColor=100, sigmaSpace=10)
    imgMeanFilter = cv2.pyrMeanShiftFiltering(img, sp=15, sr=20)

    plt.figure(figsize=(9, 6))
    plt.subplot(131), plt.axis('off'), plt.title("Original")
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.subplot(132), plt.axis('off'), plt.title("cv2.bilateralFilter")
    plt.imshow(cv2.cvtColor(imgBiFilter, cv2.COLOR_BGR2RGB))
    plt.subplot(133), plt.axis('off'), plt.title("cv2.pyrMeanShiftFiltering")
    plt.imshow(cv2.cvtColor(imgMeanFilter, cv2.COLOR_BGR2RGB))
    plt.tight_layout()
    plt.show()

在這里插入圖片描述


2.5 非線性濾波—聯合雙邊濾波(Joint bilateral filter)

聯合雙邊濾波是在雙邊濾波基礎上對相似性權重模板進行優化,對于紋理影像的處理效果較好,

聯合雙邊濾波與雙邊濾波的區別在于:雙邊濾波是根據影像中不同位置的灰度值差異建立相似性權重模板,再與距離權重模板相乘計算卷積核;聯合濾波是先對影像進行高斯平滑,然后根據高斯平滑影像的灰度值差異建立相似性模板,再計算卷積核,即聯合雙邊濾波是根據原始影像的高斯平滑作為引導圖片來建立相似性模板,進一步地,如果使用其它引導圖片來建立相似性模板,還可以實作其它功能,

OpenCV 在 ximgproc 模塊提供了 cv.ximgproc.jointBilateralFilter 函式實作聯合雙邊濾波演算法,

函式說明:

cv.ximgproc.jointBilateralFilter(joint, src, d, sigmaColor, sigmaSpace[, dst[, borderType]])  → dst

引數說明:

  • src:輸入影像,可以是灰度影像,也可以是多通道的彩色影像
  • joint:聯合濾波的導向影像,大小和型別與 src 相同
  • dst:輸出影像,大小和型別與 src 相同
  • d:濾波核的像素鄰域直徑
  • sigmaColor:濾波器核在顏色空間的方差,反映產生顏色影響的顏色強度區間的大小
  • sigmaSpace:濾波器核在坐標空間的方差,反映產生顏色影響的影響空間的大小
  • borderType:邊界擴充的型別

注意事項:

  1. OpenCV3 中的 ximgproc 模塊提供聯合雙邊濾波演算法,ximgproc 屬于擴展模塊,因此需要安裝擴展包(opencv-contrib-python)提供支持,
  2. 除了主模塊,還引入了contrib,其中的ximgproc模塊包括了聯合雙邊濾波的演算法,因此如果需要使用opencv的聯合雙邊濾波,需要安裝opencv-contrib-python包,

參考例程:

(略)

在這里插入圖片描述


2.6 非線性濾波—導向濾波(Guided filter)

導向濾波又稱引導濾波,通過一張引導圖片反映邊緣、物體等資訊,對輸入影像進行濾波處理,使輸出影像的內容由輸入影像決定,但紋理與引導圖片相似,

導向濾波的原理是區域線性模型,在保持雙邊濾波的優勢(有效保持邊緣,非迭代計算)的同時計算速度很快,

而克服雙邊濾波速度慢的缺點,

導向濾波(導向濾波)不僅能實作雙邊濾波的邊緣平滑,而且在檢測到邊緣附近有很好的表現,可應用在影像增強、HDR壓縮、影像摳圖及影像去霧等場景,

在進行保持邊緣濾波時,可以采用原始影像自身或其預處理后的影像作為導向圖片,

OpenCV 在 ximgproc 模塊提供了 cv.ximgproc.guidedFilter 函式實作導向濾波演算法,

函式說明:

cv.ximgproc_guidedFilter.filter(guide, src, d[, eps[, dDepth]) → dst

引數說明:

  • src:輸入影像,可以是灰度影像,也可以是多通道的彩色影像
  • guide:導向影像,大小和型別與 src 相同
  • dst:輸出影像,大小和型別與 src 相同
  • d:濾波核的像素鄰域直徑
  • eps:規范化引數, eps 的平方類似于雙邊濾波中的 sigmaColor
  • dDepth:輸出圖片的資料深度

參考例程:

(略)
在這里插入圖片描述



3. 空間域銳化濾波(高通濾波)

3.1 影像的梯度算子

影像模糊通過平滑(加權平均)來實作,類似于積分運算,影像銳化則通過微分運算(有限差分)實作,使用一階微分或二階微分都可以得到影像灰度的變化值,

影像銳化的目的是增強影像的灰度跳變部分,使模糊的影像變得清晰,影像銳化也稱為高通濾波,通過和增強高頻,衰減和抑制低頻,影像銳化常用于電子印刷、醫學成像和工業檢測,

  • 恒定灰度區域,一階導數為零,二階導數為零;
  • 灰度臺階或斜坡起點區域,一階導數非零,,二階導數非零;
  • 灰度斜坡區域,一階導數非零,二階導數為零,

一階導數、二階導數的有限差分公式為:

? f ? x = f ( x + 1 ) ? f ( x ) ? 2 f ? x 2 = f ( x + 1 ) ? 2 f ( x ) + f ( x ? 1 ) \begin{aligned} \dfrac{\partial f}{\partial x} &= f(x+1) - f(x) \\ \dfrac{\partial ^2 f}{\partial x ^2} &= f(x+1) - 2f(x) + f(x-1) \end{aligned} ?x?f??x2?2f??=f(x+1)?f(x)=f(x+1)?2f(x)+f(x?1)?

在影像處理中,一階導數用梯度(二維列向量)表示:
? f = g r a d ( f ) = [ g x g y ] = [ ? f / ? x ? f / ? x ] \nabla f = grad(f)=\begin{bmatrix}g_x\\g_y\end{bmatrix}=\begin{bmatrix}\partial f /\partial x \\\partial f /\partial x \end{bmatrix} ?f=grad(f)=[gx?gy??]=[?f/?x?f/?x?]
梯度指出了像素值的最大變化率的方向,經常用于工業檢測中產品缺陷檢測和自動檢測的預處理,

影像梯度提取方法簡單直接,能夠有效的描述影像的原始狀態,因此發展出多種影像梯度算子:Roberts、Prewitt、Sobel、Laplacian、Scharr,


3.2 鈍化掩蔽

簡單地,從原始影像中減去一幅平滑處理的鈍化影像,也可以實作影像銳化效果,稱為鈍化掩蔽,

f ~ ( x , y ) \tilde{f}(x,y) f~?(x,y) 表示平滑影像,則:
KaTeX parse error: No such environment: align at position 8: \begin{?a?l?i?g?n?}? g_{mask} (x,y)…
當 k>1 時,實作高提升濾波;當 k=1 時,實作鈍化掩蔽;k<1時,減弱鈍化掩蔽,

因此,鈍化掩蔽的實作程序是:

(1)對原始影像進行平滑處理,得到平滑影像;

(2)從原始影像中減去平滑影像,產生掩蔽模板;

(3)將原始影像與掩蔽模板加權相加,得到鈍化掩蔽,

原圖減去模糊圖的結果為模板,輸出影像等于原圖加上加權后的模板,當權重為1得到非銳化掩蔽,當權重大于1成為高提升濾波,

鈍化掩蔽沒有直接計算和使用梯度算子,但減法運算具有微分運算的特征,因此本質上是梯度演算法,可以實作銳化濾波的效果,


例程 1.77:影像銳化: 鈍化掩蔽

    # 1.77:影像銳化: 鈍化掩蔽
    img = cv2.imread("../images/Fig0338a.tif", flags=0)

    # 對原始影像進行平滑,GaussianBlur(img, size, sigmaX)
    imgGauss = cv2.GaussianBlur(img, (5,5), sigmaX=5)
    imgGaussNorm = cv2.normalize(imgGauss,dst=None,alpha=0,beta=255,norm_type=cv2.NORM_MINMAX)

    # 掩蔽模板:從原始影像中減去平滑影像
    imgMask = img - imgGaussNorm

    passivation1 = img + 0.6 * imgMask  # k<1 減弱鈍化掩蔽
    imgPas1 = cv2.normalize(passivation1, None, 0, 255, cv2.NORM_MINMAX)
    passivation2 = img + imgMask  # k=1 鈍化掩蔽
    imgPas2 = cv2.normalize(passivation2, None, 0, 255, cv2.NORM_MINMAX)
    passivation3 = img + 2 * imgMask  # k>1 高提升濾波
    imgPas3 = cv2.normalize(passivation3, None, 0, 255, cv2.NORM_MINMAX)

    plt.figure(figsize=(10, 7))
    titleList = ["1. Original", "2. GaussSmooth", "3. MaskTemplate",
                 "4. Passivation(k=0.5)", "5. Passivation(k=1.0)", "6. Passivation(k=2.0)"]
    imageList = [img, imgGauss, imgMask, imgPas1, imgPas2, imgPas3]
    for i in range(6):
        plt.subplot(2,3,i+1), plt.title(titleList[i]), plt.axis('off')
        plt.imshow(imageList[i], 'gray', vmin=0, vmax=255)
    plt.tight_layout()
    plt.show()

鈍化掩蔽的影像銳化效果如下圖所示,注意當 k>1 時,實作高提升濾波;當 k=1 時,實作鈍化掩蔽;而當 k<1時則會減弱鈍化掩蔽,

在這里插入圖片描述


3.3 拉普拉斯卷積核(Laplacian)

各向同性卷積核的回應與方向無關,最簡單的各向同性導數算子(卷積核)是拉普拉斯算子(Laplace):

? 2 f = ? 2 f ? x 2 + ? 2 f ? y 2 ? 2 f ? x 2 = f ( x + 1 , y ) ? 2 f ( x , y ) + f ( x ? 1 , y ) ? 2 f ? y 2 = f ( x , y + 1 ) ? 2 f ( x , y ) + f ( x , y ? 1 ) ? 2 f ( x , y ) = f ( x + 1 , y ) + f ( x ? 1 , y ) + f ( x , y + 1 ) + f ( x , y ? 1 ) ? 4 f ( x , y ) \begin{aligned} \nabla ^2 f &= \dfrac{\partial ^2 f}{\partial x ^2} + \dfrac{\partial ^2 f}{\partial y ^2} \\ \dfrac{\partial ^2 f}{\partial x ^2} &= f(x+1,y) - 2f(x,y) + f(x-1,y) \\ \dfrac{\partial ^2 f}{\partial y ^2} &= f(x,y+1) - 2f(x,y) + f(x,y-1) \\ \nabla ^2 f(x,y) &= f(x+1,y) + f(x-1,y) + f(x,y+1) + f(x,y-1) - 4f(x,y) \end{aligned} ?2f?x2?2f??y2?2f??2f(x,y)?=?x2?2f?+?y2?2f?=f(x+1,y)?2f(x,y)+f(x?1,y)=f(x,y+1)?2f(x,y)+f(x,y?1)=f(x+1,y)+f(x?1,y)+f(x,y+1)+f(x,y?1)?4f(x,y)?

由此可以得到拉普拉斯核 K1,類似地,考慮對角項后可以得到拉普拉斯核 K2,

K 1 = [ 0 1 0 1 ? 4 1 0 1 0 ] , K 2 = [ 1 1 1 1 ? 8 1 1 1 1 ] , K 3 = [ 0 ? 1 0 ? 1 4 ? 1 0 ? 1 0 ] , K 4 = [ ? 1 ? 1 ? 1 ? 1 8 ? 1 ? 1 ? 1 ? 1 ] K1= \begin{bmatrix} 0 & 1 &0\\ 1 & -4 &1\\ 0 & 1 &0\\ \end{bmatrix}, \ K2= \begin{bmatrix} 1 & 1 &1\\ 1 & -8 &1\\ 1 & 1 &1\\ \end{bmatrix}, \ K3= \begin{bmatrix} 0 & -1 &0\\ -1 & 4 &-1\\ 0 & -1 &0\\ \end{bmatrix}, \ K4= \begin{bmatrix} -1 & -1 &-1\\ -1 & 8 &-1\\ -1 & -1 &-1\\ \end{bmatrix} K1=???010?1?41?010????, K2=???111?1?81?111????, K3=???0?10??14?1?0?10????, K4=????1?1?1??18?1??1?1?1????

Laplace 是導數算子,會突出影像中的急劇灰度變化,抑制灰度緩慢變化區域,往往會產生暗色背景下的灰色邊緣和不連續影像,將拉普拉斯影像與原圖疊加,可以得到保留銳化效果的影像,

拉普拉斯卷積核很容易通過卷積操作 cv. filter_2d 實作,OpenCV 也提供了拉普拉斯算子 cv.Laplacian 來實作,

函式說明:

cv.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]]) → dst

引數說明:

  • src:輸入影像,可以是灰度影像,也可以是多通道的彩色影像

  • ddepth:輸出圖片的資料深度:

  • dst:輸出影像,大小和型別與 src 相同

  • ksize:計算二階導數濾波器的孔徑大小,必須為正奇數,可選項

  • scale:縮放比例因子,可選項,默認值為 1

  • delta:輸出影像的偏移量,可選項,默認值為 0

  • borderType:邊界擴充的型別,注意不支持對側填充(BORDER_WRAP)


例程 1.78:影像銳化:Laplacian 算子

    # 1.78:影像銳化:拉普拉斯算子 (Laplacian)
    img = cv2.imread("../images/Fig0338a.tif", flags=0)  # NASA 月球影像圖

    # 使用函式 filter2D 實作 Laplace 卷積算子
    kernLaplace = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])  # Laplacian kernel
    imgLaplace1 = cv2.filter2D(img, -1, kernLaplace, borderType=cv2.BORDER_REFLECT)

    # 使用 cv2.Laplacian 實作 Laplace 卷積算子
    imgLaplace2 = cv2.Laplacian(img, -1, ksize=3)
    imgRecovery = cv2.add(img, imgLaplace2)  # 恢復原影像

    # 二值化邊緣圖再卷積
    ret, binary = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_TRIANGLE)
    imgLaplace3 = cv2.Laplacian(binary, cv2.CV_64F)
    imgLaplace3 = cv2.convertScaleAbs(imgLaplace3)

    plt.figure(figsize=(9, 6))
    plt.subplot(131), plt.axis('off'), plt.title("Original")
    plt.imshow(img, cmap='gray', vmin=0, vmax=255)
    plt.subplot(132), plt.axis('off'), plt.title("cv.Laplacian")
    plt.imshow(imgLaplace2, cmap='gray', vmin=0, vmax=255)
    plt.subplot(133), plt.axis('off'), plt.title("thresh-Laplacian")
    plt.imshow(imgLaplace3, cmap='gray', vmin=0, vmax=255)
    plt.tight_layout()
    plt.show()

由于拉普拉斯卷積核很敏感,可以先進行閾值化處理,再進行拉普拉斯卷積,例程對比了直接進行拉普拉斯卷積,與閾值化處理后進行拉普拉斯卷積,結果如下圖所示,

在這里插入圖片描述


3.4 Sobel 梯度算子

Sobel 算子是一種離散的微分算子,是高斯平滑和微分求導的聯合運算,抗噪聲能力強,

Sobel 梯度算子利用區域差分尋找邊緣,計算得到梯度的近似值,先計算水平、垂直方向的梯度 G x = k x ? s r c G_x = k_x * src Gx?=kx??src G y = k y ? s r c G_y = k_y * src Gy?=ky??src,再求總梯度 $ G = \sqrt{G_x2+G_y2}$ ,編程實作時,可以用絕對值近似平方根: G = ∣ G x ∣ + ∣ G y ∣ G = |G_x| + |G_y| G=Gx?+Gy?

Sobel 梯度算子是由平滑算子和差分算子卷積得到,Sobel 梯度算子的卷積核為:
K x = [ ? 1 0 1 ? 2 0 2 ? 1 0 1 ] , K y = [ ? 1 ? 2 ? 1 0 0 0 1 2 1 ] K_x = \begin{bmatrix} -1 & 0 &1\\ -2 & 0 &2\\ -1 & 0 &1\\ \end{bmatrix}, \ K_y = \begin{bmatrix} -1 &-2 &-1\\ 0 &0 &0\\ 1 &2 &1\\ \end{bmatrix} Kx?=????1?2?1?000?121????, Ky?=????101??202??101????

Sobel 梯度算子很容易通過卷積操作 cv.filter2D 實作,OpenCV 也提供了函式 cv.Sobel 實作 Sobel 梯度算子,

函式說明:

cv.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]]) → dst

引數說明:

  • src:輸入影像,灰度影像,不適用彩色影像
  • dst:輸出影像,大小和型別與 src 相同
  • ddepth:輸出圖片的資料深度,由輸入影像的深度進行選擇
  • dx:x 軸方向導數的階數,1 或 2
  • dy:y 軸方向導數的階數,1 或 2
  • ksize:Sobel 卷積核的大小,可選的取值為:1/3/5/7,ksize=-1 時使用 Scharr 算子運算
  • scale:縮放比例因子,可選項,默認值為 1
  • delta:輸出影像的偏移量,可選項,默認值為 0
  • borderType:邊界擴充的型別,注意不支持對側填充(BORDER_WRAP)

注意事項:

  • ddepth 的設定比較復雜,而且容易出錯,限于篇幅本文不做展開,

此外,為了處理微分運算導致的資料例外(超出 [0,255]),OpenCV 提供了 cv.convertScaleAbs 進行飽和運算(saturate): d s t = s a t u r a t e ( s r c ? α + b e t a ) dst = saturate(src * \alpha + beta) dst=saturate(src?α+beta)

函式說明:

cv.convertScaleAbs(src[, alpha[, beta]]) → dst

引數說明:

  • src:輸入影像,可以是灰度影像,也可以是多通道的彩色影像
  • dst:輸出影像,大小和型別與 src 相同
  • alpha:調節系數,可選項,默認值為 1
  • beta:亮度調節,可選項,默認值為 0

例程 1.79:影像銳化:Sobel 算子

    # 1.79:影像銳化:Sobel 算子
    # img = cv2.imread("../images/Fig0338a.tif", flags=0)  # NASA 月球影像圖
    img = cv2.imread("../images/imgGaia.tif", flags=0)

    # 使用函式 filter2D 實作 Sobel 算子
    kernSobelX = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])  # SobelX kernel
    kernSobelY = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])  # SobelY kernel
    imgSobelX = cv2.filter2D(img, -1, kernSobelX, borderType=cv2.BORDER_REFLECT)
    imgSobelY = cv2.filter2D(img, -1, kernSobelY, borderType=cv2.BORDER_REFLECT)

    # 使用 cv2.Sobel 實作 Sobel 算子
    SobelX = cv2.Sobel(img, cv2.CV_16S, 1, 0)  # 計算 x 軸方向
    SobelY = cv2.Sobel(img, cv2.CV_16S, 0, 1)  # 計算 y 軸方向
    absX = cv2.convertScaleAbs(SobelX)  # 轉回 uint8
    absY = cv2.convertScaleAbs(SobelY)  # 轉回 uint8
    SobelXY = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)  # 用絕對值近似平方根

    plt.figure(figsize=(10, 6))
    plt.subplot(141), plt.axis('off'), plt.title("Original")
    plt.imshow(img, cmap='gray', vmin=0, vmax=255)
    plt.subplot(142), plt.axis('off'), plt.title("SobelX")
    plt.imshow(SobelX, cmap='gray', vmin=0, vmax=255)
    # plt.imshow(imgSobelX, cmap='gray', vmin=0, vmax=255)
    plt.subplot(143), plt.axis('off'), plt.title("SobelY")
    plt.imshow(SobelY, cmap='gray', vmin=0, vmax=255)
    # plt.imshow(imgSobelY, cmap='gray', vmin=0, vmax=255)
    plt.subplot(144), plt.axis('off'), plt.title("SobelXY")
    plt.imshow(SobelXY, cmap='gray')
    plt.tight_layout()
    plt.show()

在這里插入圖片描述


3.5 Scharr 算子

Scharr 算子也稱為 Scharr 濾波器,計算 x 軸或 y 軸方向的影像差分,

Scharr 算子是 Soble 算子在 ksize=3 時的優化,與 Soble 的速度相同,且精度更高,Scharr 算子與 Sobel 算子的不同點是在平滑部分,其中心元素占的權重更重,相當于使用較小標準差的高斯函式,也就是更瘦高的模板,

Scharr 算子的卷積核為:
G x = [ ? 3 0 3 ? 10 0 10 ? 3 0 3 ] , G y = [ ? 3 10 ? 3 0 0 10 3 10 3 ] G_x = \begin{bmatrix} -3 & 0 &3\\ -10 & 0 &10\\ -3 & 0 &3\\ \end{bmatrix}, \ G_y = \begin{bmatrix} -3 &10 &-3\\ 0 &0 &10\\ 3 &10 &3\\ \end{bmatrix} Gx?=????3?10?3?000?3103????, Gy?=????303?10010??3103????

Scharr 算子很容易通過卷積操作 cv.filter2D 實作,OpenCV 也提供了函式 cv.Scharr 實作 Scharr 算子,

函式說明:

cv.Scharr(src, ddepth, dx, dy[, dst[, scale[, delta[, borderType]]]]) → dst

引數說明:

  • src:輸入影像
  • dst:輸出影像,大小和型別與 src 相同
  • ddepth:輸出圖片的資料深度,由輸入影像的深度進行選擇
  • dx:x 軸方向導數的階數
  • dy:y 軸方向導數的階數
  • scale:縮放比例因子,可選項,默認值為 1
  • delta:輸出影像的偏移量,可選項,默認值為 0
  • borderType:邊界擴充的型別,注意不支持對側填充(BORDER_WRAP)

例程 1.80:影像銳化:Scharr 算子

    # 1.80:影像銳化:Scharr 算子
    # img = cv2.imread("../images/Fig0338a.tif", flags=0)  # NASA 月球影像圖
    img = cv2.imread("../images/imgGaia.tif", flags=0)

    # 使用函式 filter2D 實作 Scharr 算子
    kernScharrX = np.array([[-3, 0, 3], [-10, 0, 10], [-3, 0, 3]])  # ScharrX kernel
    kernScharrY = np.array([[-3, 10, -3], [0, 0, 10], [3, 10, 3]])  # ScharrY kernel

    # 使用 cv2.Scharr 實作 Scharr 算子
    ScharrX = cv2.Scharr(img, cv2.CV_16S, 1, 0)  # 計算 x 軸方向
    ScharrY = cv2.Scharr(img, cv2.CV_16S, 0, 1)  # 計算 y 軸方向
    absX = cv2.convertScaleAbs(ScharrX)  # 轉回 uint8
    absY = cv2.convertScaleAbs(ScharrY)  # 轉回 uint8
    ScharrXY = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)  # 用絕對值近似平方根

    plt.figure(figsize=(10, 6))
    plt.subplot(141), plt.axis('off'), plt.title("Original")
    plt.imshow(img, cmap='gray', vmin=0, vmax=255)
    plt.subplot(142), plt.axis('off'), plt.title("ScharrX")
    plt.imshow(ScharrX, cmap='gray', vmin=0, vmax=255)
    plt.subplot(143), plt.axis('off'), plt.title("ScharrY")
    plt.imshow(ScharrY, cmap='gray', vmin=0, vmax=255)
    plt.subplot(144), plt.axis('off'), plt.title("ScharrXY")
    plt.imshow(ScharrXY, cmap='gray')
    plt.tight_layout()
    plt.show()

在這里插入圖片描述



4. 低通、高通、帶阻、帶通

影像濾波是在盡可能保留影像細節特征的條件下對目標影像的噪聲進行抑制,是常用的影像預處理操作,

空間域和頻率域線性濾波器可以分為四類:低通濾波器、高通濾波器、帶通濾波器和帶阻濾波器,后三類濾波器都可以由低通濾波器構造:

  • 低通濾波器: l p ( x , y ) lp(x,y) lp(x,y)
  • 高通濾波器: h p ( x , y ) = δ ( x , y ) ? l p ( x , y ) hp(x,y) = \delta(x,y) - lp(x,y) hp(x,y)=δ(x,y)?lp(x,y)
  • 帶通濾波器: b r ( x , y ) = l p 1 ( x , y ) + h p 2 ( x , y ) br(x,y) = lp_1(x,y) + hp_2(x,y) br(x,y)=lp1?(x,y)+hp2?(x,y)
  • 帶阻濾波器: b p ( x , y ) = δ ( x , y ) ? b r ( x , y ) bp(x,y) = \delta(x,y) - br(x,y) bp(x,y)=δ(x,y)?br(x,y)

這些傳遞函式都可以由一個低通濾波器傳遞函式通過線性變換得到,
本案例中建立一維低通濾波器傳遞函式,進而可以生成空間濾波器核,
以一幅由以下公式描述的同心圓反射板為例,測驗濾波方法的特性:
z ( x , y ) = [ 1 + c o s ( x 2 + y 2 ) ] / 2 , x , y ∈ [ ? 8.2 , 8.2 ] z(x,y) = [1 + cos(x^2+y2)]/2,\quad x,y \in [-8.2,8.2] z(x,y)=[1+cos(x2+y2)]/2x,y[?8.2,8.2]
首先,設計一個一維空間低通濾波器函式
x = s i n ( x ) / x , x ∈ [ ? 6 π , 6 π ] x = sin(x) / x,\quad x \in [-6\pi,6\pi] x=sin(x)/x,x[?6π,6π]

例程 1.81:低通/高通,帶阻/帶通

    # 1.81:低通/高通,帶阻/帶通
    # 同心圓反射板
    height, width = 597, 597
    m = int((height-1) / 2)  # 298
    n = int((width-1) / 2)  # 298
    X = np.linspace(-8.2, 8.2, height)  # 長度:597
    Y = np.linspace(-8.2, 8.2, width)
    x, y = np.meshgrid(X, Y)
    circle = 0.5 * (1 + np.cos(x**2 + y**2))
    for i in range(circle.shape[0]):
        for j in range(circle.shape[1]):
            if np.sqrt((i-m)**2 + (j-n)**2) > m:
                circle[i,j] = 0

    # 一維低通濾波器函式
    hFilter, wFilter = 128, 128
    mFilter = int((hFilter-1) / 2)  # 63
    nFilter = int((wFilter-1) / 2)  # 63
    x = np.linspace(-6*np.pi, 6*np.pi, hFilter)  # 長度:128
    y = np.linspace(-6*np.pi, 6*np.pi, wFilter)  # 長度:128
    scale = 1  # 濾波器縮放因子
    xFilter = np.sin(x*scale) / x  # 128

    # 二維低通濾波器函式
    X, Y = np.meshgrid(x, y)  # 生成x、y網格化資料
    Z = np.sin(np.sqrt(X**2+Y**2)) / np.sqrt(X**2+Y**2)

    plt.figure(figsize=(10, 3))
    plt.subplot(131), plt.axis('off'), plt.title("Concentric circles(597*597)"), plt.imshow(circle, 'gray')
    plt.subplot(132), plt.title("1D low-pass filter"), plt.plot(x, xFilter), plt.axis([-20,20,-0.25,1.25])
    ax = plt.subplot(133, projection='3d')
    surf = ax.plot_surface(X, Y, Z, cmap=plt.get_cmap("rainbow"), linewidth=0, antialiased=False)
    ax.set_title("2D low-pass filter")
    plt.show()

在這里插入圖片描述



5. 空間域影像增強技術的綜合應用

空間域影像增強的方法很多,各有不同的特點和作用,對于一幅具體影像,往往要根據影像的實際情況,綜合使用幾種影像增強的方法,以便達到較為理想的結果,

本節以人體骨骼掃描影像(來自G.E.MedicalSystem)為例,要求對影像進行銳化以顯示更多的骨骼細節,原始影像的灰度級比較狹窄,噪聲含量大,簡單使用一種影像增強方法難以達到理想的結果,需要綜合應用空間域影像增強技術:首先使用拉普拉斯變換突出細節,然后使用梯度算子增強突出的邊緣,再使用低通濾波器降低噪聲,以此為模板得到需要的銳化影像,最后用伽馬校正調整灰度級的動態范圍,具體步驟如下:

(1)拉普拉斯變換,突出原始影像的細節;
(2)原始影像疊加拉普拉斯變換影像,恢復背景特征;
(3)Sobel 梯度算子,增強突出的邊緣;
(4)用盒式濾波器平滑梯度影像;
(5)拉普拉斯與平滑梯度相乘得到掩蔽模板;
(6)原始影像與掩蔽模板疊加,得到銳化影像;
(7)Gamma 變換,增大灰度級的動態范圍,


例程 1.82 空間域影像增強技術的綜合應用

    # 1.82 空間域影像增強技術的綜合應用
    # 原始影像,人體骨骼掃描影像
    img = cv2.imread("../images/bonescan.tif", flags=0)  # 人體骨骼掃描影像

    # 圖 2:拉普拉斯變換,突出細節
    kernLaplace = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]], np.int8)  # Laplacian kernel
    # kernLaplaceD = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]], np.int8)  # Diagonal Laplacian kernel
    Laplacian = cv2.filter2D(img, ddepth=-1, kernel=kernLaplace)
    imgLaplacian = np.uint8(cv2.normalize(Laplacian, None, 0, 255, cv2.NORM_MINMAX))

    # 圖 3:原始影像 + 拉普拉斯變換,恢復背景特征
    AddLap = img + imgLaplacian
    imgAddLap = np.uint8(cv2.normalize(AddLap, None, 0, 255, cv2.NORM_MINMAX))

    # 圖 4:Sobel 梯度算子,增強突出的邊緣
    SobelX = cv2.Sobel(img, cv2.CV_16S, 1, 0)  # 計算 x 軸方向
    SobelY = cv2.Sobel(img, cv2.CV_16S, 0, 1)  # 計算 y 軸方向
    absX = cv2.convertScaleAbs(SobelX)  # 轉回 uint8
    absY = cv2.convertScaleAbs(SobelY)  # 轉回 uint8
    SobelXY = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)  # 用絕對值近似平方根
    imgSobel = np.uint8(cv2.normalize(SobelXY, None, 0, 255, cv2.NORM_MINMAX))

    # 圖 5:用 (5,5) 盒式濾波器平滑梯度影像
    kernelBox = np.ones(5, np.float32) / (5 * 5)  # 生成歸一化盒式核
    SobelBox = cv2.filter2D(img, -1, kernelBox)  # cv2.filter2D 方法
    imgSobelBox = cv2.normalize(SobelBox, None, 0, 255, cv2.NORM_MINMAX)

    # 圖 6:圖2 與 圖5 相乘得到模板 mask,突出了強邊緣,相對較低了噪聲
    mask = imgLaplacian * imgSobelBox
    imgMask = np.uint8(cv2.normalize(mask, None, 0, 255, cv2.NORM_MINMAX))

    # 圖7:原始影像與圖 6 相加,得到銳化影像,大部分細節更清晰
    passivation = img + imgMask * 0.3
    imgPassi = np.uint8(cv2.normalize(passivation, None, 0, 255, cv2.NORM_MINMAX))

    # 圖8: 冪律變換(Gamma 變換),增大灰度級的動態范圍
    epsilon = 1e-5  # 非常小的值以防出現除0的情況
    # Gamma = np.zeros_like(imgPassi, dtype=np.float)
    Gamma = np.power(imgPassi + epsilon, 0.5)
    imgGamma = np.uint8(cv2.normalize(Gamma, None, 0, 255, cv2.NORM_MINMAX))

    # 繪圖
    plt.figure(figsize=(10, 7))
    titleList = ["1. Original", "2. Laplacian", "3. Original + Laplacian", "4. Sobel",
                 "5. Sobel Box5", "6. Sobel mask", "7. Passivation", "8. Gamma correction"]
    imageList = [img, imgLaplacian, imgAddLap, imgSobel, imgSobelBox, imgMask, imgPassi, imgGamma]
    for i in range(8):
        plt.subplot(2,4,i+1), plt.title(titleList[i]), plt.axis('off')
        plt.imshow(imageList[i], 'gray', vmin=0, vmax=255)
    plt.tight_layout()
    plt.show() 

在這里插入圖片描述



著作權宣告:

歡迎關注『Python 小白從零開始 OpenCV 學習課 @ youcans』 原創作品

本文中部分原始圖片來自 Rafael C. Gonzalez “Digital Image Processing, 4th.Ed.”,特此致謝,

原創作品,轉載必須標注原文鏈接:https://blog.csdn.net/youcans/article/details/121422046

Copyright 2021 youcans, XUPT

Crated:2021-12-05


歡迎關注 『Python小白從零開始 OpenCV 學習課』 系列,持續更新
Python 大白從零開始 OpenCV 學習課-1.安裝與環境配置
Python 大白從零開始 OpenCV 學習課-2.影像讀取與顯示
Python 大白從零開始 OpenCV 學習課-3.影像的創建與修改
Python 大白從零開始 OpenCV 學習課-4.影像的疊加與混合
Python 大白從零開始 OpenCV 學習課-5.影像的幾何變換
Python 大白從零開始 OpenCV 學習課-6. 灰度變換與直方圖處理
Python 大白從零開始 OpenCV 學習課-7. 空間域影像濾波

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/374766.html

標籤:其他

上一篇:演算法基礎系列第三章——層層推進的BFS

下一篇:【hadoop】虛擬機安裝及網路配置

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more