人工智能綜合項目開發- 課件 第二章 OpenCV基礎_第1頁
人工智能綜合項目開發- 課件 第二章 OpenCV基礎_第2頁
人工智能綜合項目開發- 課件 第二章 OpenCV基礎_第3頁
人工智能綜合項目開發- 課件 第二章 OpenCV基礎_第4頁
人工智能綜合項目開發- 課件 第二章 OpenCV基礎_第5頁
已閱讀5頁,還剩63頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

人工智能綜合項目開發第二章OpenCV基礎成都職業技術學院OpenCV簡介01OpenCV安裝02圖像讀取與顯示03視頻的讀取與顯示04圖像基本操作05OpenCV

基礎OpenCV

簡介OpenCV(Open

Source

Computer

Vision

Library)是一個開源的跨平臺計算機視覺

和機器學習庫。擁有超過

2500

種優化算法,包括一套全面的、經典的和最先進的計算機

視覺和機器學習算法。這些算法可用于檢測和識別面部,識別物體,對視頻中的人體動

作進行分類,跟蹤相機移動,跟蹤移動物體等應用。OpenCV

其本身是用

C++編寫的,同時提供了

C++,Python,Java

MATLAB

程序接口,

并支持

Windows、Linux、Android、Mac

OS

等操作系統。如圖

0-1

所示,1999

Intel

公司為增強

CPU

集群性能,啟動了很多研究項目,其

中就包括

OpenCV。OpenCV

最初的核心代碼和算法規范是英特爾實驗室團隊完成的。2018

年發布了

OpenCV4.X

版本,該版本全面加強了算法的性能,補充了神經網絡等模塊功能。圖

0-1OpenCV

版本迭代歷史OpenCV

安裝Python

開發環境安裝

OpenCV

依賴包可使用如下命令安裝。pip3

instal

opencv-python

-i

/simple

--user使用

pip3,意思是在

python3

中安裝

opencv-python

庫,可以使用如下命令來查看

pip3

的版本號和

pip3

所對應的庫安裝路徑。-i

選項指定倉庫源,這使用豆瓣提供的

pip

源,用來加速下載。--user

選項指定是用戶安裝,避免出現權限不足的問題,而入致安裝失敗。pi@raspberrypi:~$

pip3

--versionpip

19.3.1

from

/usr/local/lib/python3.7/dist-packages/pip

(python

3.7)任注意

如果需要安裝指定版本的

opencv-python

庫。可以使用如下命令先查詢當前有多少版本可供安裝。pip3

install

opencv-python==報錯,然后提示可以從如下版本中選擇安裝。ERROR:

Could

not

find

a

version

that

satisfies

the

requirement

opencv-python==

(from

versions:

,

,

,

,

,

,

,

,

,

,

0,1,

2,

4,

5,

6,

7,

8,

9,

0,

7,

8,

9,

1,

3,

4,

5,

6,

0)比如,需要安裝

opencv-python

庫的

6

版本,則安裝命令如下:pip3

instal

opencv-python==6

-i

https:///simple

--user圖像讀取與顯示讀入、顯示和保存圖像和視頻數據是計算機視覺中最基本也是必不可少的操作,OpenCV

提供了這些基礎操作的

API

函數,通過本節內容,開發者可以掌握如何使用OpenCV

庫中的函數進行圖像和視頻的讀取、顯示和存儲。使用

OpenCV

庫的

imread

函數實現從磁盤中讀取一張圖像,使用函數

imshow

將它顯

示到

GUI

窗口中,圖像寫入使用

imwrite

函數。讀取、顯示與寫入圖像的流程如圖

0-1

所示:圖

0-1

圖像讀取顯示與寫入基本流程根據圖

4-2

流程,讀取一張圖片并顯示的示例代碼如下:import

cv2

as

cv#

自定義圖片地址

img_path

=

'./test_alpha.png'

#

讀入圖像img_bgr

=

cv.imread(img_path)

#

顯示圖片

cv.imshow('img_bgr',

img_bgr)

#

無限期的等待鍵盤按下

cv.waitKey(0)#銷毀所有窗體

cv.destroyAllWindows()#

存儲圖片,將圖片保存成

jpg

格式

cv.imwrite('./test.jpg',

img_bgr)通過上述代碼,可以將.png

格式的圖片另存為.jpg

格式的圖像,這是因為函數

imwrite()會根據文件名的后綴名來選擇不同的壓縮編碼方式,開發者只需更改文件后綴

名即可實現將圖像保存成不同的圖像格式。視頻的讀取與顯示OpenCV

為開發者提供了

CV2.VideoCapture

視頻捕獲類函數,這是一個通用的捕獲視頻圖像的程序接口。CV2.VideoCapture

視頻捕獲類函數如下表

4-1

所示:表

4-1

攝像頭捕獲構造類功能cv2.VideoCapture

類的構造函數參數說明視頻文件<VideoCaputrue

object>

=

cv2.VideoCapture(VideoPath)VideoPath:本地視頻文件路徑攝

備<VideoCaputrue

object>

=

cv2.VideoCapture(index)index:攝像頭設備

ID,填

0

表示

使用系統默認的攝像頭,在

linux

系統中,如果存在多個攝像頭,可

以使用“/dev/video1“

等這樣的

設備名通過構造函數可獲得

VideoCapture

類的實例對象,通過實例對象

VideoCapture

的成

員方法

read

讀取視頻幀。使用

OpenCV

捕獲視頻流非常容易,流程如下圖

0-1

所示:圖

0-1

視頻捕獲基本流程視頻流捕獲示例代碼如下:import

cv2

as

cv#獲取本地攝像頭對象

cap

=

cv.VideoCapture(0)

#如果檢測到攝像頭已打開

if

cap.isOpened():state,

frame

=

cap.read()

#抓取下一個視頻幀狀態和圖像while

state:#當抓取成功則進入循環state,frame

=

cap.read()

#

抓取每一幀圖像cv.imshow('video',frame)

#

顯示抓取到的圖像幀#

等待鍵盤按下,超時

25ms

可通過設置等待超時時間來控制視頻播放速度。k

=

cv.waitKey(25)

&

0xff

#

25ms

內當有鍵盤按下時返回對應按鍵

ASCII

碼,超時返回-1if

k

==

27

or

chr(k)

==

‘q’:

#

當按下

Esc

