計算機視覺--opencv(代碼詳細教程)(二)

一、圖片的邊界填充

在 OpenCV 中,cv2.copyMakeBorder()是用于給圖像添加邊框(邊緣)的核心 API,其完整語法和參數說明如下:

函數完整定義

cv2.copyMakeBorder(src, top, bottom, left, right, borderType, value=None)

參數詳細說明

  1. src:輸入圖像(numpy.ndarray類型),可以是單通道(灰度圖)或多通道(如 RGB/BGR 彩色圖)。

  2. top:整數,指定圖像頂部需要添加的邊框像素數量。

  3. bottom:整數,指定圖像底部需要添加的邊框像素數量。

  4. left:整數,指定圖像左側需要添加的邊框像素數量。

  5. right:整數,指定圖像右側需要添加的邊框像素數量。

  6. borderType:邊框填充方式的枚舉值,決定了邊框像素如何生成。OpenCV 支持以下類型:

    • cv2.BORDER_WRAP:外包裝填充
      邊框像素從圖像的對側 “纏繞” 而來(類似平鋪效果)。
      例:原圖邊緣為[1,2,3,4],右側邊框可能填充[1,2](復用左側內容)。

    • cv2.BORDER_REFLECT_101(或cv2.BORDER_DEFAULT:對稱填充
      REFLECT類似,但反射以邊緣像素為軸,包含邊緣像素。
      例:原圖邊緣為[1,2,3,4],填充后可能為[2,1,1,2,3,4,4,3](OpenCV 推薦默認使用此類型)。

    • cv2.BORDER_REFLECT:反射填充
      邊框像素是原圖邊緣的鏡像反射,不包含邊緣像素本身的重復。
      例:原圖邊緣為[1,2,3,4],填充后可能為[3,2,1,2,3,4,3,2]

    • cv2.BORDER_REPLICATE:復制填充
      邊框像素由原圖最邊緣的像素復制而來(如右側邊框復制原圖最右列像素,頂部邊框復制原圖最上行像素)。

    • cv2.BORDER_CONSTANT:常數填充
      邊框像素使用指定的單一顏色填充,需配合value參數設置顏色(BGR 格式,如(255,0,0)表示藍色)。

  7. value:可選參數,僅當borderType=cv2.BORDER_CONSTANT時有效,指定邊框的顏色值:

    • 彩色圖:BGR 三通道值(如(0,255,0)表示綠色)。

    • 灰度圖:單值(如128表示灰色)。

返回值

  • 添加邊框后的新圖像(numpy.ndarray類型),尺寸為:
    (src.shape[0] + top + bottom, src.shape[1] + left + right, src.shape[2])(彩色圖)
    或?(src.shape[0] + top + bottom, src.shape[1] + left + right)(灰度圖)。

示例代碼:

可以自選隨便一張圖片

# 導入OpenCV庫
import cv2# 讀取圖像文件,返回BGR格式的numpy數組
# 注意:如果圖像路徑錯誤,會返回None但不報錯
ys = cv2.imread('mm.jpg')# 調整圖像尺寸:按比例縮小
# dsize=None表示不直接指定目標尺寸,而是通過fx和fy設置縮放比例
# fx=0.2表示寬度縮小為原來的20%,fy=0.2表示高度縮小為原來的20%
ys = cv2.resize(ys, dsize=None, fx=0.2, fy=0.2)# 下面是另一種尺寸調整方式(被注釋掉了)
# 直接指定目標尺寸為(640, 480),參數格式為(寬度, 高度)
# ys = cv2.resize(ys, (640, 480))# 定義邊界填充的尺寸:上下左右各填充50像素
# top: 頂部填充像素數,bottom: 底部填充像素數
# left: 左側填充像素數,right: 右側填充像素數
top, bottom, left, right = 50, 50, 50, 50# 1. 常量邊界填充(BORDER_CONSTANT)
# 使用指定的顏色填充邊界,這里填充為(229,25,80)對應的粉紅色
# 參數說明:原圖像、上下左右填充量、邊界類型、填充顏色
constant = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_CONSTANT, value=(229,25,80))# 2. 反射邊界填充(BORDER_REFLECT)
# 以圖像邊緣為軸,對稱反射填充像素(類似鏡像)
# 例如原圖像邊緣像素為a,b,c,則填充為c,b,a,b,c,b,a...
reflect = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_REFLECT)# 3. 反射101邊界填充(BORDER_REFLECT101)
# 與REFLECT類似,但不重復邊緣像素
# 例如原圖像邊緣像素為a,b,c,則填充為b,a,b,c,b,a...
reflect101 = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_REFLECT101)# 4. 復制邊界填充(BORDER_REPLICATE)
# 重復最邊緣的像素進行填充
# 例如原圖像邊緣像素為a,b,c,則填充為c,c,c,c,c...
replicate = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_REPLICATE)# 5. 環繞邊界填充(BORDER_WRAP)
# 以圖像對側的內容填充邊界(類似平鋪效果)
# 例如右側邊界用左側內容填充,底部邊界用頂部內容填充
wrap = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_WRAP)# 顯示原始圖像,窗口名為"1.yuantu"
cv2.imshow('1.yuantu', ys)
# cv2.waitKey(0)  # 注釋掉的等待按鍵,不啟用時所有窗口會同時顯示# 顯示常量填充效果
cv2.imshow('2.CONSTANT', constant)
# cv2.waitKey(0)# 顯示反射填充效果
cv2.imshow('3.REFLECT', reflect)
# cv2.waitKey(0)# 顯示反射101填充效果
cv2.imshow('4.REFLECT 101', reflect101)
# cv2.waitKey(0)# 顯示復制填充效果
cv2.imshow('5.REPLICATE', replicate)
# cv2.waitKey(0)# 顯示環繞填充效果
cv2.imshow('6.WRAP', wrap)# 等待用戶按鍵,0表示無限等待,按任意鍵后關閉所有窗口
cv2.waitKey(0)

