欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報激活碼778899分享:OpenCV計算機視覺庫

柚子快報激活碼778899分享:OpenCV計算機視覺庫

http://yzkb.51969.com/

計算機視覺和圖像處理

Tensorflow入門深度神經(jīng)網(wǎng)絡圖像分類目標檢測圖像分割OpenCVPytorchNLP自然語言處理

OpenCV

一、OpenCV簡介1.1 簡介1.2 OpenCV部署1.3 OpenCV模塊

二、OpenCV基本操作2.1 圖像的基本操作2.1.1 圖像的IO操作2.1.2 繪制幾何圖像2.1.3 獲取并修改圖像的像素點2.1.4 獲取圖像的屬性2.1.5 圖像通道的拆分和合并2.1.6 色彩空間的改變

2.2 算數(shù)操作2.2.1 圖像的加法2.2.2 圖像的混合

三、OpenCV圖像處理3.1 圖像的幾何變換3.2 圖像的形態(tài)學操作3.3 圖像的平滑3.4 直方圖3.1.4 灰度直方圖3.1.5 直方圖均衡化

3.5 邊緣檢測3.5.1 Sobel檢測算子3.5.2 Laplacian算子3.5.3 Canny邊緣檢測

3.6 模板匹配和霍夫變換的應用3.6.1 模板匹配3.6.2 霍夫變換

3.7 圖像變化3.7.1 傅里葉變換3.7.2 高通和低通濾波3.7.3 帶通和帶阻濾波

3.8 輪廓檢測與輪廓特征3.8.1 輪廓檢測3.8.2 輪廓特征

3.9 圖像分割3.9.1 全閾值分割3.9.2 自適應閾值分割3.9.3 Ostu閾值(大律法)3.9.4 分水嶺算法3.9.5 GrabCut算法

四、圖像的特征提取與描述4.1 Harris角點檢測4.2 Shi-Tomasi角點檢測4.3 sift算法4.4 fast檢測算法4.5 orb角點檢測

五、視頻操作5.1 視頻讀寫5.2 視頻保存5.3 視頻追蹤5.3.1 meanshift算法5.3.2 camshift算法

六、人臉、眼睛檢測案例6.1 人臉以及眼睛檢測(圖片)6.2 人臉以及眼睛檢測(視頻)

一、OpenCV簡介

1.1 簡介

OpenCV是?個計算機視覺處理開源軟件庫,?持與計算機視覺和機器學習相關的眾多算法。

1.2 OpenCV部署

創(chuàng)建虛擬環(huán)境 在Anaconda終端中創(chuàng)建虛擬環(huán)境OpenCV_env

conda create --name OpenCV_env

激活虛擬環(huán)境

conda activate OpenCV_env

安裝OpenCV

安裝OpenCV之前需要先安裝numpy, matplotlib

pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple

如果我們要利用SIFT和SURF算法進行特征提取時,還需安裝:

pip install opencv-contrib-python -i https://pypi.tuna.tsinghua.edu.cn/simple

查看是否安裝成功

import cv2

cv2.__version__

1.3 OpenCV模塊

core模塊實現(xiàn)了最核心的數(shù)據(jù)結構及其基本運算,如繪圖函數(shù)、數(shù)組操作相關函數(shù)等。highgui模塊實現(xiàn)了視頻與圖像的讀取、顯示、存儲等接口。imgproc模塊實現(xiàn)了圖像處理的基礎方法,包括圖像濾波、圖像的幾何變換、平滑、閾值分割、形態(tài)學處理、邊緣檢測、目標檢測、運動分析和對象跟蹤等。features2d模塊用于提取圖像特征以及特征匹配,nonfree模塊實現(xiàn)了一些專利算法,如sift特征。objdetect模塊實現(xiàn)了一些目標檢測的功能,經(jīng)典的基于Haar、LBP特征的人臉檢測,基于HOG的行人、汽車等目標檢測,分類器使用CascadeClassification(級聯(lián)分類)和Latent SVM等。

二、OpenCV基本操作

2.1 圖像的基本操作

2.1.1 圖像的IO操作

# 讀取圖像

import numpy as np

import cv2 as cv

import matplotlib.pyplot as plt

#以灰度圖的方式讀取圖像

img = cv.imread("dog.jpg",0)

# 顯示圖像

# Jupyter Notebook 是一個基于 Web 的交互式計算環(huán)境,不支持傳統(tǒng)的 GUI 窗口顯示

# cv.imshow('image',img)

# cv.waitKey(0)

plt.imshow(img,cmap='gray')

# 以彩色圖的方式讀取圖像

img1 = cv.imread("dog.jpg",1)

# img1[:,:,::-1]將BGR圖像轉換為RGB圖像

plt.imshow(img1[:,:,::-1])

使用cv.imread()讀取的圖像是BGR,而matplot使用是的RGB圖像

img.shape

# 圖像保存

cv.imwrite('dog1.jpg',img)

2.1.2 繪制幾何圖像

# 創(chuàng)建圖像

img = np.zeros((512,512,3),np.uint8)

# 直線的起點、終點、顏色、寬度

cv.line(img,(0,0),(512,512),(255,0,0),5)

# 圓形的圓心、半徑、顏色、填充、寬度

cv.circle(img,(250,250),130,(0,255,0),-1,5)

# 矩形的左上角、右下角、顏色、寬度

cv.rectangle(img,(50,50),(450,450),(0,0,255),5)

# 圖像中添加文字 文本、位置、字體、字體大小、顏色、寬度

cv.putText(img,"OpenCV",(130,250),cv.FONT_HERSHEY_COMPLEX,2,(255,0,255),2)

plt.imshow(img[:,:,::-1])

plt.show()

2.1.3 獲取并修改圖像的像素點

img2 = np.zeros((250,250,3),np.uint8)

plt.imshow(img2[:,:,::-1])

# 獲取位置(50,200)的像素點

img2[50,200]

#獲取位置(50,100)藍色通道的強度值,0表示藍色,1表示綠色,2表示紅色

img2[50,100,0]

# 修改位置(50,100)的像素值

img2[50,100] = [255,0,0]

plt.imshow(img2[:,:,::-1])

2.1.4 獲取圖像的屬性

img2.shape

img2.size

img2.dtype

2.1.5 圖像通道的拆分和合并

# 通道拆分

b,g,r = cv.split(img1)

plt.imshow(b,cmap='gray')

# 通道合并

img3 = cv.merge((b,g,r))

plt.imshow(img3[:,:,::-1])

2.1.6 色彩空間的改變

# 將BGR通道圖像轉變?yōu)镠SV通道圖像