或者

q

時退出循環。break(1)視頻存儲視頻是由一幀一幀的圖像構成的,當一秒中內切換

24

幀圖像,人眼就會覺得視頻流暢,人們把一秒鐘切換圖像的次數叫做幀率(FPS),如一秒鐘能切換

30

張圖像,則其幀率為

30FPS。為了減少視頻大小,設計了很多視頻壓縮編碼格式,如常見的

MPEG-4、H.264、H.265。將視頻壓縮編碼之后,原來為

4.976

GB

的視頻文件就被壓縮到

50MB

以內,且畫質還原度高。在

OpenCV

中的

VideoWriter

類提供的

API

可以輕松實現視頻編碼壓縮。目前視頻信

息壓縮編碼的方法很多,fourcc

是用于設置壓縮幀的

4

字符編解碼方式代碼。視頻保存示例代碼如下:#!/usr/bin/env

python3

#

-*-

coding:UTF8

-*-

import

cv2

as

cv

import

numpy

as

np#獲取本地攝像頭對象

cap

=

cv.VideoCapture(0)#

指定視頻的編碼格式fourcc

=

cv.VideoWriter_fourcc(*

'XVID')

#

保存到文件,VideWriter

參數說明:#

VideWriter(文件名,

編碼格式,

FPS,

幀大小,isColor),isColor

默認為

True

表示保存彩圖

out

=

cv.VideoWriter('output.avi',

fourcc,

30,

(640,

480))while

cap.isOpened():

ret,

frame

=

cap.read()

if

ret:#

幀翻轉

圖像基本操作圖像運算指以圖像為單位進行的操作,該操作對圖像中的所有像素同樣進行,運算

的結果是一幅其灰度分布與原來參與運算圖像灰度分布不同的新圖像。具體的運算主要

包括算術和邏輯運算,它們通過改變像素的值來得到圖像增強的效果。算術運算是指對兩幅或兩幅以上的輸入圖像中對應像素的灰度值作加、減、乘或除

等運算后,將運算結果作為輸出圖像相應像素的灰度值。這種運算的特點在于:其一,

輸出圖像像素的灰度僅取決于兩幅或兩幅以上的輸入圖像的對應像素灰度值,和點運算out.write(frame)

#

保存視頻幀cv.imshow('frame',

frame)

#

顯示當前幀k

=

cv.waitKey(25)

&

0xFFif

chr(k)

==

'q':

#

按‘q’鍵退出break#

調用

release

函數釋放內存cap.release()out.release()cv.destroyAllWindows()相似,算術運算結果和參與運算像素的鄰域內像素的灰度值無關;其二,算術運算不會

改變像素的空間位置。(1)圖像按位運算圖像的基本運算有很多種,比如兩幅圖像可以相加、相減、相乘、相除、位運算、

平方根、對數、絕對值等。通常在圖像處理過程中需要對圖像截取其中的一部分作為感

興趣的區域(region

of

interest,ROI),按位運算常被廣泛用于

ROI

區域提取。所謂按位運算,就是對圖像像素的二進制形式的每個

bit

進行對應運算。按位運算

通常包括按位與、按位或、按位非和按位異或運算。OpenCV

提供了函數

cv2.

bitwise_and

能將兩幅圖像

src1

src2

每個像素值進行位

與運算,并返回處理后的圖像。該函數的用法如表

5-1

所示:表

5-1

位與函數函數名稱cv2.bitwise_and函數原型bitwise_and(src1,

src2[,

dst[,

mask]])

->

dst必填參數src1&src2:輸入的需要按位與的圖像,要求兩幅圖像有相同的類型和大小默認參數dst:與輸入圖像有同樣大小和類型的輸出圖像mask:輸入掩模,可省略參數,必須是

8

位單通道圖像返回值返回位與之后的圖像調用示例output

=

cv2.bitwise_and(source,

mask)函數

cv2.bitwise_not

將輸入圖像

src

每個像素值按位取反,并返回處理后的圖像。

該函數的用法如表

5-2

所示:表

5-2

位或函數函數名稱cv2.

bitwise_not函數原型bitwise_not(src[,

dst[,

mask]])

->

dst必填參數src:輸入的需要按位取反的圖像默認參數dst:與輸入圖像有同樣大小和類型的輸出圖像mask:輸入掩模,可省略參數,必須是

8

位單通道圖像返回值返回位與之后的圖像調用示例output

=

cv2.bitwise_not(source)(2)圖像加法OpenCV

提供了

cv2.add()函數實現圖像相加,使用該函數進行圖像的加法運算時,

相加的兩張圖像應保證

shape

一致。此外圖像的加法運算還可以通過

Numpy

實現,不同的)是

OpenCV

的加法是一種飽和操作,而

Numpy

中的加法是一種模操作,如下面代碼所示:

圖像加法函數中

cv2.addWeighted()函數能做圖像混合,函數的計算公式如下:

(

)

=