二、圖像的運算

1. 像素值加法(numpy 運算)
c = a + 10  # 對圖像a的所有像素值加10
c = a[50:250, 50:200] + b[50:250, 50:200]  # 對指定區域的像素相加
  • 原理:基于 Numpy 數組的元素級運算,每個像素的 BGR 三個通道值分別參與運算
  • 特點:屬于模運算(溢出時取模),例如像素值250 + 10 = 260 → 260 % 256 = 4
  • 限制:要求參與運算的圖像區域尺寸完全相同(如a[50:250,50:200]b[50:250,50:200]的寬高必須一致)
2. 圖像加法(OpenCV 函數)
c = cv2.add(a, b)
  • 功能:與a + b類似,但屬于飽和運算(溢出時取最大值 255)
  • 區別
    • a + b:模運算(250 + 10 = 4)
    • cv2.add(a, b):飽和運算(250 + 10 = 255)
  • 優勢:更符合視覺預期,避免像素值溢出導致的異常顏色
3. 加權圖像融合:cv2.addWeighted()
c = cv2.addWeighted(a, 0.5, b, 0.5, 10)
  • 功能:按權重融合兩張圖像,公式為:
    result = α×img1 + β×img2 + γ
  • 參數
    • a/b:輸入圖像(需尺寸和通道數相同)
    • 0.5/0.5:權重αβ(總和可不為 1,控制兩張圖像的占比)
    • 10:偏置項γ(對結果整體加一個常量,調整亮度)
  • 應用場景:實現圖像淡入淡出、疊加水印等效果

示例代碼:

# 導入OpenCV庫,cv2是OpenCV在Python中的別名
import cv2# 讀取圖像文件,返回的是numpy數組(ndarray),默認讀取為彩色圖像(BGR格式)
# 注意:如果文件路徑錯誤,會返回None但不報錯
a = cv2.imread('flower_dog.jpg')  # 讀取第一張圖像
b = cv2.imread('img.png')         # 讀取第二張圖像
# 像素值運算:對圖像a的所有像素點的每個通道值都加10
# 原理:numpy數組的元素級運算,屬于模運算(超過255會取模,如250+10=260→260%256=4)
c = a + 10
# 創建窗口顯示圖像,第一個參數是窗口名稱,第二個參數是要顯示的圖像
cv2.imshow('yuan', a)       # 顯示原始圖像a,窗口名為"yuan"
cv2.imshow('a+10', c)       # 顯示像素值加10后的圖像c,窗口名為"a+10"
# 等待鍵盤輸入,參數0表示無限等待,直到用戶按下任意鍵
# 必須配合imshow使用,否則窗口會一閃而逝
cv2.waitKey(0)
# 圖像區域像素相加:對a和b的指定區域進行像素加法
# [50:250,50:200]表示裁剪圖像的行范圍50-250,列范圍50-200(注意是高×寬)
# 要求兩個區域的尺寸完全相同,否則會報錯
c = a[50:250, 50:200] + b[50:250, 50:200]
cv2.imshow('a+b', c)        # 顯示區域相加的結果# 重新讀取圖像(可能因為之前的操作修改了原圖像數據)
a = cv2.imread('flower_dog.jpg')
b = cv2.imread('img.png')
# 調整圖像尺寸:將a和b都調整為400×400像素
# 注意參數是(寬度, 高度),與圖像數組的(高度,寬度)維度順序相反
a = cv2.resize(a, (400, 400))
b = cv2.resize(b, (400, 400))
# OpenCV的圖像加法函數:與a+b的區別是采用飽和運算(超過255則取255)
# 例如250+10=255而不是4,更符合視覺預期
c = cv2.add(a, b)
cv2.imshow('a,add,b', c)    # 顯示cv2.add的運算結果
cv2.waitKey(0)              # 等待按鍵輸入
cv2.destroyAllWindows()     # 關閉所有OpenCV創建的窗口# 再次讀取圖像,準備進行加權融合
a = cv2.imread('flower_dog.jpg')
b = cv2.imread('img.png')
# 統一圖像尺寸,確保可以進行融合運算
a = cv2.resize(a, (400, 400))
b = cv2.resize(b, (400, 400))
# 圖像加權融合:result = α*a + β*b + γ
# 參數說明:a和b是輸入圖像,0.5和0.5是權重,10是亮度調節值(偏置項)
# 公式:c = 0.5*a + 0.5*b + 10
c = cv2.addWeighted(a, 0.5, b, 0.5, 10)
cv2.imshow('addweighted', c)  # 顯示加權融合結果
cv2.waitKey(0)                # 等待按鍵輸入
cv2.destroyAllWindows()       # 關閉所有窗口,釋放資源