img3 = cv.cvtColor(img1,cv.COLOR_BGR2HSV)

plt.imshow(img3[:,:,::-1])

# 將BGR通道圖像變?yōu)镚RAY通道圖像

img4 = cv.cvtColor(img1,cv.COLOR_BGR2GRAY)

plt.imshow(img4,cmap='gray')

2.2 算數(shù)操作

2.2.1 圖像的加法

# 讀取圖像

img_sun = cv.imread('sun.jpg')

img_tree = cv.imread('tree.jpg')

plt.imshow(img_tree[:,:,::-1])

plt.imshow(img_sun[:,:,::-1])

# 查看圖像形狀

img_sun.shape,img_tree.shape

形狀相同才能進行相加

# 縮小圖形形狀

img_sun = cv.resize(img_sun,(350,251))

img_sun.shape

# 加法操作

img_cvadd = cv.add(img_sun,img_tree)

img_add = img_sun+img_tree

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(img_cvadd[:,:,::-1])

axes[0].set_title("cv中的加法")

axes[1].imshow(img_add[:,:,::-1])

axes[1].set_title("直接相加")

plt.show()

2.2.2 圖像的混合

# 讀取圖像

img_sun = cv.imread('sun.jpg')

img_tree = cv.imread('tree.jpg')

# 縮小圖形形狀

img_sun = cv.resize(img_sun,(350,251))

# 圖像混合,gamma參數(shù)會影響最終圖像的亮度

img5 = cv.addWeighted(img_sun,0.3,img_tree,0.7,0)

# 圖像的顯示

plt.imshow(img5[:,:,::-1])

plt.show()

三、OpenCV圖像處理

3.1 圖像的幾何變換

import cv2 as cv

import matplotlib.pyplot as plt

圖像縮放

# 讀取圖片

img = cv.imread('dog.jpg')

# 圖像縮放

# 絕對尺寸

rows,cols = img.shape[:2]

res = cv.resize(img,(2*cols,2*rows))

# 相對尺寸

res1 = cv.resize(img,None,fx=0.5,fy=0.5)

# 圖像顯示

fig,axes = plt.subplots(1,3,figsize=(10,8))

axes[0].imshow(img[:,:,::-1])

axes[0].set_title("原始圖像")

axes[1].imshow(res[:,:,::-1])

axes[1].set_title("絕對尺寸")

axes[2].imshow(res1[:,:,::-1])

axes[2].set_title("相對尺寸")

plt.show()

圖像平移

import numpy as np

img = cv.imread('dog.jpg')

# 像素點平移(50,100)

rows,cols = img.shape[:2]

# 平移矩陣

m = np.float32([[1,0,50],[0,1,100]])

res = cv.warpAffine(img,m,(cols,rows))

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(img[:,:,::-1])

axes[0].set_title("原始圖像")

axes[1].imshow(res[:,:,::-1])

axes[1].set_title("平移后圖像")

plt.show()

圖像旋轉

img = cv.imread("dog.jpg")

rows,cols = img.shape[:2]

# 旋轉矩陣

m = cv.getRotationMatrix2D((cols//2,rows//2),90,0.5)

res = cv.warpAffine(img,m,(cols,rows))

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(img[:,:,::-1])

axes[0].set_title("原始圖像")

axes[1].imshow(res[:,:,::-1])

axes[1].set_title("旋轉后圖像")

plt.show()

仿射變換

rows,cols = img.shape[:2]

# 原點集

pts1 = np.float32([[50,50],[200,50],[50,200]])

# 目標點集

pts2 = np.float32([[100,100],[200,50],[100,250]])

# 仿射變化矩陣

m = cv.getAffineTransform(pts1,pts2)

res = cv.warpAffine(img,m,(cols,rows))

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(img[:,:,::-1])

axes[0].set_title("原始圖像")

axes[1].imshow(res[:,:,::-1])

axes[1].set_title("仿射后圖像")

plt.show()

投射變換

img = cv.imread("dog.jpg")

rows,cols = img.shape[:2]

# 投射變換矩陣

pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])

pts2 = np.float32([[100,145],[300,100],[80,290],[310,300]])

m = cv.getPerspectiveTransform(pts1,pts2)

# 進行變換

res = cv.warpPerspective(img,m,(cols,rows))

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(img[:,:,::-1])

axes[0].set_title("原圖像")

axes[1].imshow(res[:,:,::-1])

axes[1].set_title("仿射后圖像")

plt.show()

圖像金字塔

img = cv.imread("dog.jpg")

# 上采樣

img_up = cv.pyrUp(img)

# 下采樣

img_down = cv.pyrDown(img)

fig,axes = plt.subplots(1,3,figsize=(10,8))

axes[0].imshow(img[:,:,::-1])

axes[0].set_title("原圖像")

axes[1].imshow(img_up[:,:,::-1])

axes[1].set_title("上采樣圖像")

axes[2].imshow(img_down[:,:,::-1])

axes[2].set_title("下采樣圖像")

plt.show()

3.2 圖像的形態(tài)學操作

膨脹和腐蝕

img = cv.imread("img_five.jpg")

# 創(chuàng)建核結構

kernel = np.ones((5,5),np.uint8)

# 腐蝕

erode = cv.erode(img,kernel)

# 膨脹

dilate = cv.dilate(img,kernel)

fig,axes = plt.subplots(1,3,figsize=(10,8))

axes[0].imshow(img[:,:,::-1])

axes[0].set_title("原圖像")

axes[1].imshow(erode[:,:,::-1])

axes[1].set_title("腐蝕后圖像")

axes[2].imshow(dilate[:,:,::-1])

axes[2].set_title("膨脹后圖像")

plt.show()

開閉運算

img_1 = cv.imread('img1.png')

img_2 = cv.imread('img2.png')

kernel = np.ones((10,10),np.uint8)

Open = cv.morphologyEx(img_1,cv.MORPH_OPEN,kernel)

Close = cv.morphologyEx(img_2,cv.MORPH_CLOSE,kernel)

fig,axes = plt.subplots(2,2,figsize=(10,8))

axes[0][0].imshow(img_1[:,:,::-1])

axes[0][0].set_title("原圖像")

axes[0,1].imshow(Open[:,:,::-1])

axes[0,1].set_title("開運算圖像")

axes[1,0].imshow(img_2[:,:,::-1])

axes[1,0].set_title("原圖像")

axes[1,1].imshow(Close[:,:,::-1])

axes[1,1].set_title("閉運算圖像")

plt.show()

禮貌和黑帽

img_1 = cv.imread("img1.png")