(

0(

)

1(

)

+因為兩幅圖片相加的權重不同,所以有混合的效果,通過修改

α

的值(0→1)便可

以實現非常好的混合效果,參考代碼如下所示:數字圖像顏色空間數字圖像中的灰度圖每一個像素都是由一個數字量化的,而彩色圖像的每一個像素

都是由至少三個數字進行量化,因此顏色空間的用途是保證在一個固定的標準下能夠對

某一種顏色加以說明量化。針對不同數字成像系統和領域各自的特點,目前已經存在上x=np.uint8([250])y=np.uint8([10])print(cv2.add(x,y)

#

OpenCV

實現圖像相加[[255]]

#

250+10=260=>255print(x+y)

#

Numpy

實現圖像相加[[4]]

#

250+10=260%256=4img=cv2.addWeighted(img1,

0.7,

img2,

0.3,

0)百種對彩色圖像色彩的量化方式,比較常用的三色顏色空間包括

RGB、HSV、Lab、YUV

等。RGB

色彩空間源于使用陰極射線管的彩色電視,是人們接觸最多的顏色空間之一。

RGB

分別代表三個基色(R-紅色、G-綠色、B-藍色),具體的色彩值由三個基色疊加而成。

在圖像處理中,常使用向量表示色彩的值,如(0,0,0)表示黑色、(255,

255,

255)

表示白色,其中,255

表示色彩空間被量化成

255

個數,最高亮度值為

255。在這個色彩

空間中,有

256*256*256

種顏色,因此

RGB

色彩空間是一個包含

Red、Green、Blue

的三

維空間。HSV(Hue-色調、Saturation-飽和度、Value-值)色彩空間將亮度從色彩中分解出

來,由于其對光線不敏感的特性,在圖像增強算法中用途很廣。在圖像處理中,經常將

圖像從

RGB

色彩空間轉換到了

HSV

色彩空間,利用

HSV

分量從圖像中提取

ROI

區域,以便

更好地感知圖像顏色。由于在圖像處理過程中,HSV

模型比

RGB

模型更適合做預處理,且日常生活中的顯示設備大多都是使用

RGB

顏色空間,因此常需將兩個顏色空間進行互換。OpenCV

中實現了顏色空間轉換的接口函數

cv2.cvtColor(),函數參數說明如表

5-3

所示:表

5-3

顏色空間轉換函數函數名稱cv2.cvtColor函數原型cvtColor(src,

code[,

dst[,

dstCn]])

->

dst必填參數src:輸入圖像code:顏色空間轉換類型,常用的是:

cv2.COLOR_BGR2HSV

cv2.COLOR_HSV2BGR

cv2.COLOR_BGR2GRAY

cv2.COLOR_GRAY2BGR默認參數dstCn:輸出圖像的顏色通道數,默認為

0,此時輸出圖像通道數將由

code

決定返回值轉換了顏色空間后的圖像調用示例hsv

=

cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

bgr

=

cv2.cvtColor(img,cv2.COLOR_HSV2BGR)(1)圖像通道拆分及合并如果對圖像的單個通道進行特殊操作,需要把

BGR

拆分成三個單獨的通道,操作完單個通道后,再將三個單獨的通道合并成一張

BGR

圖,如下所示為通道拆分及合并操作

示例:

使用

cv2.split()分割通道,cv2.merge()合并通道,這是一種有很大開銷的操作,

因此實際開發中建議使用如下代碼替代:

(2)顏色閾值分割在做顏色識別時,常需單獨提取出某一種顏色來做一些識別操作,這時候需要檢查

圖片元素是否在顏色高低閾值之間。OpenCV

中提供了

cv2.inRange()函數進行閾值分割,

這個函數根據上下顏色邊界閾值對原輸入圖像進行分割,上下閾值之外的像素全部設置b,g,r=cv2.split(img)img=cv2.merge((b,g,r))#

使用

python

切片來完成通道分割和替換功能b=img[:,:,:1]g=img[:,:,1:2]r=img[:,:,2:3]img[:,:,2:3]=rimg[:,:,1:2]=gimg[:,:,0:1]=b為

0,閾值之間的像素值設置為全

1,返回的是一個二值圖,即掩模。cv2.inRange()函數參數說明如表

5-4

所示:表

5-4

inRange

函數函數名稱cv2.inRange函數原型inRange(src,

lowerb,

upperb[,

dst])

->

dst必填參數src:輸入圖像lowerb:設置分割的下邊界閾值upperb:設置分割的上邊界閾值返回值返回顏色提取后的二值圖像,即掩模。調用示例mask=

cv2.inRange(hsv,

(0,

43,

46),

(10,

255,

255))因此,常使用

inRange

進行閾值處理操作,能達到分割指定顏色塊的目的。將圖像

轉化到

HSV

顏色空間下,然后參照表

5-5

所示

HSV

顏色空間對照表,即可根據顏色空間值

分割出指定顏色塊。表

5-5

HSV

顏色空間對照表黑灰白紅橙黃綠青藍紫hmin0000

15611263578100125hma/p>

18025347799124155smin00043434343434343smax2554330255255255255255255255vmin04622146464646464646vmax46220255255255255255255255255以分割綠色圖像為例,首先使用

inRange()函數來進行分割然后與原圖進行位與運算實現綠色分割,示例代碼如下所示:import

cv2

as

cv#

1)載入圖像img_src

=

cv.imread('rub00.jpg')#

2)轉換空間轉換hsv_src

=

cv.cvtColor(img_src,

cv.COLOR_BGR2HSV)#

3)查表可得綠色高低閾值green_low_hsv

=

(35,

43,

46)green_high_hsv

=

(77,

255,

255)#

4)分割顏色獲得掩模mask_green

=

cv.inRange(hsv_src,

green_low_hsv,

green_high_hsv)#

5)掩模和原圖進行位與green

=

cv.bitwise_and(hsv_src,hsv_src,mask

=

mask_green)green

=

cv.cvtColor(green,cv.COLOR_HSV2BGR)#

6)顯示圖像cv.imshow('src',

img_src)cv.imshow('mask_green',

green)

程序運行效果如圖

0-1

所示,將利用

inRange()函數,輸入綠色顏色空間閾值,將綠

色從原圖中分割開來。圖

0-1

綠色分割效果(3)數字圖像二值化在數字圖像處理中,圖像二值化(Image

Binarization)是指將圖像上的灰度值按

照某種方式設置為

0

255,得到一張黑白分明二值圖像的過程。在二值化圖像中,只存

在二種顏色黑色(0)和白色(maxval

最大值)。圖像二值化可以使邊緣變得更加明顯,

邊緣是指像素值急劇變化的地方,而

0

255

的跳變將使得邊緣信息更加突出,如圖

0-2cv.waitKey(0)cv.destroyAllWindows()所示。二值化圖像經常出現在圖像處理中,如掩模、圖像分割、輪廓查找等應用中。圖

0-2

數字圖像二值化二值化分為全局閾值二值化和自適應(局部)二值化。全局閾值二值化指根據自定

義閥值對圖像進行二值化處理,即灰度值大于閥值時設該像素灰度值為

255,灰度值小于

閾值時設該像素灰度值為

0。在

OpenCV

中,使用

cv2.threshold()函數實現簡單全局閾值

二值化,函數參數說明如表

5-1

所示:表

5-1

threshold

函數函數名稱cv2.threshold函數原型threshold(src,

thresh,

maxval,

type[,

dst])

->

retval,

dst必填參數src:傳入待二值化的灰度圖thresh:比較閾值(0-255)maxval:最大值(0-255)type:閾值處理方式cv2.THRESH_BINARY

超過閾值部分取

maxval(最大值),否則取

0

cv2.THRESH_BINARY_INV