三、圖像的閾值處理

1.?cv2.THRESH_BINARY(二進制閾值)

核心邏輯:將圖像像素值與閾值比較,大于閾值的像素設為最大值(通常為 255,白色),小于等于閾值的設為 0(黑色)。
數學表達式
dst(x,y) = maxval, if src(x,y) > thresh
dst(x,y) = 0, otherwise

直觀理解:非黑即白的二值化,直接將圖像分為兩個極端。
適用場景

  • 文檔掃描(將文字與背景分離)
  • 目標檢測中提取輪廓(如二維碼識別)
  • 去除灰度圖中灰度值較低的背景噪聲

2.?cv2.THRESH_BINARY_INV(反二進制閾值)

核心邏輯:與THRESH_BINARY完全相反,大于閾值的像素設為 0(黑色),小于等于閾值的設為最大值(255,白色)。
數學表達式
dst(x,y) = 0, if src(x,y) > thresh
dst(x,y) = maxval, otherwise

直觀理解:黑白反轉的二值化,原來看起來亮的區域變暗,暗的區域變亮。
適用場景

  • 文字識別中需要 “黑底白字” 轉 “白底黑字”
  • 提取圖像中較暗的目標(如夜景中的燈光)
  • 修正光照不均導致的明暗顛倒問題

3.?cv2.THRESH_TRUNC(截斷閾值)

核心邏輯:像素值大于閾值時,強制設為閾值本身;小于等于閾值時,保持原像素值不變。
數學表達式
dst(x,y) = thresh, if src(x,y) > thresh
dst(x,y) = src(x,y), otherwise

直觀理解:“截斷” 過亮的像素,將超過閾值的亮度 “壓” 到閾值水平,保留暗部細節。
適用場景

  • 處理過曝圖像(如強光導致的白色區域過大)
  • 抑制高光區域(如人像攝影中過亮的皮膚)
  • 保留圖像暗部紋理,同時避免亮部過曝丟失信息

4.?cv2.THRESH_TOZERO(歸零閾值)

核心邏輯:像素值大于閾值時,保持原像素值;小于等于閾值時,設為 0(黑色)。
數學表達式
dst(x,y) = src(x,y), if src(x,y) > thresh
dst(x,y) = 0, otherwise

直觀理解:只保留亮度高于閾值的區域,低于閾值的區域直接 “歸零”(變黑)。
適用場景

  • 提取圖像中較亮的目標(如 X 光片中的高亮病變區域)
  • 去除暗部噪聲(如低光照下的圖像噪點)
  • 保留目標區域(通常較亮)并簡化背景(變為黑色)

5.?cv2.THRESH_TOZERO_INV(反歸零閾值)

核心邏輯:與THRESH_TOZERO相反,像素值大于閾值時,設為 0(黑色);小于等于閾值時,保持原像素值。
數學表達式
dst(x,y) = 0, if src(x,y) > thresh
dst(x,y) = src(x,y), otherwise

直觀理解:只保留亮度低于閾值的區域,高于閾值的區域 “歸零”(變黑)。
適用場景

  • 提取圖像中較暗的目標(如夜景中的陰影區域)
  • 去除高光干擾(如反光、光斑)
  • 保留暗部細節,同時消除過亮區域的影響

總結:5 種閾值類型的核心差異

閾值類型大于閾值的像素處理小于等于閾值的像素處理核心作用
THRESH_BINARY設為 maxval(如 255)設為 0亮區域保留,暗區域變黑
THRESH_BINARY_INV設為 0設為 maxval(如 255)暗區域保留,亮區域變黑
THRESH_TRUNC設為閾值本身保持原值抑制過亮區域,保留暗部
THRESH_TOZERO保持原值設為 0保留亮區域,暗區域變黑
THRESH_TOZERO_INV設為 0保持原值保留暗區域,亮區域變黑

示例代碼:

