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

首頁綜合 正文
目錄

柚子快報(bào)激活碼778899分享:OpenCV計(jì)算機(jī)視覺庫

柚子快報(bào)激活碼778899分享:OpenCV計(jì)算機(jī)視覺庫

http://yzkb.51969.com/

計(jì)算機(jī)視覺和圖像處理

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

OpenCV

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

二、OpenCV基本操作2.1 圖像的基本操作2.1.1 圖像的IO操作2.1.2 繪制幾何圖像2.1.3 獲取并修改圖像的像素點(diǎn)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)學(xué)操作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 模板匹配和霍夫變換的應(yīng)用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 自適應(yīng)閾值分割3.9.3 Ostu閾值(大律法)3.9.4 分水嶺算法3.9.5 GrabCut算法

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

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

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

一、OpenCV簡介

1.1 簡介

OpenCV是?個(gè)計(jì)算機(jī)視覺處理開源軟件庫,?持與計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)相關(guān)的眾多算法。

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算法進(jìn)行特征提取時(shí),還需安裝:

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

查看是否安裝成功

import cv2

cv2.__version__

1.3 OpenCV模塊

core模塊實(shí)現(xiàn)了最核心的數(shù)據(jù)結(jié)構(gòu)及其基本運(yùn)算,如繪圖函數(shù)、數(shù)組操作相關(guān)函數(shù)等。highgui模塊實(shí)現(xiàn)了視頻與圖像的讀取、顯示、存儲等接口。imgproc模塊實(shí)現(xiàn)了圖像處理的基礎(chǔ)方法,包括圖像濾波、圖像的幾何變換、平滑、閾值分割、形態(tài)學(xué)處理、邊緣檢測、目標(biāo)檢測、運(yùn)動分析和對象跟蹤等。features2d模塊用于提取圖像特征以及特征匹配,nonfree模塊實(shí)現(xiàn)了一些專利算法,如sift特征。objdetect模塊實(shí)現(xiàn)了一些目標(biāo)檢測的功能,經(jīng)典的基于Haar、LBP特征的人臉檢測,基于HOG的行人、汽車等目標(biāo)檢測,分類器使用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 是一個(gè)基于 Web 的交互式計(jì)算環(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圖像轉(zhuǎn)換為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)

# 直線的起點(diǎn)、終點(diǎn)、顏色、寬度

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 獲取并修改圖像的像素點(diǎn)

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

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

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

img2[50,200]

#獲取位置(50,100)藍(lán)色通道的強(qiáng)度值,0表示藍(lán)色,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通道圖像轉(zhuǎn)變?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

形狀相同才能進(jìn)行相加

# 縮小圖形形狀

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')

# 像素點(diǎn)平移(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()

圖像旋轉(zhuǎn)

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

rows,cols = img.shape[:2]

# 旋轉(zhuǎn)矩陣

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("旋轉(zhuǎn)后圖像")

plt.show()

仿射變換

rows,cols = img.shape[:2]

# 原點(diǎn)集

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

# 目標(biāo)點(diǎn)集

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)

# 進(jìn)行變換

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)學(xué)操作

膨脹和腐蝕

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

# 創(chuàng)建核結(jié)構(gòu)

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()

開閉運(yùn)算

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("開運(yùn)算圖像")

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

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

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

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

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("禮帽運(yùn)算結(jié)果")

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

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

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

axes[1,1].set_title("黑帽運(yùn)算結(jié)果")

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("均值濾波運(yùn)算結(jié)果")

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

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

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

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

plt.show()

3.4 直方圖

3.1.4 灰度直方圖

直方圖的計(jì)算和繪制

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

# 統(tǒng)計(jì)灰度圖

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')

# 調(diào)整布局

plt.tight_layout()

plt.show()

掩碼的應(yīng)用

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

# 創(chuàng)建遮擋

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

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

# 進(jìn)行按位與運(yùn)算

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 直方圖均衡化

應(yīng)用

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("均衡化后的結(jié)果")

# plt.tight_layout()

plt.show()