THRESH_BINARY

的反轉

cv2.THRESH_TRUNC

大于閾值部分設為閾值,否則不變

cv2.THRESH_TOZERO

大于閾值部分不改變,否則設為

0

cv2.THRESH_TOZERO_INV

THRESH_TOZERO

的反轉默認參數無返回值返回兩個值

retval,

dst。retval

表示該次二值化使用的

thresh

值,dst

二值圖像調用示例ret,

thresh_binary

=

cv2.threshold(gray,

127,

255,

cv2.THRESH_BINARY)簡單閾值二值化是指設置一個全局閾值,用該閾值對灰度圖像素值進行歸類。具體

做法是,像素點灰度值小于等于閾值時將該點置

0(反轉置

maxval),大于閾值置

maxval(反轉置

0)。自適應閾值二值化同全局二值化有較大區別,全局二值化只使用一個全局閾值來對

圖像進行二值化處理,而自適應閾值使用每個塊中的平均值或加權平均值作為閾值。從數學角度上看自適應閾值較簡單閾值有更好的局部處理能力,從實際應用角度上看兩種

二值化算法各有優劣。簡單閾值勝在處理速度和某些特定場景的二值化表現更優,而自

適應閾值則在對局部過曝場景中二值化表現更優。因此在實際應用場景中需要根據場景

特點選擇合適的二值化處理函數,通常先使用全局閾值調參,效果不好再考慮使用自適

應閾值二值化。OpenCV

提供了函數

cv2.adaptiveThreshold()來實現自適應閾值二值化,函數參數說

明如表

5-2

所示:表

5-2

自適應閾值二值化函數名稱cv2.adaptiveThreshold函數原型adaptiveThreshold(src,

maxValue,

adaptiveMethod,

thresholdType,

blockSize,

C[,

dst])

->

dst必填參數src:傳入待二值化的灰度圖maxValue:最大值(0-255)adaptiveMethod:cv2.ADAPTIVE_THRESH_MEAN_C

值取自相鄰區域的平均值

cv2.ADAPTIVE_THRESH_GAUSSIAN_C

值取值相鄰區域的加權和

,權重為高斯

窗口thresholdType:閾值處理方式cv2.THRESH_BINARY

#超過閾值部分取

maxval(最大值),否則取

0

cv2.THRESH_BINARY_INV

THRESH_BINARY

的反轉

cv2.THRESH_TRUNC

#大于閾值部分設為閾值,否則不變

cv2.THRESH_TOZERO

#大于閾值部分不改變,否則設為

0

cv2.THRESH_TOZERO_INV

#THRESH_TOZERO

的反轉blockSize:鄰域大小

用來計算自適應閾值的區域大小C:常數

C,閾值等于平均值或者加權平均值減去這個常數默認參數無返回值返回值

dst

二值圖像調用示例dst

=

cv2.adaptiveThreshold(img,

255,cv2.ADAPTIVE_THRESH_MEAN_C,

cv2.THRESH_BINARY,

11,

2)對比全局閾值二值化和自適應閾值二值化效果如圖

0-3

所示,圖中左一為原灰度圖,右二為原灰度圖使用簡單閾值二值化圖,左三為原灰度圖使用自適應二值化圖,鄰域均值,右四為原灰度圖使用自適應二值化圖,高斯加權均值。圖

0-3

二值化結果對比圖像幾何變換幾何變換不改變圖像的像素值,只是在圖像平面上進行像素的重新安排。一個幾何

變換需要兩部分運算:首先是空問變換所需的運算,如平移、旋轉和鏡像等,需要用它

來表示輸出圖像與輸入圖像之間的像素映射關系;此外,還需要使用灰度插值算法,因為按照這種變換關系進行計算,輸出圖像的像素可能被映射到輸入圖像的非整數坐標上。(1)圖像平移平移是二維上空間的操作,是指將一個點或一整塊像素區域沿著

X、Y

方向移動指定

),可以使用如下矩

陣構建表示:使用如下代碼來構建平移描述矩陣:#

X

軸移動

100

個像素單位,Y

軸移動

50

個像素單位

M=np.float32([[1,0,100],

[0,1,50]])圖

0-4

圖像平移]在

OpenCV

中進行圖像平移操作,如圖

4-7,首先使用

Numpy

構建出一個平移描述矩

陣,然后將該矩陣作為參數傳遞到函數

cv2.warpAffine

中進行幾何變換,幾何變換函數

用法如表

5-3

所示:表

5-3

幾何變換函數函數名稱cv2.

warpAffine函數原型warpAffine(src,

M,

dsize[,

dst[,

flags[,

borderMode[,

borderValue]]]])

->

dst必填參數src:傳入待幾何變換的灰度圖或彩色圖M:幾何變換描述矩陣

如旋轉:M

=

cv2.getRotationMatrix2D((w

/

2,

h

/

2),

45,

.6)dsize:指定幾何變換后輸出圖像的(寬,高)默認參數flags:插值方式cv2.INTER_NEAREST

最鄰近插值,將離新像素所在位置最近的像素像素值賦值給新像素cv2.INTER_LINEAR

雙線性插值,

x、y

方向臨近像素取乘以相應權重并相加賦值給

i

新的像素值cv2.INTER_CUBIC

雙立方插值,

精度更高,計算量最大,取附近十六個點加權取像素值cv2.INTER_LANCZOS4

附近像素及原像素加權取值borderModer:填充模式BORDER_CONSTANT

=

0

borderValue

值填充邊界

BORDER_REPLICATE

=

1

拉伸填充BORDER_WRAP

=

3

溢出填充BORDER_DEFAULT

=

4

鏡像填充

BORDER_REFLECT

=

2

鏡像填充bordValue:邊界填充值

0-255返回值幾何變換后的圖像調用示例dst

=

cv2.warpAffine(img,

M,

(cols,

rows))圖像平移示例代碼:import

cv2import

numpy

as

np#

讀取圖片,路徑自定義img

=

cv2.imread("Resources/SunsetSea.png",

17)#

獲取圖片高寬imageInfo

=

img.shapeh

=

imageInfo[0]w

=

imageInfo[1]#

圖像平移array

=

np.array([[1,

0,

100],

[0,

1,

100]],

np.float32)dst

=

cv2.warpAffine(img,

array,

(w,

h))#

顯示原圖及平移后的圖像cv2.imshow("src

Image",

img)