img_2 = cv.imread("img2.png")

kernel = np.ones((10,10),np.uint8)

Open = cv.morphologyEx(img_1,cv.MORPH_TOPHAT,kernel)

Close = cv.morphologyEx(img_2,cv.MORPH_BLACKHAT,kernel)

fig,axes = plt.subplots(2,2,figsize=(10,8))

axes[0][0].imshow(img_1[:,:,::-1])

axes[0][0].set_title("原圖像")

axes[0,1].imshow(Open[:,:,::-1])

axes[0,1].set_title("禮帽運算結果")

axes[1,0].imshow(img_2[:,:,::-1])

axes[1,0].set_title("原圖像")

axes[1,1].imshow(Close[:,:,::-1])

axes[1,1].set_title("黑帽運算結果")

plt.show()

3.3 圖像的平滑

img_girl= cv.imread("girl_img.png")

# 均值濾波

blur = cv.blur(img_girl,(7,7))

# 高斯濾波

gaublur = cv.GaussianBlur(img_girl,(9,9),0)

# 中值濾波

medblur = cv.medianBlur(img_girl,5)

fig,axes = plt.subplots(2,2,figsize=(10,8))

axes[0][0].imshow(img_girl[:,:,::-1])

axes[0][0].set_title("原圖像")

axes[0,1].imshow(blur[:,:,::-1])

axes[0,1].set_title("均值濾波運算結果")

axes[1,0].imshow(gaublur[:,:,::-1])

axes[1,0].set_title("高斯濾波結果")

axes[1,1].imshow(medblur[:,:,::-1])

axes[1,1].set_title("中值濾波結果")

plt.show()

3.4 直方圖

3.1.4 灰度直方圖

直方圖的計算和繪制

img_dog = cv.imread("dog.jpg",0)

# 統(tǒng)計灰度圖

histr = cv.calcHist(img_dog,[0],None,[256],[0,256])

fig,axes = plt.subplots(1,2,figsize=(18,6))

axes[0].imshow(img_dog,cmap='gray')

axes[1].plot(histr)

axes[1].grid()

axes[1].set_xlabel('Pixel Value')

axes[1].set_ylabel('Frequency')

# 調整布局

plt.tight_layout()

plt.show()

掩碼的應用

img_dog1 = cv.imread("dog.jpg",0)

# 創(chuàng)建遮擋

mask = np.zeros(img_dog1.shape[:2],np.uint8)

mask[50:130,150:230] = 255

# 進行按位與運算

mask_img = cv.bitwise_and(img_dog1,img_dog1,mask=mask)

mask_histr = cv.calcHist([img_dog1],[0],mask,[256],[0,256])

fig,axes = plt.subplots(2,2,figsize=(10,8))

axes[0,0].imshow(img_dog1,cmap='gray')

axes[0,0].set_title("原圖")

axes[0,1].imshow(mask,cmap='gray')

axes[0,1].set_title("遮擋")

axes[1,0].imshow(mask_img,cmap="gray")

axes[1,0].set_title("遮擋后數(shù)據(jù)")

axes[1,1].plot(mask_histr)

axes[1,1].set_title("灰度直方圖")

plt.show()

3.1.5 直方圖均衡化

應用

img_dog = cv.imread("dog.jpg",0)

dst = cv.equalizeHist(img_dog)

fig,axes = plt.subplots(1,2,figsize=(18,6))

axes[0].imshow(img_dog,cmap='gray')

axes[0].set_title("原圖")

axes[1].imshow(dst,cmap='gray')

axes[1].set_title("均衡化后的結果")

# plt.tight_layout()

plt.show()

自適應的直方圖均衡化

img_dog = cv.imread("dog.jpg",0)

clahe = cv.createCLAHE(clipLimit=2,tileGridSize=(12,12))

cl1 = clahe.apply(img_dog)

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(img_dog,cmap="gray")

axes[0].set_title("原圖")

axes[1].imshow(cl1,cmap="gray")

axes[1].set_title("自適應后圖像")

plt.show()

3.5 邊緣檢測

3.5.1 Sobel檢測算子

import cv2 as cv

import matplotlib.pyplot as plt

import numpy as np

img_horse = cv.imread("horse.jpg",0)

# 計算Sobel卷積結果(邊緣檢測)

x = cv.Sobel(img_horse,cv.CV_16S,1,0)

y = cv.Sobel(img_horse,cv.CV_16S,0,1)

# 數(shù)據(jù)轉換(將其縮放到uint8)

scale_x = cv.convertScaleAbs(x)

scale_y = cv.convertScaleAbs(y)

# 結果合成 gamma為正亮度增加,0亮度不變,負數(shù)亮度降低

res = cv.addWeighted(scale_x,0.5,scale_y,0.5,0)

fig,axes = plt.subplots(1,2,figsize=(9,10))

axes[0].imshow(img_horse,cmap='gray')

axes[0].set_title("原圖")

axes[1].imshow(res,cmap=plt.cm.gray)

axes[1].set_title("Sobel濾波后結果")

plt.show()

# ksize為-1時,使用3x3的Scharr濾波器

x = cv.Sobel(img_horse,cv.CV_16S,1,0,ksize=-1)

y = cv.Sobel(img_horse,cv.CV_16S,0,1,ksize=-1)

scale_x = cv.convertScaleAbs(x)

scale_y = cv.convertScaleAbs(y)

res = cv.addWeighted(scale_x,0.5,scale_y,0.5,0)

fig,axes = plt.subplots(1,2,figsize=(9,10))

axes[0].imshow(img_horse,cmap='gray')

axes[0].set_title("原圖")

axes[1].imshow(res,cmap=plt.cm.gray)

axes[1].set_title("Scharr濾波后結果")

plt.show()

3.5.2 Laplacian算子

img_horse = cv.imread("horse.jpg",0)

res = cv.Laplacian(img_horse,cv.CV_16S,ksize=3)

scale_res = cv.convertScaleAbs(res)

fig,axes = plt.subplots(1,2,figsize=(9,10))

axes[0].imshow(img_horse,cmap='gray')

axes[0].set_title("原圖")

axes[1].imshow(scale_res,cmap=plt.cm.gray)

axes[1].set_title("Laplacian濾波后結果")

plt.show()

3.5.3 Canny邊緣檢測

img_horse = cv.imread("horse.jpg",0)

# Canny邊緣檢測,min_threshold最小閾值

min_threshold = 20

max_threshold = 100

res = cv.Canny(img_horse,min_threshold,max_threshold)

fig,axes = plt.subplots(1,2,figsize=(9,10))