# 導入OpenCV庫,OpenCV是一個用于計算機視覺的開源庫
import cv2# 讀取圖像文件,并轉換為灰度圖
# 參數說明:
# 'mm.jpg':圖像文件路徑(需與腳本同目錄或使用絕對路徑)
# 0:讀取模式,0表示以灰度圖模式讀取(單通道)
image = cv2.imread('mm.jpg', 0)# 調整圖像尺寸為400x400像素
# 注意:resize函數的參數是(width, height),與圖像通常的(height, width)格式相反
image = cv2.resize(image, (400, 400))# 1. 二進制閾值處理
# 參數說明:
# image:輸入的灰度圖像
# 130:設定的閾值
# 255:最大值(用于THRESH_BINARY和THRESH_BINARY_INV類型)
# cv2.THRESH_BINARY:閾值類型,大于閾值的像素設為255,否則設為0
# 返回值:ret為使用的閾值,binary為處理后的圖像
ret, binary = cv2.threshold(image, 130, 255, cv2.THRESH_BINARY)# 2. 反二進制閾值處理
# cv2.THRESH_BINARY_INV:與BINARY相反,大于閾值的像素設為0,否則設為255
ret1, binaryInv = cv2.threshold(image, 130, 255, cv2.THRESH_BINARY_INV)# 3. 截斷閾值處理
# cv2.THRESH_TRUNC:大于閾值的像素設為閾值(130),否則保持原像素值
ret2, trunc = cv2.threshold(image, 130, 255, cv2.THRESH_TRUNC)# 4. 歸零閾值處理
# cv2.THRESH_TOZERO:大于閾值的像素保持原值,否則設為0
ret3, tozero = cv2.threshold(image, 130, 255, cv2.THRESH_TOZERO)# 5. 反歸零閾值處理
# cv2.THRESH_TOZERO_INV:與TOZERO相反,大于閾值的像素設為0,否則保持原值
ret4, tozeroInv = cv2.threshold(image, 130, 255, cv2.THRESH_TOZERO_INV)# 顯示原始灰度圖像
# 參數:窗口名稱('gray')和要顯示的圖像
cv2.imshow('gray', image)# 顯示二進制閾值處理后的圖像
# 效果:像素值>130的區域變為白色(255),<=130的區域變為黑色(0)
cv2.imshow('binary', binary)# 顯示反二進制閾值處理后的圖像
# 效果:像素值>130的區域變為黑色(0),<=130的區域變為白色(255)
cv2.imshow('binaryInv', binaryInv)# 顯示截斷閾值處理后的圖像
# 效果:像素值>130的區域變為130(灰色),<=130的區域保持原圖亮度
cv2.imshow('trunc', trunc)# 顯示歸零閾值處理后的圖像
# 效果:像素值>130的區域保持原圖亮度,<=130的區域變為黑色(0)
cv2.imshow('tozero', tozero)# 顯示反歸零閾值處理后的圖像
# 效果:像素值>130的區域變為黑色(0),<=130的區域保持原圖亮度
cv2.imshow('tozeroInv', tozeroInv)# 等待用戶按鍵操作
# 參數0表示無限等待,直到用戶按下任意鍵
# 所有窗口會在用戶按鍵后關閉
cv2.waitKey(0)

四、圖像的平滑處理

圖像平滑(smoothing)也稱為“模糊處理”(bluring)
通過消除圖像中的噪聲或細節來使圖像看起來更為模糊,從而實現平滑效果
可以用來壓制、弱化或消除圖像中的細節、突變和噪聲。
下面是常用的一些濾波器
均值濾波(鄰域平均濾波)-> blur函數
方框濾波-> boxFilter函數
高斯濾波->GaussianBlur函數
中值濾波->medianBlur函數

dst=cv2.blur(src,ksize,anchor,borderType)

dst是返回值
src是需要處理的圖像
ksize是濾波核(卷積核)的大小
anchor是錨點,默認值是(-1,-1)一般無需更改
borderType是邊界樣式,一般無需更改
一般情況下,使用dst=cv2.blur(src,ksize)即可

準備代碼:

準備一個含有噪聲點的圖像來方便后面的演示

# 導入OpenCV庫,用于圖像處理
import cv2
# 導入numpy庫,用于數值計算和隨機數生成
import numpy as np# 定義添加椒鹽噪聲的函數
# 參數:
#   image: 原始圖像
#   n: 噪聲點的數量,默認值為10000
def add_peppersalt_noize(image, n=10000):# 復制原始圖像,避免直接修改原圖result = image.copy()# 獲取圖像的高度和寬度(shape[:2]取前兩個值,即高度和寬度)h, w = image.shape[:2]# 循環n次,生成n個噪聲點for i in range(n):# 隨機生成x坐標(行),范圍在1到h之間x = np.random.randint(1, h)# 隨機生成y坐標(列),范圍在1到w之間y = np.random.randint(1, w)# 隨機生成0或1,決定是添加椒噪聲(0)還是鹽噪聲(255)if np.random.randint(0, 2) == 0:# 添加椒噪聲(黑色點)result[x, y] = 0else:# 添加鹽噪聲(白色點)result[x, y] = 255# 返回添加噪聲后的圖像return result# 讀取圖像文件'mm.jpg',默認讀取為BGR格式
image = cv2.imread('mm.jpg')
# 調整圖像大小為400x400像素
image = cv2.resize(image, (400, 400))# 創建一個窗口顯示原始圖像,窗口名為'mm'
cv2.imshow('mm', image)# 調用函數為圖像添加椒鹽噪聲
noise = add_peppersalt_noize(image)# 創建一個窗口顯示帶噪聲的圖像,窗口名為'noise'
cv2.imshow('noise', noise)# 等待用戶按下任意鍵,參數0表示無限等待
cv2.waitKey(0)
# 關閉所有OpenCV創建的窗口(雖然代碼中沒寫,但通常建議加上)
# cv2.destroyAllWindows()