程序運行結果如圖

0-5

所示圖

0-5

平移填充實驗結果(2)圖像縮放圖像縮放是指將一副圖像放大或縮小得到新圖像。對一張圖像進行縮放操作,可以

按照比例縮放,也可指定圖像寬高進行縮放。放大圖像即是對圖像矩陣進行拓展,而縮

小即是對圖像矩陣進行壓縮。放大圖像會增大圖像文件大小,同樣縮小圖像會減小文件

體積,如圖

0-6

所示:cv2.imshow("dst

Image",

dst)cv2.waitKey(0)圖

0-6

圖像縮放OpenCV

中提供了函數

cv2.resize

實現圖像縮放,詳細參數如表

5-6:表

5-6

圖像縮放函數函數名稱cv2.resize函數原型resize(src,

dsize[,

dst[,

fx[,

fy[,

interpolation]]]])

->

dst必填參數src:傳入待幾何變換的灰度圖或彩色圖dsize:指定幾何變換后輸出圖像的(寬,高)默認參數fxx:軸縮放比例fyy:軸縮放比例Interpolation:插值方式cv2.INTER_NEAREST

最鄰近插值,將離新像素所在位置最近的像素像素值賦值給新像素cv2.INTER_LINEAR

雙線性插值,

x、y

方向臨近像素取乘以相應權重并相加賦值給

i

新的像素值cv2.INTER_CUBIC

雙立方插值,

精度更高,計算量最大,取附近十六個點加

權取像素值cv2.INTER_LANCZOS4

附近像素及原像素加權取值返回值幾何變換后的圖像(3)圖像旋轉圖像旋轉是二維上空間的操作,是指將一塊區域的像素,以指定的中心點坐標,按

照逆時針方向旋轉到指定角度得到旋轉后的圖像。對圖像進行旋轉操作時需要預先構建

一個旋轉描述矩陣,指定旋轉中心點和旋轉的角度。圖

0-7

所示是旋轉

90

度的效果示意

圖:圖

0-7

圖像旋轉示意圖在

OpenCV

中進行圖像旋轉,需先構造出旋轉描述矩陣,構建旋轉描述矩陣函數參數說明如表

5-7

所示:表

5-7

構造旋轉描述矩陣函數名稱cv2.getRotationMatrix2D函數原型getRotationMatrix2D(center,

angle,

scale)

->

retval必填參數center:指定旋轉中心點angle:angle:旋轉角度(負數順時針旋轉,正數逆時針旋轉)scale:縮放因子,小于

1

縮小,

等于

1

不縮放,

大于

1

放大默認參數無返回值返回旋轉描述矩陣調用示例M

=

cv2.getRotationMatrix2D((w

/

2,

h

/

2),

45,

.6)構造好的旋轉描述矩陣后,將它傳遞到函數

cv.warpAffine

中進行幾何變換。圖像旋轉示例程序如下:

圖像旋轉實驗結果如圖

0-8

所示:import

cv2

as

cvimport

numpy

as

np#

讀取圖片img

=

cv2.imread("Resources/SunsetSea.png",

17)#

獲取圖片高寬imageInfo

=

img.shapeh

=

imageInfo[0]w

=

imageInfo[1]#

圖像旋轉rotate

=

cv2.getRotationMatrix2D((w

/

2,

h

/

2),

30,

.5)dst

=

cv2.warpAffine(img,

rotate,

(w,

h))#

結果顯示cv2.imshow("src

Image",

img)cv2.imshow("dst

Image",

dst)cv2.waitKey(0)cv.waitKey(0)圖

0-8

圖像旋轉(4)仿射變換仿射變換(affine

transform)是二維圖像上的線性變換加平移操作,如圖

0-9

示,Image1

先經過旋轉(線性變換),再進行縮放(線性變換),最后進行平移(向量

加)就可得到

Image2:圖

0-9

仿射變換圖

0-9

Image1

Image2

的轉變是仿射變換,原圖中所有的平行線在變換后的圖像中同樣平行。進行仿射變換需要先確定原圖中三個不共線的點,以及目標圖像中對應三點的映射

位置,使用函數

getAffineTransform()來構建仿射描述矩陣

M,將描述矩陣傳入函數

warpAffine()得到仿射變換目標圖像。仿射變換示例代碼如下所示:原圖變換的頂點

從左上角開始

逆時針方向填入

程序運行結果如圖

0-10

所示:pts1

=

np.float32([[50,

50],

[400,

50],

[50,

400]])#

目標圖像變換頂點

從左上角開始

逆時針方向填入pts2

=

np.float32([[100,

100],

[300,

50],

[100,

400]])#

構建仿射變換描述矩陣M

=

cv.getAffineTransform(pts1,

pts2)#

進行仿射變換dst

=

cv.warpAffine(img,

M,

(cols,

rows))圖

0-10

仿射變換結果(5)透視變換透視變換(perspective

transform)本質是將圖像投影到一個新的視平面,仿射變

換可理解為透視變換的一種特殊形式。仿射變換與透視變換在圖像還原、圖像局部變化

處理方面有重要意義。仿射變換是

2D

平面變換,透視變換時

3D

空間變換。仿射變換需要

先確定原圖中三個頂點坐標,而透視變換需要先確定原圖中四點坐標(任意三點不共

線)。下面給出透視變換示例代碼。

import

cv2

as

cvimport

numpy

as

np#

讀取原圖img

=

cv.imread('./sudoku.jpg')h,

w,

c

=

img.shape

print(h,

w)#

首先確定原圖中四點坐標pts1

=

np.float32([(56,

65),

(28,

387),

(389,

390),

(368,

52)])

pts2

=

np.float32([(0,

0),

(0,

h),

(w,

h),

(w,

0)])M

=

cv.getPerspectiveTransform(pts1,

pts2)

dst

=

cv.warpPerspective(img,

M,

(w,

h))#

在原圖中標記這些頂點cv.circle(img,

tuple(pts1[0]),

1,

(0,

255,

255),

cv.LINE_AA)

cv.circle(img,

tuple(pts1[1]),

1,

(255,

0,

255),

cv.LINE_AA)

cv.circle(img,

tuple(pts1[2]),

1,

(255,

255,

255),

cv.LINE_AA)

cv.circle(img,

tuple(pts1[3]),

1,

(0,

0,

0),

cv.LINE_AA)#