axes[0].imshow(img_horse,cmap='gray')

axes[0].set_title("原圖")

axes[1].imshow(res,cmap=plt.cm.gray)

axes[1].set_title("Canny濾波后結果")

plt.show()

3.6 模板匹配和霍夫變換的應用

3.6.1 模板匹配

img_party = cv.imread("party.jpg")

template = cv.imread("template.jpg")

h,w = template.shape[:2]

# 模板匹配

res = cv.matchTemplate(img_party,template,cv.TM_SQDIFF)

# 返回圖像最佳匹配位置,確定左上角的坐標

min_val,max_val,min_loc,max_loc = cv.minMaxLoc(res)

# 使用平方差時(cv.TM_SQDIFF)最小值為最佳匹配位置

top_left = min_loc

bottom_right = (top_left[0]+h,top_left[1]+w)

cv.rectangle(img_party,top_left,bottom_right,(0,255,0),2)

fig,axes = plt.subplots(1,2,figsize=(10,8),gridspec_kw={'width_ratios': [1, 6]})

axes[0].imshow(template[:,:,::-1])

axes[0].set_title("匹配模板")

axes[1].imshow(img_party[:,:,::-1])

axes[1].set_title("匹配結果")

plt.tight_layout()

plt.show()

3.6.2 霍夫變換

# 讀取圖像

img_rili = cv.imread("rili.jpg")

# 使用Canny轉換為二值圖

gray = cv.cvtColor(img_rili,cv.COLOR_BGR2GRAY)

edges = cv.Canny(gray,100,200)

# 霍夫直線變換

lines = cv.HoughLines(edges,0.8,np.pi/180,150)

# 檢查是否檢測到直線

for line in lines:

rho, theta = line[0]

a = np.cos(theta)

b = np.sin(theta)

x0 = a * rho

y0 = b * rho

x1 = int(x0 - 1000 * b)

y1 = int(y0 + 1000 * a)

x2 = int(x0 + 1000 * b)

y2 = int(y0 - 1000 * a)

cv.line(img_rili, (x1, y1), (x2, y2), (0, 0, 255), 2)

# 使用matplotlib顯示圖像

plt.imshow(img_rili[:, :, ::-1])

plt.xticks([]), plt.yticks([])

plt.title("霍夫變換直線檢測")

plt.show()

3.7 圖像變化

3.7.1 傅里葉變換

讀取圖像: 讀取圖像并轉換為灰度圖像。 傅里葉變換: 正變換:將圖像轉換為頻域表示。 頻譜中心化:將頻譜的低頻部分移到中心,高頻部分移到四周。 計算頻譜和相位譜:將復數(shù)形式的頻譜轉換為幅度和相位,并對幅度譜進行對數(shù)變換。 傅里葉逆變換: 反變換:將頻域表示轉換回時域(或空域)。 計算灰度值:計算逆變換后的圖像的幅度。 顯示結果: 使用 matplotlib 顯示原始圖像、頻譜圖和逆變換后的圖像。

img_dog= cv.imread("dog.jpg",0)

# 傅里葉正變換,cv.DFT_COMPLEX_OUTPUT:指定輸出為復數(shù)形式

dft = cv.dft(np.float32(img_dog),flags=cv.DFT_COMPLEX_OUTPUT)

# 頻譜中心化

dft_shift = np.fft.fftshift(dft)

# 計算頻譜和相位譜

mag,angle = cv.cartToPolar(dft_shift[:,:,0],dft_shift[:,:,-1],angleInDegrees=True)

# 對幅度譜進行對數(shù)變換,以便更好地可視化。對數(shù)變換可以壓縮動態(tài)范圍,使圖像的細節(jié)更明顯。

mag = 20 * np.log(mag)

# 傅里葉反變換

img_back = cv.idft(dft)

img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])

fig,axes = plt.subplots(2,2,figsize=(10,8))

axes[0,0].imshow(img_dog,cmap='gray')

axes[0,0].set_title("原圖")

axes[0,1].imshow(mag,cmap='gray')

axes[0,1].set_title("頻譜")

axes[1,0].imshow(angle,cmap='gray')

axes[1,0].set_title("相位譜")

axes[1,1].imshow(img_back,cmap='gray')

axes[1,1].set_title("逆變換結果")

plt.show()

3.7.2 高通和低通濾波

# 高通濾波

dog_img = cv.imread("dog.jpg",0)

rows,cols = dog_img.shape

mask = np.ones((rows,cols,2),np.uint8)

mask[int(rows/2)-30:int(rows/2)+30,int(cols/2)-30:int(cols/2)+30,:] = 0

# 正變換

dft = cv.dft(np.float32(dog_img),flags=cv.DFT_COMPLEX_OUTPUT)

# 頻譜中心化

dft_shift = np.fft.fftshift(dft)

# 濾波(移除低頻)

dft_shift = dft_shift * mask

# 頻譜中心化

dft_shift = np.fft.fftshift(dft_shift)

# 反變化

img_back = cv.idft(dft_shift)

# 計算灰度值

img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(dog_img, cmap = 'gray')

axes[0].set_title('原圖')

axes[1].imshow(img_back, cmap = 'gray')

axes[1].set_title('高通濾波結果')

plt.show()

# 低通濾波

dog_img = cv.imread("dog.jpg",0)

rows,cols = dog_img.shape

mask = np.zeros((rows,cols,2),np.uint8)

mask[int(rows/2)-30:int(rows/2)+30,int(cols/2)-30:int(cols/2)+30,:] = 1

# 正變換

dft = cv.dft(np.float32(dog_img),flags=cv.DFT_COMPLEX_OUTPUT)

# 頻譜中心化

dft_shift = np.fft.fftshift(dft)

# 濾波(移除低頻)

dft_shift = dft_shift * mask

# 頻譜中心化

dft_shift = np.fft.fftshift(dft_shift)

# 反變化

img_back = cv.idft(dft_shift)

# 計算灰度值

img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(dog_img, cmap = 'gray')

axes[0].set_title('原圖')

axes[1].imshow(img_back, cmap = 'gray')

axes[1].set_title('低通濾波結果')

plt.show()

3.7.3 帶通和帶阻濾波

# 帶通濾波

dog_img = cv.imread("dog.jpg",0)

rows,cols = dog_img.shape

mask1 = np.ones((rows,cols,2),np.uint8)

mask1[int(rows/2)-8:int(rows/2)+8,int(cols/2)-8:int(cols/2)+8] = 0

mask2 = np.zeros((rows,cols,2),np.uint8)