自適應(yīng)的直方圖均衡化

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("自適應(yīng)后圖像")

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)

# 計(jì)算Sobel卷積結(jié)果(邊緣檢測)

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

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

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

scale_x = cv.convertScaleAbs(x)

scale_y = cv.convertScaleAbs(y)

# 結(jié)果合成 gamma為正亮度增加,0亮度不變,負(fù)數(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濾波后結(jié)果")

plt.show()

# ksize為-1時(shí),使用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濾波后結(jié)果")

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濾波后結(jié)果")

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濾波后結(jié)果")

plt.show()

3.6 模板匹配和霍夫變換的應(yīng)用

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)

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

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

# 使用平方差時(shí)(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("匹配結(jié)果")

plt.tight_layout()

plt.show()

3.6.2 霍夫變換

# 讀取圖像

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

# 使用Canny轉(zhuǎn)換為二值圖

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 傅里葉變換

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

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

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

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

# 頻譜中心化

dft_shift = np.fft.fftshift(dft)

# 計(jì)算頻譜和相位譜

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

# 對幅度譜進(jìn)行對數(shù)變換,以便更好地可視化。對數(shù)變換可以壓縮動態(tài)范圍,使圖像的細(xì)節(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("逆變換結(jié)果")

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)

# 計(jì)算灰度值

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('高通濾波結(jié)果')

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)

# 計(jì)算灰度值

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('低通濾波結(jié)果')

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)

# 計(jì)算灰度值

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('帶通濾波結(jié)果')

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)

# 計(jì)算灰度值

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('帶阻濾波結(jié)果')

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")

# 復(fù)制原圖

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")

# 灰度轉(zhuǎn)換

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:

# 計(jì)算輪廓的弧長

arc_length = cv.arcLength(cnt, True)

# 計(jì)算近似多邊形

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)

# 圖像復(fù)制

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("輪廓檢測結(jié)果")

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

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

plt.show()

邊界矩形

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

# 灰度處理

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

# 轉(zhuǎn)換為二值化

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

# 輪廓提取

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

# 圖像復(fù)制

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)

# 旋轉(zhuǎn)邊界矩形

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("旋轉(zhuǎn)邊界矩形")

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:

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

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 = ["原圖","閾值二值化","閾值反二值化","截?cái)?,"閾值取零","閾值反取零"]

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 自適應(yīng)閾值分割

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

# 固定閾值

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

# 自適應(yīng)閾值

# 領(lǐng)域內(nèi)求平均值

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

# 領(lǐng)域內(nèi)高斯加權(quán)

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

title = ["原圖","固定閾值","自適應(yīng)閾值(求均值)","自適應(yīng)閾值(高斯加權(quán))"]

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)

# 初始化標(biāo)記圖像

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

# 繪制輪廓

for index in range(len(contours)):

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

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

# 使用分水嶺算法

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

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

marks = cv.watershed(img,marks)

# 生成隨機(jī)顏色

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)

# 對每個(gè)區(qū)域進(jìn)行顏色填充

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("圖像分割結(jié)果")

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("扣取結(jié)果")

plt.show()

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

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

4.1 Harris角點(diǎn)檢測

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

import cv2 as cv

import matplotlib.pyplot as plt

import numpy as np

# 對棋盤進(jìn)行角點(diǎn)檢測

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

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

gray = np.float32(gray)

# Harris角點(diǎn)檢測

# 2,blockSize計(jì)算每個(gè)像素的角點(diǎn)響應(yīng)時(shí)考慮的窗口大小

# 3,Sobel 算子用于計(jì)算圖像的梯度,進(jìn)而用于計(jì)算角點(diǎn)響應(yīng)。

# 0.04,用于平衡角點(diǎn)檢測的靈敏度

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

# 設(shè)置閾值,選擇 dst 中角點(diǎn)響應(yīng)值大于閾值的像素位置

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

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

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

plt.show()

4.2 Shi-Tomasi角點(diǎn)檢測

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

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

# 提取角坐標(biāo)

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

# 繪制角點(diǎn)

for i in conners:

# 將坐標(biāo)展平為一維

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算法

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

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

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