在目標圖中標記頂點cv.circle(dst,

tuple(pts2[0]),

1,

(0,

255,

255),

cv.LINE_AA)

cv.circle(dst,

tuple(pts2[1]),

1,

(255,

0,

255),

cv.LINE_AA)

cv.circle(dst,

tuple(pts2[2]),

1,

(255,

255,

255),

cv.LINE_AA)

cv.circle(dst,

tuple(pts2[3]),

1,

(0,

0,

0),

cv.LINE_AA)#

結果顯示

cv.imshow('img',

img)

cv.imshow('dst',

dst)

程序運行結果如圖

0-11

所示:圖

0-11

透視變換結果對比(左原圖,右為變換后的圖)透視變換常用于車牌矯正,車牌矯正需要找到車牌區域四個頂點坐標,左上記為點

A,

右上記為點

B,左下記為點

C,右下記為點

D。假設原圖中四點坐標為

A(88,

92)、B(218,118)、C(84,125)、D(211,

160)。

x

y

為x_min,x_max,y_min,y_max,四個頂點坐標映射坐標為

A(x_min,y_min)、B(x_max,

y_min)、C(x_min,

y_max)、D(x_max,y_max)。車牌矯正參考代碼如下:cv.waitKey(0)cv.destroyAllWindows()

最終矯正效果如圖

0-12

所示:圖

0-12

透視變換傾斜矯正形態學操作(1)腐蝕圖像腐蝕也即是“收縮”或“細化”二值圖像中的對象。如圖

4-16

所示,假設用一#

原圖中車牌四頂點坐標pts1

=

np.float32([(88,

92),

(218,

118),

(84,

125),

(211,

160)])#

矯正后車牌四頂點坐標pts2

=

np.float32([(88,

118),

(218,

118),

(88,

160),

(218,

160)])#

構建透視變換描述矩陣M

=

cv.getPerspectiveTransform(pts1,

pts2)#進行透視變換——圖像校正dst

=

cv.warpPerspective(img,

M,

(w,

h))個

3X3

的全一矩陣去腐蝕一張灰度圖,中心錨點的值就會被替換為對應核中最小的值。圖

4-16

腐蝕原理OpenCV

中使用函數

cv2.erode

來進行腐蝕操作。cv2.erode

函數參數說明如下表

4-12

所示:表

4-12

腐蝕函數函數名稱cv2.erode函數原型erode(src,

kernel[,

dst[,

anchor[,

iterations[,

borderType[,

borderValue]]]]])

->

dst必填參數src:指定要腐蝕的灰度圖或二值化圖像kernel:腐蝕操作的內核。

如果該參數不指定,默認為一個簡單的

3x3

使

getStructuringElement()獲取結構化元,也可以指定自定義腐蝕核。默認參數anchor:錨點,默認為-1

表示內核中心點,省略時為默認值iterations

迭代次數。省略時為默認值

1borderType:推斷邊緣類型,具體參見

borderInterpolate

函數。默認值為

邊緣值拷貝borderValue:邊緣填充值,具體可參見

createMorphoogyFilter

函數,可

省略返回值返回腐蝕操作后的結果圖像調用示例kernel

=

np.ones((3,

3),

np.uint8)

erosion

=

cv2.erode(img,

kernel,

iterations

=

1)圖像腐蝕會使白色區域的邊緣像素值減小,從而使白色區域的面積減少。迭代次數

越多腐蝕效果越明顯,內核大小越大腐蝕效果越明顯。因此腐蝕可以用來去除圖像中細

小的白色區域,可以用來斷開連接在一起的的白色區域塊,腐蝕會明顯減少白色區域面

積。多次腐蝕效果如圖

4-17

所示:圖

4-17

連續腐蝕效果(2)膨脹與腐蝕操作相反,膨脹是在二值圖像中“加長”或“變粗”的操作,如圖

4-18

所示,

使用一個

3X3

的全一矩陣去膨脹一張灰度圖,中心錨點的值就會被替換為對應核中最大

的值。圖

4-18

膨脹原理因此膨脹的效果是增大白色區域的面積,其原理是在原圖的小區域內取局部最大值。OpenCV

中使用函數

cv2.dilate

來進行膨脹操作,其參數說明如表

4-13

所示:表

4-13

膨脹原理函數名稱cv2.dilate函數原型dilate(src,

kernel[,

dst[,

anchor[,

iterations[,

borderType[,

borderValue]]]]])

->

dst必填參數src:指定要膨脹的灰度圖或二值化圖像,彩色圖像也可以,但一般不這么做kernel:膨脹操作的內核。

如果不指定,默認為一個簡單的

3x3

全一矩陣,否則,就要明確指定它的形狀,可以使用函數

getStructuringElement()獲取結構化元,也可以指定自定義膨脹核默認參數anchor:錨點,默認為-1

表示內核中心點,省略時為默認值iterations:迭代次數。省略時為默認值

1borderType:推斷邊緣類型,具體參見

borderInterpolate

函數。默認值為邊緣值拷貝borderValue:邊緣填充值,具體可參見

createMorphoogyFilter

函數,可省略返回值返回膨脹操作后的結果圖像調用示例kernel

=

np.ones((3,

3),

np.uint8)dilate

=

cv2.dilate(img,

kernel,

iterations=1)膨脹會使白色區域的邊緣像素值增大,從而使白色區域的面積減增大。膨脹迭代次

數越多膨脹效果越明顯,內核大小越大膨脹效果越明顯。因此,膨脹可以用來去除圖像

中細白色區域內細小的空洞,可以用來連接斷在了的白色區域,膨脹明顯增加白色區域

面積。多次膨脹效果如圖

4-19

所示。圖

4-19

多次膨脹效果圖像濾波圖像濾波,即在盡量保留圖像細節特征的條件下對目標圖像的噪聲進行抑制,是圖

像預處理中不可缺少的操作,其處理效果的好壞將直接影響到后續圖像處理和分析的有

效性和可靠性。(1)均值濾波均值濾波是平滑線性濾波器中的一種,具有平滑圖像過濾噪聲的作用。均值濾波的

思想即使用濾波器模板

w

所包含像素的平均值去覆蓋中心錨點的值。在

OpenCV

中可以使用函數

cv2.blur

cv2.boxFilter

做均值濾波,這兩個函數的詳細用法如表