mask2[int(rows/2)-80:int(rows/2)+80,int(cols/2)-80:int(cols/2)+80] = 1

mask = mask1*mask2

# 正變換

dft = cv.dft(np.float32(dog_img),flags=cv.DFT_COMPLEX_OUTPUT)

# 頻譜中心化

dft_shift = np.fft.fftshift(dft)

# 濾波(移除低頻)

dft_shift = dft_shift * mask

# 頻譜中心化

dft_shift = np.fft.fftshift(dft_shift)

# 反變化

img_back = cv.idft(dft_shift)

# 計算灰度值

img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(dog_img, cmap = 'gray')

axes[0].set_title('原圖')

axes[1].imshow(img_back, cmap = 'gray')

axes[1].set_title('帶通濾波結果')

plt.show()

# 帶阻濾波

dog_img = cv.imread("dog.jpg",0)

rows,cols = dog_img.shape

mask = np.ones((rows,cols,2),np.uint8)

mask[int(rows/2)+60:int(rows/2)+130,int(cols/2)-130:int(cols/2)+130] = 0

mask[int(rows/2)-130:int(rows/2)-60,int(cols/2)-130:int(cols/2)+130] = 0

mask[int(rows/2)-130:int(rows/2)+130,int(cols/2)+60:int(cols/2)+130] = 0

mask[int(rows/2)-130:int(rows/2)+130,int(cols/2)-130:int(cols/2)-60] = 0

# 正變換

dft = cv.dft(np.float32(dog_img),flags=cv.DFT_COMPLEX_OUTPUT)

# 頻譜中心化

dft_shift = np.fft.fftshift(dft)

# 濾波(移除低頻)

dft_shift = dft_shift * mask

# 頻譜中心化

dft_shift = np.fft.fftshift(dft_shift)

# 反變化

img_back = cv.idft(dft_shift)

# 計算灰度值

img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(dog_img, cmap = 'gray')

axes[0].set_title('原圖')

axes[1].imshow(img_back, cmap = 'gray')

axes[1].set_title('帶阻濾波結果')

plt.show()

3.8 輪廓檢測與輪廓特征

3.8.1 輪廓檢測

import cv2 as cv

import matplotlib.pyplot as plt

import numpy as np

ditu = cv.imread("ditu.jpg")

# 復制原圖

img_ditu = ditu.copy()

imggray = cv.cvtColor(ditu,cv.COLOR_BGR2GRAY)

canny = cv.Canny(imggray,120,255)

# 輪廓提取

contours,hierarchy = cv.findContours(canny,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)

# 將輪廓繪制在圖形上

img = cv.drawContours(ditu,contours,-1,(0,0,255),2)

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(img_ditu[:,:,::-1])

axes[0].set_title("原圖")

axes[1].imshow(img[:,:,::-1])

axes[1].set_title("輪廓")

plt.show()

3.8.2 輪廓特征

輪廓面積

area = sum(cv.contourArea(cnt) for cnt in contours)

area

輪廓周長

perimeter = sum(cv.arcLength(cnt,True) for cnt in contours)

perimeter

輪廓近似

# 讀取圖像

img = cv.imread("jinsi.jpg")

# 灰度轉換

imggray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

# 二值化處理

ret, thresh = cv.threshold(imggray, 127, 255, cv.THRESH_BINARY)

# 輪廓提取

contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

# 初始化繪制圖像

img_contours = img.copy()

img_approx = img.copy()

# 處理所有輪廓

for cnt in contours:

# 計算輪廓的弧長

arc_length = cv.arcLength(cnt, True)

# 計算近似多邊形

epsilon = 0.1 * arc_length

approx = cv.approxPolyDP(cnt, epsilon, True)

# 繪制原始輪廓和近似多邊形(-1表示繪制所有輪廓)

img_contours = cv.drawContours(img_contours, [cnt], -1, (0, 255, 0), 2)

img_approx = cv.drawContours(img_approx, [approx], -1, (0, 255, 0), 2)

# 顯示圖像

fig, axes = plt.subplots(1, 3, figsize=(10, 13))

axes[0].imshow(ditu[:, :, ::-1])

axes[0].set_title("原圖")

axes[1].imshow(img_contours[:, :, ::-1])

axes[1].set_title("原始輪廓")

axes[2].imshow(img_approx[:, :, ::-1])

axes[2].set_title("近似多邊形")

plt.show()

凸包

star = cv.imread("star.jpg")

# 灰度處理

imggray = cv.cvtColor(star,cv.COLOR_BGR2GRAY)

# 邊緣檢測

canny = cv.Canny(imggray,50,200)

# 獲取輪廓

contours,hierarchy = cv.findContours(canny,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)

# 圖像復制

img_star = star.copy()

#凸包檢測

Hulls = []

for cnt in contours:

hull = cv.convexHull(cnt)

Hulls.append(hull)

# 繪制圖形

img_contour = cv.drawContours(star,contours,-1,(255,0,0),2)

img_hull = cv.drawContours(img_star,Hulls,-1,(255,0,0),2)

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(img_contour[:,:,::-1])

axes[0].set_title("輪廓檢測結果")

axes[1].imshow(img_hull[:,:,::-1])

axes[1].set_title("凸包結果")

plt.show()

邊界矩形

rect = cv.imread("rect.jpg")

# 灰度處理

imggray = cv.cvtColor(rect,cv.COLOR_BGR2GRAY)

# 轉換為二值化

ret,thresh = cv.threshold(imggray,127,255,0)

# 輪廓提取

contours,hierarchy = cv.findContours(thresh,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)

# 圖像復制

rect_img = rect.copy()

# 直邊界矩形

bounding_box = []

for cnt in contours:

x,y,w,h = cv.boundingRect(cnt)

bounding_box.append((x,y,w,h))

for x,y,w,h in bounding_box:

cv.rectangle(rect,(x,y),(x+w,y+h),(0,255,0),2)

# 旋轉邊界矩形

min_area_rects = []

for cnt in contours:

rect_min = cv.minAreaRect(cnt)

box = cv.boxPoints(rect_min)

box = np.int0(box)

min_area_rects.append(box)

for box in min_area_rects:

cv.polylines(rect_img,[box],True,(0,255,0),2)

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(rect[:,:,::-1])

axes[0].set_title("直邊界矩形")

axes[0].set_xticks([]),axes[0].set_yticks([])

axes[1].imshow(rect_img[:,:,::-1])

axes[1].set_title("旋轉邊界矩形")

axes[1].set_xticks([]),axes[1].set_yticks([])

plt.show()

最小外接圓

img = cv.imread("rect.jpg")

imggray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)