1、均值濾波

cv2.blur()?是 OpenCV 中用于實現均值模糊(也稱為歸一化盒式濾波)的 API,其核心原理是用圖像中某一像素周圍鄰域內所有像素的平均值來替代該像素的值,從而達到平滑圖像、降低噪聲的效果。

語法格式:

dst = cv2.blur(src, ksize[, anchor[, borderType]])

參數說明:

  1. src(必選):
    輸入圖像(源圖像),可以是單通道灰度圖或多通道彩色圖(如 BGR 格式)。

  2. ksize(必選):
    模糊核(卷積核)的大小,格式為?(width, height),例如?(3,3)?表示使用 3×3 的正方形核。
    核的尺寸越大,模糊效果越強,但圖像細節損失也越多。

  3. anchor(可選):
    核的錨點(即計算均值時的參考點),默認值為?(-1,-1),表示錨點位于核的中心。

  4. borderType(可選):
    邊界填充方式,用于處理圖像邊緣像素(因為邊緣像素沒有完整的鄰域)。
    默認值為?cv2.BORDER_DEFAULT,常用選項還包括?cv2.BORDER_CONSTANT(常量填充)、cv2.BORDER_REPLICATE(復制邊緣像素填充)等。

示例代碼(接上面的準備代碼):

blur_1 = cv2.blur(noise,(3,3))#卷積核為(3,3)
cv2.imshow('bler_1',blur_1)
blur_2 = cv2.blur(noise,(9,9))#卷積核為(3,3)
cv2.imshow('bler_2',blur_2)
blur_3 = cv2.blur(noise,(15,15))#卷積核為(3,3)
cv2.imshow('bler_3',blur_3)
blur_4 = cv2.blur(noise,(21,21))#卷積核為(3,3)
cv2.imshow('bler_4',blur_4)
cv2.waitKey(0)

2、方框濾波

cv2.boxFilter()?是 OpenCV 中一個靈活的線性濾波函數,用于實現盒式濾波(Box Filter)。它可以看作是?cv2.blur()?的通用版本,既可以實現均值模糊(歸一化盒式濾波),也可以實現非歸一化的盒式濾波(僅對鄰域像素求和)。

語法格式:

dst = cv2.boxFilter(src, ddepth, ksize[, anchor[, normalize[, borderType]]])

參數說明:

  1. src(必選):
    輸入圖像(源圖像),可以是單通道灰度圖或多通道彩色圖。

  2. ddepth(必選):
    輸出圖像的深度(數據類型),常用值:

    • cv2.CV_8U:8 位無符號整數(0-255)
    • cv2.CV_32F:32 位浮點數
    • -1:表示輸出圖像深度與輸入圖像相同(推薦使用)
  3. ksize(必選):
    濾波核(卷積核)的大小,格式為?(width, height),例如?(3,3)?表示 3×3 的核。

  4. anchor(可選):
    核的錨點(計算濾波時的參考點),默認值?(-1,-1)?表示錨點在核中心。

  5. normalize(可選):
    布爾值,是否對濾波結果進行歸一化:

    • True(默認):歸一化盒式濾波,即鄰域像素求和后除以核的面積(等價于?cv2.blur())。
    • False:非歸一化盒式濾波,僅計算鄰域像素的總和(可能導致像素值溢出,需注意數據類型)。
  6. borderType(可選):
    邊界填充方式,用于處理圖像邊緣像素,默認值為?cv2.BORDER_DEFAULT,其他常用選項同?cv2.blur()

功能說明:

  • 當?normalize=True?時,cv2.boxFilter()?與?cv2.blur()?效果完全一致,都是計算鄰域像素的平均值:
    dst(x,y) = (sum of src(x',y') in ksize) / (width×height)

  • 當?normalize=False?時,僅計算鄰域像素的總和:
    dst(x,y) = sum of src(x',y') in ksize
    這種模式下,結果可能超過像素值范圍(如 0-255),因此通常需要配合?ddepth=cv2.CV_32F?使用,避免溢出。

3、高斯濾波

cv2.GaussianBlur()?是 OpenCV 中用于實現高斯模糊的 API,其核心原理是使用高斯核(符合高斯分布的卷積核)對圖像進行卷積操作,相比均值模糊能更好地保留圖像細節,同時有效去除高斯噪聲。

語法格式:

dst = cv2.GaussianBlur(src, ksize[, sigmaX[, sigmaY[, borderType]]])