4-14

和表

4-15

所示:表

4-14

均值濾波函數

blur函數名稱cv2.blur函數原型blur(src,

ksize[,

dst[,

anchor[,

borderType]]])

->

dst必填參數src:傳入待濾波的圖像彩色圖或單通道圖ksize:模板大小

如(3,3)表示

3X3

模板默認參數anchor:錨點;默認值

Point(-1,-1)表示錨位于內核中央borderType:borderType:邊框模式用于圖像外部的像素,

默認邊緣像素拷貝返回值均值濾波后的圖像調用示例blur

=

cv.blur(img,

(3,

3))表

4-15

均值濾波函數

boxFilter函數名稱cv2.boxFilter函數原型boxFilter(src,

ddepth,

ksize[,

dst[,

anchor[,

normalize[,

borderType]]]])

->

dst必填參數src:傳入待濾波的圖像彩色圖或單通道圖ddepth:指定輸出圖像深度,-1

表示與

src

深度保持一致ksize:模板大小

如(3,3)表示

3X3

模板默認參數anchor:錨點:默認值

Point(-1,-1)表示錨位于內核中央normalize:normalize

flag,指定內核是否按其區域進行規范化borderType:borderType:邊框模式用于圖像外部的像素,

默認邊緣像素拷貝返回值濾波后的圖像調用示例blur_b

=

cv2.boxFilter(img,

-1,

(3,

3))均值濾波公式如下:}對原始圖像稍顯模糊使用

5X5

模板進行均值濾波,對于尺寸稍小的亮點,使用均值

濾波后亮度明顯降低;對于尺寸非常小的亮點,使用均值濾波后亮點消失融入背景,如

4-20

所示:圖

4-20

5X5

均值濾波結果對原始圖像十分模糊使用

9X9

模板進行均值濾波,對于尺寸較大的亮點,濾波后亮

度明顯降低;對于尺寸稍小的亮點,濾波后亮點消失融入背景,如圖

4-21

所示:圖

4-21

9X9

均值濾波最后使用不同大小的模板,對同一張圖進行均值濾波實驗,實驗效果如圖

4-22

所示:圖

4-22

不同尺寸均值濾波結果對比根據上述實驗可知,均值濾波能夠消除小尺寸圖像亮點。同時濾波器模板尺寸越大,

濾波后的圖像越模糊/平滑,但也越模糊,因此,在實際應用中,應選擇合適大小的濾波

器模板進行圖像濾波。(2)中值濾波中值濾波是一種基于統計排序的非線性濾波器,能有效抑制噪聲,如非線性噪聲,

平滑其它非脈沖噪聲,減少物體邊界細化或粗化的失真。與線性濾波器均值濾波相比,

均值無法消除椒鹽噪聲,中值濾波卻可以輕松去除。中值濾波容易斷開圖像中的縫隙,

如字符縫隙,均值濾波可以連通圖像中的縫隙。中值濾波計算原理如圖

4-23

所示:圖

4-23

中值濾波原理中值濾波計算方法為:濾波輸出像素點

g(x,

y)

=

濾波模板

domain

定義的排列集合

的中值。使用中值濾波時需要注意以下幾點:濾波模板

domain

的中心與像素點

f(s,

y)重合;濾波器模板

domain

0/1

矩陣,與

domain

中元素

1

對應的像素才參與排序;對參與排序的像素點進行升序排序,g(x,y)=排序集合的中值。在

OpenCV

中使用

cv2.medianBlur

來進行中值濾波去除椒鹽噪聲,函數參數說明如表

4-16

所示:表

4-16

中值濾波函數函數名稱cv2.medianBlur函數原型medianBlur(src,

ksize[,

dst])

->

dst必填參數src:傳入待濾波的圖像彩色圖或單通道圖ksize:模板大小

傳一個正奇數,而不是一個元組默認參數無返回值中值濾波后的圖像調用示例blur_b

=

cv2.

medianBlur(img,

3)中值濾波能有效去除椒鹽噪聲,椒鹽噪聲也稱脈沖噪聲,是一種隨機出現的白點或

者黑點。椒鹽噪聲的成因可能是影像訊號受到突如其來的強烈干擾而產生。中值濾波去除椒鹽噪聲實驗結果如圖

4-24

所示:圖

4-24

不同尺寸中值濾波結果對比根據實驗結果可知,中值濾波能高效濾除椒鹽噪聲,如椒鹽白噪聲、椒鹽黑噪聲和

其他脈沖噪聲,如類似老式電視雪花噪點,但同時也容易丟失圖像邊緣信息,造成圖像

縫隙,如

OCR

中斷開單字符連通,當使用較大核濾波時容易誤將真實邊界當作噪聲去除。使用中值濾波函數

cv.medianBlur()時,值得注意的是核大小需是一個正奇數,不能

是一個元組。圖

4-25

是中值濾波案例運行的效果圖,可以看到圖片經過中值濾波降噪后變得更清

晰。圖

4-25

中值濾波降噪(3)高斯濾波高斯濾波和均值濾波很相似,均值濾波是計算鄰域內所有像素灰度的平均值或加權

平均值,然后去替換中心點的像素值。高斯濾波是計算鄰域內所有像素灰度的高斯加權

平均值,然后去替換中心點的像素。二者的主要區別在于鄰域權重值的分布,高斯濾波

權重值符合正態分布,均值濾波權重不符合正態分布。高斯濾波計算方法如圖

4-26

所示:圖

4-26

高斯濾波原理高斯濾波計算規則如下:a.

高斯運算結果

=

高斯權重矩陣

*

對應像素矩陣;

b.

對應像素矩陣錨點

=

高斯運算結果矩陣求和;

c.

邊界點默認的處理方式是邊緣拷貝。在

OpenCV

中使用函數

cv2.GaussianBlur

進行高斯濾波,函數參數說明如表

4-17

所示:表

4-17

高斯濾波函數函數名稱cv2.

GaussianBlur函數原型GaussianBlur(src,

ksize,

sigmaX[,

dst[,

sigmaY[,

borderType]]])

->

dst必填參數src:傳入待濾波的圖像彩色圖或單通道圖ksize:高斯內核大小sigmaX:高斯核函數在

X

方向上的正態分布標準偏差默認參數sigmaY:高斯核函數在

Y

方向上的標準偏差,如果