ret,thresh = cv.threshold(imggray,127,255,0)

contours,hierarchy = cv.findContours(thresh,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)

boundings = []

for cnt in contours:

(x,y),radius = cv.minEnclosingCircle(cnt)

center = (int(x),int(y))

radius = int(radius)

boundings.append((center,radius))

for center,radius in boundings:

cv.circle(img,center,radius,(0,255,0),2)

plt.imshow(img[:,:,::-1])

plt.xticks([])

plt.yticks([])

plt.show()

橢圓擬合

img = cv.imread("rect.jpg")

imggray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)

ret,thresh = cv.threshold(imggray,127,255,0)

contours,hierarchy = cv.findContours(thresh,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)

boundings = []

for cnt in contours:

# 過濾掉點數(shù)少于5個和面積過小的輪廓

if len(cnt) >= 5 and cv.contourArea(cnt) > 100:

ellipse = cv.fitEllipse(cnt)

boundings.append(ellipse)

for ellipse in boundings:

cv.ellipse(img,ellipse,(0,255,0),2)

plt.imshow(img[:,:,::-1])

plt.xticks([])

plt.yticks([])

plt.show()

3.9 圖像分割

3.9.1 全閾值分割

img = cv.imread("gradient.jpg",0)

ret,thresh1 = cv.threshold(img,127,255,cv.THRESH_BINARY)

ret,thresh2 = cv.threshold(img,127,255,cv.THRESH_BINARY_INV)

ret,thresh3 = cv.threshold(img,127,255,cv.THRESH_TRUNC)

ret,thresh4 = cv.threshold(img,127,255,cv.THRESH_TOZERO)

ret,thresh5 = cv.threshold(img,127,255,cv.THRESH_TOZERO_INV)

titles = ["原圖","閾值二值化","閾值反二值化","截斷","閾值取零","閾值反取零"]

images = [img,thresh1,thresh2,thresh3,thresh4,thresh5]

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

for i in range(6):

plt.subplot(2,3,i+1)

plt.imshow(images[i],cmap='gray')

plt.title(titles[i])

plt.show()

3.9.2 自適應閾值分割

fruit = cv.imread("fruit.jpg",0)

# 固定閾值

ret,threshold = cv.threshold(fruit,127,225,cv.THRESH_BINARY)

# 自適應閾值

# 領域內求平均值

th1 = cv.adaptiveThreshold(fruit,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,11,4)

# 領域內高斯加權

th2 = cv.adaptiveThreshold(fruit,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,17,6)

title = ["原圖","固定閾值","自適應閾值(求均值)","自適應閾值(高斯加權)"]

images = [fruit,threshold,th1,th2]

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

for i in range(4):

plt.subplot(2,2,i+1)

plt.imshow(images[i],cmap="gray")

plt.title(title[i])

plt.show()

3.9.3 Ostu閾值(大律法)

littledog = cv.imread("littledog.jpg",0)

# 固定閾值

ret,thresh = cv.threshold(littledog,40,255,cv.THRESH_BINARY)

# ostu分割

ret1,thresh2 = cv.threshold(littledog,0,255,cv.THRESH_BINARY+cv.THRESH_OTSU)

fig,axes = plt.subplots(1,3,figsize=(10,8))

axes[0].imshow(littledog,cmap="gray")

axes[0].set_title("原圖")

axes[1].imshow(thresh,cmap="gray")

axes[1].set_title("全閾值分割")

axes[2].imshow(thresh2,cmap="gray")

axes[2].set_title("OStu分割")

plt.show()

3.9.4 分水嶺算法

img = cv.imread("horse.jpg")

imggray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)

# 邊緣檢測

canny = cv.Canny(imggray,127,255)

# 輪廓檢測

contours,hierarchy = cv.findContours(canny,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)

# 初始化標記圖像

marks = np.zeros(img.shape[:2],np.int32)

# 繪制輪廓

for index in range(len(contours)):

# index:-1 繪制所有的輪廓,非負數(shù):要繪制的輪廓的索引

marks = cv.drawContours(marks,contours,index,(index,index,index),1,8,hierarchy)

# 使用分水嶺算法

# img必須是8位無符號整數(shù)的三通道圖像,marks必須是32位有符號整數(shù)的單通道圖像

# 返回值:正整數(shù):表示該像素屬于某個特定區(qū)域,-1表示該像素是區(qū)域的邊界

marks = cv.watershed(img,marks)

# 生成隨機顏色

colours = np.zeros((np.max(marks) + 1,3))

for i in range(len(colours)):

aa = np.random.uniform(0,255)

bb = np.random.uniform(0,255)

cc = np.random.uniform(0,255)

colours[i] = np.array([aa,bb,cc],np.uint8)

# 對每個區(qū)域進行顏色填充

bgrimg = np.zeros(img.shape,np.uint8)

index = 0

for i in range(marks.shape[0]):

for j in range(marks.shape[1]):

index = marks[i][j]

if index == -1:

bgrimg[i][j] = np.array([255,255,255])

else:

bgrimg[i][j] = colours[index]

plt.imshow(bgrimg[:,:,::-1])

plt.title("圖像分割結果")

plt.show()

3.9.5 GrabCut算法

img = cv.imread("liying.jpg")

masks = np.zeros(img.shape[:2],np.uint8)

# 矩形窗口,指定前景區(qū)域

rect = [260,50,740,730]

# 前景和背景分割

cv.grabCut(img,masks,tuple(rect),None,None,30,cv.GC_INIT_WITH_RECT)

# 摳取圖像

mask2 = np.where((masks==2)|(masks==0),0,1).astype("uint8")

img_show = img * mask2[:,:,np.newaxis]

# 將矩形繪制在圖像上

cv.rectangle(img,(260,50),(1000,780),(255,0,0),2)

fig,axes = plt.subplots(1,2,figsize=(10,8))

axes[0].imshow(img[:,:,::-1])

axes[0].set_title("矩形框選位置")

axes[1].imshow(img_show[:,:,::-1])

axes[1].set_title("扣取結果")

plt.show()

四、圖像的特征提取與描述

圖像特征要有區(qū)分性,容易被比較。一般認為角點、斑點等是比較好的圖像特征特征檢測:找到圖像中的特征特征描述:對特征及其周圍的區(qū)域描述

4.1 Harris角點檢測

Harris角點檢測的思想是通過圖像的局部的小窗口觀察圖像,角點的特征是窗口沿任意方向移動都會導致圖像灰度明顯變化。

import cv2 as cv

import matplotlib.pyplot as plt

import numpy as np

# 對棋盤進行角點檢測