參數說明:

  1. src(必選):
    輸入圖像(源圖像),可以是單通道灰度圖或多通道彩色圖(如 BGR 格式)。

  2. ksize(必選):
    高斯核的大小,格式為?(width, height),需滿足:

    • 寬度和高度必須是正奇數(如?(3,3)(5,5)(7,7)?等)。

    • 若寬度≠高度,核可以是矩形(如?(3,5)),但通常使用正方形核。
      核的尺寸越大,模糊效果越強。
  3. sigmaX(可選):
    高斯核在 X 方向(水平方向)的標準差,控制高斯分布的 "寬窄":

    • sigmaX > 0:使用指定值作為 X 方向標準差。
    • sigmaX = 0(默認):根據核尺寸自動計算(sigma = 0.3×((ksize-1)×0.5 - 1) + 0.8)。
    • sigmaX < 0:不合法,會報錯。
  4. sigmaY(可選):
    高斯核在 Y 方向(垂直方向)的標準差:

    • 若未指定或為?0:默認與?sigmaX?相等(各向同性高斯模糊)。
    • 若?sigmaY > 0:可實現 X、Y 方向不同強度的模糊(各向異性)。
  5. borderType(可選):
    邊界填充方式,處理圖像邊緣像素,默認值為?cv2.BORDER_DEFAULT,其他選項同?cv2.blur()

示例代碼(接上面的準備代碼):

GaussianB = cv2.GaussianBlur(noise, ksize=(3,3), sigmaX=1) # 標準正態分布、3、3、高斯濾波
cv2.imshow(winname='GaussianBlur', mat=GaussianB)
cv2.waitKey(0)

4、中值濾波

cv2.medianBlur()?是 OpenCV 中用于實現中值濾波的 API,其核心原理是用圖像中某一像素周圍鄰域內所有像素的中值來替代該像素的值。這種濾波方式對椒鹽噪聲(圖像中隨機出現的黑白點)有非常好的去除效果,同時能較好地保留圖像邊緣細節。

語法格式:

dst = cv2.medianBlur(src, ksize[, dst])

參數說明:

  1. src(必選):
    輸入圖像(源圖像),可以是單通道灰度圖或多通道彩色圖(如 BGR 格式)。
    注意:該函數僅支持 8 位單通道圖像、16 位單通道圖像(CV_16U)或 32 位浮點單通道圖像(CV_32F)。對于多通道圖像,會對每個通道分別進行中值濾波。

  2. ksize(必選):
    濾波核的大小,必須是大于 1 的正奇數(如?357?等),表示使用?ksize×ksize?的正方形核。
    核的尺寸越大,去噪效果越強,但圖像細節損失也可能越多。

  3. dst(可選):
    輸出圖像,與輸入圖像具有相同的尺寸和類型,通常不需要手動指定,函數會自動創建并返回。

功能原理:

中值濾波的計算過程:

  1. 以目標像素為中心,取?ksize×ksize?大小的鄰域窗口;
  2. 將窗口內所有像素值按大小排序;
  3. 取排序后的中間值作為目標像素的新值。

例如,使用 3×3 核時,會對 9 個像素值排序,取第 5 個值(中間值)作為結果。

示例代碼(接上面的準備代碼):

medianB = cv2.medianBlur(noise, ksize=3) # 4、中值濾波
cv2.imshow(winname='medianBlur', mat=medianB)
cv2.waitKey(0)
cv2.destroyAllWindows()

實戰項目:

現在有一個視頻,如上述的做法將其添加噪聲點并優化(視頻已經上傳)

示例代碼:

# 導入OpenCV庫,用于圖像處理和視頻操作
import cv2
# 導入NumPy庫,用于數值計算和隨機數生成
import numpy as np## 噪聲點選取:添加椒鹽噪聲
def add_peppersalt_noize(image, n=10000):"""為圖像添加椒鹽噪聲參數:image: 原始圖像n: 噪聲點數量,默認10000個返回:添加噪聲后的圖像"""# 復制原始圖像,避免直接修改原圖result = image.copy()# 獲取圖像的高度和寬度(忽略通道數)h, w = image.shape[:2]# 循環生成n個噪聲點for i in range(n):# 隨機生成一個高度方向的坐標(1到h之間)x = np.random.randint(1, h)# 隨機生成一個寬度方向的坐標(1到w之間)y = np.random.randint(1, w)# 50%概率生成胡椒噪聲(黑色點),50%概率生成鹽噪聲(白色點)if np.random.randint(0, 2) == 0:# 胡椒噪聲:將像素值設為0(黑色)result[x, y] = 0else:# 鹽噪聲:將像素值設為255(白色)result[x, y] = 255# 返回添加噪聲后的圖像return result## 視頻處理主程序# 創建VideoCapture對象,打開視頻文件'test.avi'
cap = cv2.VideoCapture('test.avi')
# 初始化幀計數器
frame_number = 0# 循環讀取視頻的每一幀
while cap.isOpened():# 讀取一幀圖像# ret: 布爾值,表示是否成功讀取幀# frame: 讀取到的當前幀圖像ret, frame = cap.read()# 如果沒有讀取到幀(視頻結束),退出循環if not ret:break# 調整幀的大小,縮小為原來的70%(fx和fy分別為x和y方向的縮放因子)# dsize=None表示根據縮放因子自動計算目標大小frame = cv2.resize(frame, dsize=None, fx=0.7, fy=0.7)# 為當前幀添加椒鹽噪聲noise = add_peppersalt_noize(frame)# 使用中值濾波去除噪聲,卷積核大小為3x3# 中值濾波對椒鹽噪聲有很好的去除效果medianB = cv2.medianBlur(noise, ksize=3)# 顯示原始圖像窗口,窗口名為'begin'cv2.imshow('begin', frame)# 顯示添加噪聲后的圖像窗口,窗口名為'noise'cv2.imshow('noise', noise)# 顯示中值濾波處理后的圖像窗口,窗口名為'mesianB'cv2.imshow('mesianB', medianB)# 等待25毫秒,接收鍵盤輸入# 25ms的延遲大約對應40fps的播放速度key = cv2.waitKey(25)# 如果按下ESC鍵(ASCII碼為27),退出循環if key == 27:print("用戶手動退出")break# 幀計數器加1frame_number += 1# 釋放視頻捕獲對象,關閉視頻文件
cap.release()
# 關閉所有OpenCV創建的窗口
cv2.destroyAllWindows()# 打印處理完成信息
print("視頻處理完成")

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/93342.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/93342.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/93342.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