sigmaY

0,會自動將

sigmaY

的值設置為與

sigmaX

相同的值borderType:borderType:邊框模式用于圖像外部的像素,

默認邊緣像素拷貝返回值濾波后的圖像調用示例g_blur

=

cv2.GaussianBlur(img,

(kw,

kh),

0.1,

0.2)使用不同的高斯核大小,進行高斯濾波結果如圖

4-27

所示:圖

4-27

去除高斯型噪聲對比結果根據圖

4-27

可知,高斯濾波只能去除高斯噪聲,無法去除椒鹽噪聲、脈沖噪聲;高斯濾波在使用較大高斯內核時,降噪能力明顯加強,但模糊效果

卻沒有明顯增強,這使得在使用大核時也可以較好的保存邊界信息。高斯小核過濾小尺寸高斯噪聲,大核過濾較大尺寸噪聲。隨著核大小增大,降噪能力增強。但邊緣信息依然能得到較好的保留。圖像邊緣檢測與輪廓提取圖像輪廓是指具有相同顏色或灰度值的連續點連接在一起的曲線,對圖像的輪廓進

行檢測在形狀分析和物體識別應用場景中十分重要。圖像輪廓檢測方法通常需定義亮度、

顏色等特征的低層突變,通過標識圖像中亮度變化明顯的點來完成邊緣檢測。邊緣檢測

通常將圖像與微分算子卷積,比如借助于

Sobel

算子和

Canny

算子等,但此方法沒有考慮

視覺中層和高層信息,因此在含有大量噪聲或者紋理的情況下,難得出完整的目標輪廓。檢測圖像中物體輪廓的過程主要有以下四個步驟:步驟

1:首先對輸入圖像做預處理,通用的方法是采用較小的二維高斯模板做平滑濾

波處理,去除圖像噪聲,采用小尺度的模板是為了保證后續輪廓定位的準確性。因為大

尺度平滑往往會入致平滑過渡,從而模糊邊緣,影響邊緣檢測效果。步驟

2:對平滑后的圖像做邊緣檢測處理,利用亮度、顏色等可以區分物體與背景的

可用梯度特征信息,得到初步的邊緣圖像。步驟

3:對邊緣響應做進一步處理,得到更好的邊緣響應圖像。這個過程通常會涉及

到判據,即對輪廓點和非輪廓點做出不同處理達到區分輪廓點和非輪廓點的效果,從而

得到可以作為輪廓的邊緣圖像。步驟

4:根據上一步驟檢測到的輪廓進行精確的定位,最后確定圖像輪廓。因為在實

際應用過程中,上一步驟得到的輪廓檢測結果往往是不盡人意的,因此需要對其再進行

精確地篩選定位。OpenCV

提供了圖像輪廓檢測函數

cv2.findContours(),以及圖像輪廓繪制函數

cv2.

drawContours(),函數參數說明分別如下表

4-18

所示:表

4-18

圖像輪廓查找函數函數名稱cv2.findContours函數原型findContours(image,

mode,

method[,

contours[,

hierarchy[,

offset]]])

->

contours,

hierarchy必填參數image:傳入二值化圖像或邊緣檢測算子計算結果圖像mode:輪廓檢查模式,有四個可選的值

cv2.RETR_EXTERNAL

表示只提取最外面的輪廓;

cv2.RETR_LIST

表示提取所有輪廓并將其放入列表;cv2.RETR_CCOMP

表示提取所有輪廓并將組織成一個兩層結構,其中頂層輪廓是外部輪廓,第二層輪廓是“洞”的輪廓;

cv2.RETR_TREE:表示提取所有輪廓并組織成輪廓嵌套的完整層級結構。method:輪廓的近似方法,有四個可選擇值cv2.CHAIN_APPROX_NONE

獲取每個輪廓的每個像素,相鄰的兩個點的像素位置差不超過

1;cv2.CHAIN_APPROX_SIMPLE

壓縮水平方向,垂直方向,對角線方向的元素,值保留該方向的重點坐標,如果一個矩形輪廓只

4

個點來保存輪廓信息;cv2.CHAIN_APPROX_TC89_L1

cv2.CHAIN_APPROX_TC89_KCOS

使用

Teh-Chinl

鏈逼近算法中的一種。返回值舊版

API

返回三個值,新版兩個值。contours

存儲著查找的的輪廓,hierarchy

存儲著查找的輪廓層次關系。調用示例contours,

hierarchy

=

cv2.findContours(thresh,

cv2.RETR_TREE,

cv2.CHAIN_APPROX_SIMPLE)[-2:]圖像輪廓繪制函數如表

4-19:表

4-19

輪廓繪制函數函數名稱cv2.drawContours函數原型drawContours(image,

contours,

contourIdx,

color[,

thickness[,

lineType[,

hierarchy[,

maxLevel[,

offset]]]]])

->

image必填參數image:繪制輪廓的目標圖像,該函數會修改

image

值,經過該函數處理后,返回值

return_image

image

相同。

如果需要保存原圖信息,請使用

copycontours:所有的輪廓,是一個

Python

列表contourIdx:輪廓的索引,為-1

時表示繪制

contours

里的所有color:繪制輪廓時使用的顏色默認參數thickness:繪制輪廓的線條寬度,為-1

時表示填充輪廓內部lineType:線條的類型hierarchy:層次結構信息,與函數

findcontours()的

hierarchy

有關maxLevel:

0,

1,

(nested

contours);若為

2,則繪制該輪廓、嵌套輪廓(nested

contours)/子輪廓和嵌套-嵌套輪廓(all

the

nested-to-

nested

contours)/孫輪廓,等等。該參數只有在層級結構時才用到。offset

:按照偏移量移動所有的輪廓(點坐標)返回值繪制了輪廓的目標圖像調用示例drawing1

=

cv2.drawContours(src.copy(),

contours,

-1,

(0,

255,

0),

thickness=2,

lineType=cv.LINE_AA)利用如下代碼將檢測出來的所有輪廓繪制到原圖中,效果如圖

4-28

所示:drawing1

=

cv.drawContours(src.copy(),

contours,

-1,

(0,

255,

0),

thickness=2,

lineType=8)圖

4-28

圖像輪廓繪制將輪廓繪制到掩模中,示例代碼如下:

程序運行效果如圖

4-29

所示:圖

4-29

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論