# 實(shí)例化shif

sift = cv.xfeatures2d.SIFT_create()

# 角點(diǎn)檢測:kp角點(diǎn)的信息包括坐標(biāo),方向等 des角點(diǎn)描述

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

# 繪制角點(diǎn)

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檢測算法

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

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

# 實(shí)例化fast對象

fast = cv.FastFeatureDetector_create(threshold=30)

# 檢測關(guān)鍵的

kp = fast.detect(tv,None)

# 繪制關(guān)鍵點(diǎn),默認(rèn)開啟非極大值抑制,抑制候選角點(diǎn)的重疊

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

# 關(guān)閉非極大值抑制

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("關(guān)閉非極大值抑制")

plt.show()

4.5 orb角點(diǎn)檢測

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

# 實(shí)例化ORB

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

orb = cv.ORB_create(nfeatures=200)

# 角點(diǎn)檢測

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

# 繪制角點(diǎn)

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對象,關(guān)閉視頻文件

video_ying.release()

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

cv.destroyAllWindows()

5.2 視頻保存

# 讀取視頻

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

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

frame_width = int(cap.get(3))

frame_height = int(cap.get(4))

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

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 視頻追蹤

目標(biāo):追蹤視頻中的小柯基

5.3.1 meanshift算法

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

import cv2 as cv

import numpy as np

# 視頻捕獲

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

# 獲取第一幀圖像,并指定目標(biāo)位置

ret, frame = video_dog.read()

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

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

track_window = (c, r, w, h)

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

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

# 計(jì)算直方圖

# 轉(zhuǎn)換色彩空間(HSV)

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

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

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

# 計(jì)算直方圖

# [0] 只計(jì)算第一個(gè)通道,即色調(diào)(hue)通道的直方圖

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

# [0,180] 計(jì)算從0到180之間的色調(diào)值的直方圖

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

# 歸一化

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

# 目標(biāo)追蹤

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

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

while True:

# 獲取每一幀圖像

ret, frame = video_dog.read()

if ret:

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

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

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

# 進(jìn)行Meanshift追蹤

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

# 追蹤的位置繪制在視頻上,并進(jìn)行顯示

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算法可以適應(yīng)目標(biāo)大小形狀的改變,具有較好的追蹤效果。但當(dāng)背景色和目標(biāo)顏色接近時(shí),容易使目標(biāo)的區(qū)域變大。

import cv2 as cv

import numpy as np

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

# 獲取第一幀圖像,并指定目標(biāo)位置

ret, frame = video_dog.read()

# 目標(biāo)位置

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

track_window = (c, r, w, h)

# 指定目標(biāo)區(qū)域

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

# 計(jì)算直方圖

# 轉(zhuǎn)換色彩空間(HSV)

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

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

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

# 計(jì)算直方圖

# [0] 只計(jì)算第一個(gè)通道,即色調(diào)(hue)通道的直方圖

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

# [0,180] 計(jì)算從0到180之間的色調(diào)值的直方圖

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

# 歸一化

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

# 目標(biāo)追蹤

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

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

while True:

ret, frame = video_dog.read()

if ret:

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

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)

# 將追蹤的位置繪制在視頻上,并進(jìn)行顯示

# pst矩形框的四個(gè)坐標(biāo)

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中自帶已訓(xùn)練好的檢測器,包括面部、眼睛等,都保存在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)

# 定義訓(xùn)練器路徑

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"

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

face_cas = cv.CascadeClassifier(cascade_path)

# 實(shí)例化眼睛級聯(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("檢測結(jié)果")

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)

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

face_cas = cv.CascadeClassifier(cascade_path)

# 實(shí)例化眼睛級聯(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()

由于運(yùn)行結(jié)果是視頻所以無法展示

柚子快報(bào)激活碼778899分享:OpenCV計(jì)算機(jī)視覺庫

http://yzkb.51969.com/

參考文章

評論可見,查看隱藏內(nèi)容

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

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

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

發(fā)布評論

您暫未設(shè)置收款碼

請?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問

文章目錄