FPGA實現Aurora 64B66B視頻點對點傳輸,基于GTX高速收發器,提供4套工程源碼和技術支持

目錄 1、前言Aurora 64B66B是啥&#xff1f;官方有Example&#xff0c;為何要用你這個&#xff1f;工程概述免責聲明 2、相關方案推薦我已有的所有工程源碼總目錄----方便你快速找到自己喜歡的項目我這里已有的 GT 高速接口解決方案本方案在Aurora 8B10B上的應用 3、工程詳細設…

【軟件安裝|1】CentOS7最新可用國內 yum 鏡像源配置和Linux版MySQL8.0安裝及其相關知識

文章目錄一.更換yum鏡像源二.安裝并配置MySQL8.0安裝配置相關知識什么是yum&#xff1f;什么是鏡像源&#xff1f;相關知識請看最后&#xff0c;首先來更換yum鏡像源 更換前需要準備好VmwareWorkstation和Finalshell&#xff0c;開啟虛擬機&#xff0c;切換到root用戶 Vmware和…

【深度學習】深度學習的四個核心步驟:從房價預測看機器學習本質

文章目錄基礎概念與原理第一步&#xff1a;準備數據 - 構建學習的基礎數據生成與特征工程&#xff08;選擇對預測有用的特征&#xff09;數據集劃分的重要性第二步&#xff1a;設計模型 - 建立數學表達線性回歸模型的數學表達損失函數的設計哲學第三步&#xff1a;訓練優化 - 自…

Java使用Apache POI讀取Excel文件

一、下載jar包 Apache POI有提供下載地址&#xff1a;Apache Archive Distribution Directory&#xff0c;直接打開鏈接并選擇所需的版本下載即可(雙擊last modified可按最新更新時間排序)&#xff0c;本文章以poi-bin-4.1.1-20191023.zip為例&#xff0c;進入官網下載鏈接后&…

VLMs開發——基于Qwen2.5-VL 實現視覺語言模型在目標檢測中的層級結構與實現方法

概述 目標檢測作為計算機視覺領域的核心任務&#xff0c;傳統方法依賴于 YOLO 等視覺模型對預定義類別進行位置預測。然而&#xff0c;此類方法受限于預訓練類別體系&#xff0c;難以實現靈活的視覺交互。視覺語言模型&#xff08;Vision-Language Models, VLMs&#xff09;的…

Spring Boot + Redis + 布隆過濾器防止緩存穿透

? 項目概述 在高并發系統中&#xff0c;緩存穿透 是一個經典問題&#xff1a;當惡意請求或業務邏輯查詢一個數據庫中不存在的 Key&#xff0c;由于緩存中也沒有&#xff0c;請求會直接打到數據庫&#xff0c;導致數據庫壓力激增&#xff0c;甚至宕機。 本項目使用 Spring Bo…

電子電路學習日記

這里的 K 表示 千歐&#xff08;kilo-ohm&#xff09;&#xff0c;而 F 在很多國產 EDA 軟件&#xff08;比如立創EDA、Altium 的一些中文封裝庫&#xff09;里用來標注精度&#xff08;公差&#xff09;&#xff0c; F 代表 1% 精度&#xff08;英文 Fine tolerance&#xff0…

oracle 怎么實現讀一致性

? Oracle 數據塊讀一致性判斷流程&#xff08;正確版&#xff09; 假設&#xff1a;Query SCN 查詢開始的 SCN&#xff08;Query SCN&#xff09; lastSubbmit SCN 行中最新的提交scn Row SCN 行最后修改的 SCN&#xff08;存儲在行頭&#xff0c;通過 ITL 推導&#xff09…

ISTA為什么要加上軟閾值激活函數?r若沒有L1 正則化也要加其他激活函數嗎?