qipan = cv.imread("qipan.jpg")

gray = cv.cvtColor(qipan,cv.COLOR_BGR2GRAY)

gray = np.float32(gray)

# Harris角點檢測

# 2,blockSize計算每個像素的角點響應時考慮的窗口大小

# 3,Sobel 算子用于計算圖像的梯度,進而用于計算角點響應。

# 0.04,用于平衡角點檢測的靈敏度

dst = cv.cornerHarris(gray,2,3,0.04)

# 設置閾值,選擇 dst 中角點響應值大于閾值的像素位置

qipan[dst > 0.001*dst.max()] = [0,255,0]

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

plt.imshow(qipan[:,:,::-1])

plt.show()

4.2 Shi-Tomasi角點檢測

tv = cv.imread("tv.jpg")

gray = cv.cvtColor(tv,cv.COLOR_BGR2GRAY)

# 提取角坐標

conners = cv.goodFeaturesToTrack(gray,1000,0.01,10)

# 繪制角點

for i in conners:

# 將坐標展平為一維

x,y = i.ravel()

x,y = int(x),int(y)

cv.circle(tv,(x,y),3,(0,255,0),-1)

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

plt.imshow(tv[:,:,::-1])

plt.show()

4.3 sift算法

通過多尺度空間檢測極值點作為關鍵點,確保尺度不變性;再對關鍵點鄰域進行方向賦值,確保旋轉不變性,從而實現(xiàn)對圖像特征的穩(wěn)定提取。

tv = cv.imread("tv.jpg")

gray = cv.cvtColor(tv,cv.COLOR_BGR2GRAY)

# 實例化shif

sift = cv.xfeatures2d.SIFT_create()

# 角點檢測:kp角點的信息包括坐標,方向等 des角點描述

kp, des = sift.detectAndCompute(gray,None)

# 繪制角點

cv.drawKeypoints(tv,kp,tv,flags=cv.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

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

plt.imshow(tv[:,:,::-1])

plt.show()

4.4 fast檢測算法

若一個像素周圍有一定數(shù)量的像素與該點像素值不同,則認為其為角點

tv = cv.imread("tv.jpg")

# 實例化fast對象

fast = cv.FastFeatureDetector_create(threshold=30)

# 檢測關鍵的

kp = fast.detect(tv,None)

# 繪制關鍵點,默認開啟非極大值抑制,抑制候選角點的重疊

img1 = cv.drawKeypoints(tv,kp,None,(0,0,255))

# 關閉非極大值抑制

fast.setNonmaxSuppression(0)

kp = fast.detect(tv,None)

img2 = cv.drawKeypoints(tv,kp,None,(0,0,255))

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

plt.subplot(121)

plt.imshow(img1[:,:,::-1])

plt.title("開啟非極大值抑制")

plt.subplot(122)

plt.imshow(img2[:,:,::-1])

plt.title("關閉非極大值抑制")

plt.show()

4.5 orb角點檢測

tv = cv.imread("tv.jpg")

# 實例化ORB

# nfeatures設置要檢測的最大特征點數(shù)量

orb = cv.ORB_create(nfeatures=200)

# 角點檢測

kp,des = orb.detectAndCompute(tv,None)

# 繪制角點

cv.drawKeypoints(tv,kp,tv,(0,255,0))

plt.figure(figsize=(5,4))

plt.imshow(tv[:,:,::-1])

plt.show()

五、視頻操作

import cv2 as cv

import numpy as np

import matplotlib.pyplot as plt

5.1 視頻讀寫

video_ying = cv.VideoCapture("趙麗穎.mp4")

# 查看是否捕獲成功

video_ying.isOpened()

# 判斷是否讀取成功

while(video_ying.isOpened()):

# 獲取每一幀圖像

ret,frame = video_ying.read()

if ret == True:

cv.imshow("frame",frame)

# 每一幀間隔50秒,按q退出

if cv.waitKey(50) & 0xFF == ord('q'):

break

# 釋放VideoCapture對象,關閉視頻文件

video_ying.release()

# 關閉OpenCV所創(chuàng)建的窗口

cv.destroyAllWindows()

5.2 視頻保存

# 讀取視頻

cap = cv.VideoCapture("趙麗穎.mp4")

# 獲取圖像的屬性(寬度和高度),并將其轉換為整數(shù)

frame_width = int(cap.get(3))

frame_height = int(cap.get(4))

# 創(chuàng)建保存視頻的對象,設置編碼格式,幀率,圖像的寬度和高度

out = cv.VideoWriter('outpy.avi', cv.VideoWriter_fourcc('M', 'J', 'P', 'G'), 10, (frame_width, frame_height))

# 循環(huán)讀取視頻中的每一幀圖像

while True:

# 獲取視頻中的每一幀圖像

ret, frame = cap.read()

# 如果讀取成功,將每一幀圖像寫入到輸出文件中

if ret == True:

out.write(frame)

else:

break

# 釋放資源

cap.release()

out.release()

cv.destroyAllWindows()

5.3 視頻追蹤

目標:追蹤視頻中的小柯基

5.3.1 meanshift算法

簡單,迭代次數(shù)少。但不能適應運動目標的形狀和大小的變化

import cv2 as cv

import numpy as np

# 視頻捕獲

video_dog = cv.VideoCapture('dog.mp4')

# 獲取第一幀圖像,并指定目標位置

ret, frame = video_dog.read()

# 目標位置(行,高,列,寬)

r, h, c, w = 140, 230, 300, 150

track_window = (c, r, w, h)

# 指定目標的感興趣區(qū)域

roi = frame[r:r+h, c:c+w]

# 計算直方圖

# 轉換色彩空間(HSV)

hsv_roi = cv.cvtColor(roi, cv.COLOR_BGR2HSV)

# 去除低亮度的值(色調,飽和度,亮度)

mask = cv.inRange(hsv_roi, np.array((0, 100, 52)), np.array((180, 255, 255)))

# 計算直方圖

# [0] 只計算第一個通道,即色調(hue)通道的直方圖

# [180] 定義直方圖bin數(shù)量

# [0,180] 計算從0到180之間的色調值的直方圖

roi_hist = cv.calcHist([hsv_roi],[0],mask,[180],[0,180])

# 歸一化

cv.normalize(roi_hist, roi_hist, 0, 255, cv.NORM_MINMAX)

# 目標追蹤

# 設置窗口搜索終止條件:最大迭代次數(shù),窗口中心漂移最小值

term_crit = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1)

while True:

# 獲取每一幀圖像

ret, frame = video_dog.read()

if ret:

# 算直方圖的反向投影,生成一個概率圖 dst,指示當前幀中哪些區(qū)域最可能包含目標。

hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)

dst = cv.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)

# 進行Meanshift追蹤

ret, track_window = cv.meanShift(dst, track_window, term_crit)

# 追蹤的位置繪制在視頻上,并進行顯示

x, y, w, h = track_window

img2 = cv.rectangle(frame, (x, y), (x + w, y + h), 255, 2)

cv.imshow('frame', img2)

if cv.waitKey(65) & 0xFF == ord('q'):

break

else:

break

video_dog.release()

cv.destroyAllWindows()

5.3.2 camshift算法

camshift算法可以適應目標大小形狀的改變,具有較好的追蹤效果。但當背景色和目標顏色接近時,容易使目標的區(qū)域變大。

import cv2 as cv

import numpy as np

video_dog = cv.VideoCapture('dog.mp4')

# 獲取第一幀圖像,并指定目標位置

ret, frame = video_dog.read()

# 目標位置

r, h, c, w = 170, 150, 350, 90

track_window = (c, r, w, h)

# 指定目標區(qū)域

roi = frame[r:r+h, c:c+w]

# 計算直方圖

# 轉換色彩空間(HSV)

hsv_roi = cv.cvtColor(roi, cv.COLOR_BGR2HSV)

# 去除低亮度的值(色調,飽和度,亮度)

mask = cv.inRange(hsv_roi, np.array((0, 100, 50)), np.array((180, 255, 255)))

# 計算直方圖

# [0] 只計算第一個通道,即色調(hue)通道的直方圖

# [180] 定義直方圖bin數(shù)量

# [0,180] 計算從0到180之間的色調值的直方圖

roi_hist = cv.calcHist([hsv_roi],[0],mask,[180],[0,180])

# 歸一化

cv.normalize(roi_hist, roi_hist, 0, 255, cv.NORM_MINMAX)

# 目標追蹤

# 設置窗口搜索終止條件:最大迭代次數(shù),窗口中心漂移最小值

term_crit = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1)

while True:

ret, frame = video_dog.read()

if ret:

# 計算直方圖的反向投影,生成一個概率圖 dst,指示當前幀中哪些區(qū)域最可能包含目標。

hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)

dst = cv.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)

# CamShift追蹤

ret, track_window = cv.CamShift(dst, track_window, term_crit)

# 將追蹤的位置繪制在視頻上,并進行顯示

# pst矩形框的四個坐標

pts = cv.boxPoints(ret)

pts = np.intp(pts)

img2 = cv.polylines(frame,[pts],True, 255,2)

# 顯示圖像

cv.imshow('frame', img2)

if cv.waitKey(60) & 0xFF == ord('q'):

break

else:

break

video_dog.release()

cv.destroyAllWindows()

六、人臉、眼睛檢測案例

OpenCV中自帶已訓練好的檢測器,包括面部、眼睛等,都保存在XML中,我們可以通過以下程序找到他們:

import cv2 as cv

print(cv.__file__)

所有的XML文件都在D:\Anaconda\Lib\site-packages\cv2\data\中

6.1 人臉以及眼睛檢測(圖片)

img = cv.imread("liying2.jpg")

gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)

# 定義訓練器路徑

cascade_path = "D:\\Anaconda\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml"

eye_cascade_path = "D:\\Anaconda\\Lib\\site-packages\\cv2\\data\\haarcascade_eye.xml"

# 實例化人臉級聯(lián)分類器

face_cas = cv.CascadeClassifier(cascade_path)

# 實例化眼睛級聯(lián)分類器

eyes_cas = cv.CascadeClassifier(eye_cascade_path)

# 人臉檢測

faceRects = face_cas.detectMultiScale(gray,scaleFactor=1.05,minNeighbors=5,minSize=(20,20))

# 遍歷人臉

for faceRect in faceRects:

x,y,w,h = faceRect

cv.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

roi_color = img[x:x+w,y:y+h]

roi_gray = gray[x:x+w,y:y+h]

eyes = eyes_cas.detectMultiScale(roi_gray,scaleFactor=1.2, minNeighbors=5, minSize=(30, 30), maxSize=(100, 100))

for x,y,w,h in eyes:

cv.rectangle(roi_color,(x,y),(x+w,y+h),(255,0,0),2)

plt.figure(figsize=(7,4))

plt.imshow(img[:,:,::-1])

plt.title("檢測結果")

plt.show()

6.2 人臉以及眼睛檢測(視頻)

import cv2 as cv

import matplotlib.pyplot as plt

video = cv.VideoCapture("趙麗穎.mp4")

cascade_path = "D:\\Anaconda\\Lib\\site-packages\\cv2\\data\\haarcascade_frontalface_default.xml"

eyes_cascade_path = "D:\\Anaconda\\Lib\\site-packages\\cv2\\data\\haarcascade_eye.xml"

while True:

ret,frame = video.read()

if ret==True:

gray = cv.cvtColor(frame,cv.COLOR_BGR2GRAY)

# 實例化人臉級聯(lián)分類器

face_cas = cv.CascadeClassifier(cascade_path)

# 實例化眼睛級聯(lián)分類器

eyes_cas = cv.CascadeClassifier(eyes_cascade_path)

# 檢測人臉

faceRects = face_cas.detectMultiScale(gray,scaleFactor=1.2,minNeighbors=3,minSize=(60,60))

for faceRect in faceRects:

x,y,w,h = faceRect

cv.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)

roi_color = frame[y:y+h,x:x+w]

# 定位人臉上半部分

roi_gray = gray[y:y+int(h*0.7),x:x+w]

eyes = eyes_cas.detectMultiScale(roi_gray,scaleFactor=1.3,minNeighbors=5, minSize=(20,20), maxSize=(100, 100))

for x,y,w,h in eyes:

cv.rectangle(roi_color,(x,y),(x+w,y+h),(255,0,0),2)

cv.imshow("frame",frame)

if cv.waitKey(20) & 0xFF==ord('q'):

break

else:

break

video.release()

cv.destroyAllWindows()

由于運行結果是視頻所以無法展示

柚子快報激活碼778899分享:OpenCV計算機視覺庫

http://yzkb.51969.com/

參考文章

評論可見,查看隱藏內容

本文內容根據(jù)網(wǎng)絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉載請注明,如有侵權,聯(lián)系刪除。

本文鏈接:http://m.gantiao.com.cn/post/19609570.html

發(fā)布評論

您暫未設置收款碼

請在主題配置——文章設置里上傳

掃描二維碼手機訪問

文章目錄