一、加上軟閾值函數&#xff08;Soft-thresholding&#xff09;是因為 LISTA&#xff08;以及它的前身 ISTA&#xff09;本質上是在求解一個 帶 L1 正則化的稀疏優化問題&#xff1a; min?x12∥y?Ax∥22λ∥x∥1 \min_x \frac{1}{2} \|y - Ax\|_2^2 \lambda \|x\|_1 xmin?2…

線程P4 | 線程安全問題及解決方法

何為線程安全&#xff1f;要談及何為線程安全&#xff0c;總得說來&#xff0c;我們可以用一句話來概況&#xff1a;如果在多線程環境下代碼運行結果和我們預期是相符的&#xff0c;即和單線程環境下的運行結果相同&#xff0c;那么我們就稱這個程序是線程安全的&#xff0c;反…

水印消失術!JavaAI深度學習去水印技術深度剖析

一、飛算JavaAI平臺概述1.1 飛算JavaAI定位與技術特色 飛算JavaAI是國內領先的智能化Java開發平臺&#xff0c;通過AI技術賦能軟件開發全流程&#xff0c;特別針對小程序、Web應用等輕量級開發場景提供*零基礎編程→高質量交**的一站式解決方案。其核心優勢體現在&#xff1a; …

醋酸釓:醫學影像與科技創新中的重要角色

醋酸釓是一種由釓元素和醋酸根離子組成的化合物。釓是稀土金屬之一&#xff0c;常常用于醫學影像、核磁共振成像&#xff08;MRI&#xff09;以及某些工業應用。醋酸釓作為釓的鹽之一&#xff0c;具有許多獨特的性質&#xff0c;尤其在醫學和科學研究領域表現突出。一、醋酸釓的…

插入排序專欄

插入排序&#xff08;Insertion Sort&#xff09;是一種簡單直觀的排序算法&#xff0c;其思想源于我們日常生活中整理撲克牌的方式。本文將詳細解析插入排序的工作原理&#xff0c;通過 Java 實現代碼進行分析&#xff0c;深入探討其時間復雜度的計算過程&#xff0c;并闡述其…

高效Unicode字符表示:一種創新的詞表構建策略分析

在自然語言處理中&#xff0c;處理多語言和特殊字符的表示始終是一項挑戰。本文將分析一種創新的詞表構建策略&#xff0c;該策略通過數學優化和雙token機制&#xff0c;在保持詞表緊湊的同時實現了對Unicode字符的全面覆蓋。 詞表構建的核心邏輯 該策略包含四個關鍵步驟&#…

python與物聯網基礎知識

軟件準備&#xff1a;軟件&#xff1a;thonny-4.0.1-windows-portable(win10,11系統64位)驅動&#xff1a;CP210x_Windows_Drivers固件&#xff1a;esp8266-1m-20220618-v1.19.1.bin物料準備&#xff1a;面包板、開發板、電源線一、安裝與調試&#xff1a;1.在軟件文件中找到th…

SVN提交服務器拒絕訪問的問題

SVN提交服務器拒絕訪問的問題 介紹 分析 1.服務器的SVN沒有開啟 2.服務器的網絡端口除了問題沒有開放端口 3.客戶端的SVN配置除了問題刷新一下數據 4.客戶端的SVN重裝 找原因 1.初步以為是**防火墻**的問題 2.網絡運營商的問題 總結 介紹 SVN相信大家都用過,今天反饋一個比較…

【Linux】庫制作與原理

前言 本篇博客我們來認識下庫方面的知識 &#x1f493; 個人主頁&#xff1a;zkf ? 文章專欄&#xff1a;Linux 若有問題 評論區見&#x1f4dd; &#x1f389;歡迎大家點贊&#x1f44d;收藏?文章 目錄 1.什么是庫 2.靜態庫 2.1靜態庫的生成 2.2靜態庫的使用 3.動態庫 …

Android ADB 常用指令全解析

ADB&#xff08;Android Debug Bridge&#xff09;是 Android 開發和測試不可或缺的調試工具&#xff0c;它建立了電腦與 Android 設備之間的通信橋梁&#xff0c;通過命令行指令可實現對設備的全方位控制。掌握 ADB 指令能大幅提升開發效率&#xff0c;解決各類調試難題。本文…

使用 Rust 創建 32 位 DLL 的完整指南

使用 Rust 創建 32 位 DLL 的完整指南 在 Rust 中創建 32 位 DLL 需要特定的工具鏈配置和編譯選項。以下是詳細步驟和最佳實踐&#xff1a; 環境準備 1. 安裝 Rust 工具鏈 # 安裝 Rust curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh# 安裝 32 位目標 rustu…

算法基礎 第3章 數據結構

1.單調棧 1.什么是單調棧 單調棧&#xff0c;即具有單調性的棧。 實現 #include <iostream> #include <stack> using namespace std; const int N 3e6 10; int a[N], n; void test1() {stack<int> st; // 維護?個單調遞增的棧for(int i 1; i < n; i…