<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【CV】OpenCV 入門(mén)之旅

          共 4937字,需瀏覽 10分鐘

           ·

          2021-12-09 15:39

          OpenCV 是一個(gè)強(qiáng)大的圖片處理工具,尤其是隨著人工智能、圖片識(shí)別等行業(yè)的興起,這個(gè)第三方庫(kù)也越來(lái)越受到重視,今天我們就一起來(lái)開(kāi)啟 OpenCV 之旅

          計(jì)算機(jī)視覺(jué)

          我們先來(lái)看下到底什么是計(jì)算機(jī)視覺(jué)

          其實(shí)這個(gè)是一個(gè)比較大的問(wèn)題了,我們先來(lái)簡(jiǎn)化下問(wèn)題,思考如下場(chǎng)景

          相信很多朋友都會(huì)使用微博來(lái)曬出自己的旅游照片,當(dāng)然照片中會(huì)包含自己和家人朋友等等。那么該怎么快速的識(shí)別出照片中不同的人并標(biāo)注出來(lái)呢,這個(gè)時(shí)候就可以用到計(jì)算機(jī)視覺(jué)的知識(shí)了

          計(jì)算機(jī)視覺(jué)是一個(gè)跨學(xué)科領(lǐng)域,涉及如何使計(jì)算機(jī)從數(shù)字圖像或視頻中獲得高級(jí)別的理解,并使得計(jì)算機(jī)能夠識(shí)別諸如人臉、燈柱甚至雕像之類的物體

          計(jì)算機(jī)如何讀取圖像

          比如說(shuō)下面這張圖片,計(jì)算機(jī)是怎么展示的呢

          計(jì)算機(jī)會(huì)將任何圖像讀取為 0 到 255 之間的范圍值

          對(duì)于任何彩色圖像,都有 3 個(gè)主要通道——紅色綠色藍(lán)色,它的工作原理非常簡(jiǎn)單:

          為每種原色形成一個(gè)矩陣,然后這些矩陣組合起來(lái)為各個(gè) R、G、B 顏色提供像素值,然后矩陣的每個(gè)元素提供與像素亮度強(qiáng)度有關(guān)的數(shù)據(jù)

          文字有些抽象,我們來(lái)看下面這張圖片

          如圖所示,此處圖像的大小可以計(jì)算為 B x A x 3

          注意:對(duì)于黑白圖像,只有一個(gè)通道

          了解了前置基礎(chǔ)知識(shí)后,接下來(lái)讓我們看看 OpenCV 到底是什么

          OpenCV 是什么

          OpenCV 是一個(gè) Python 庫(kù),用于解決計(jì)算機(jī)視覺(jué)問(wèn)題。OpenCV 最初由 Intel 于 1999 年開(kāi)發(fā),后來(lái)得到 Willow Garage 的支持,從而發(fā)展的更加迅速

          OpenCV 支持多種編程語(yǔ)言,如 C++、Python、Java 等,同時(shí)也支持多種平臺(tái),包括 Windows、Linux 和 MacOS

          OpenCV Python 只不過(guò)是與 Python 一起使用的原始 C++ 庫(kù)的包裝類,所有 OpenCV 數(shù)組結(jié)構(gòu)都會(huì)被轉(zhuǎn)換為 NumPy 數(shù)組

          這使得 OpenCV 更容易與其他使用 NumPy 的庫(kù)集成,例如,SciPy 和 Matplotlib 等

          接下來(lái)讓我們看看使用 OpenCV 執(zhí)行的一些基本操作

          OpenCV 基本操作

          載入圖像

          Import?cv2

          #?彩色圖片

          Img?=?cv2.imread?(Penguins.jpg,1)


          #?黑白圖片

          Img_1?=?cv2.imread?(Penguins.jpg,0)

          如上一段代碼所示,首先我們需要導(dǎo)入 OpenCV 模塊

          然后我們可以使用 imread 模塊讀取圖像,參數(shù)中的1表示是彩色圖像。如果該參數(shù)為 0 而不是 1,則表示導(dǎo)入的圖像是黑白圖像

          圖像形狀/分別率

          我們可以利用 shape 子函數(shù)來(lái)打印出圖像的形狀

          Import?cv2

          Img?=?cv2.imread?(Penguins.jpg,0)

          Print(img.shape)

          圖像的形狀是指 NumPy 數(shù)組的形狀,從執(zhí)行代碼可以看出,矩陣由 768 行和 1024 列組成

          展示圖像

          import?cv2

          Img?=?cv2.imread(Penguins.jpg,0)

          cv2.imshow(Penguins,?Img)

          cv2.waitKey(0)

          #?cv2.waitKey(2000)

          cv2.destroyAllWindows()

          我們首先使用 imread 導(dǎo)入圖像

          接下來(lái)使用 imshow 函數(shù)通過(guò)打開(kāi)一個(gè)窗口來(lái)顯示圖像,imshow 函數(shù)有兩個(gè)參數(shù),分別是窗口的名稱和要顯示的圖像對(duì)象

          然后我們等待用戶事件,waitKey 使窗口保持靜態(tài),直到用戶按下某個(gè)鍵,傳遞的參數(shù)是以毫秒為單位的時(shí)間

          最后,我們使用 destroyAllWindows 根據(jù) waitForKey 參數(shù)關(guān)閉窗口

          調(diào)整圖像大小

          調(diào)整圖像大小也很容易

          import?cv2

          img?=?cv2.imread(Penguins.jpg,0)

          resized_image?=?cv2.resize(img,?(650,500))

          cv2.imshow(Penguins,?resized_image)

          cv2.waitKey(0)

          cv2.destroyAllWindows()

          在這里,resize 函數(shù)用于將圖像調(diào)整為所需的形狀,這里的參數(shù)是新調(diào)整大小的圖像的形狀

          我們注意到,圖像對(duì)象從 img 變?yōu)?resized_image,因?yàn)楝F(xiàn)在圖像對(duì)象發(fā)生了變化

          還有另一種方法可以將參數(shù)傳遞給 resize 函數(shù)

          Resized_image?=?cv2.resize(img,?int(img.shape[1]/2),?int(img.shape[0]/2)))

          這樣,我們得到的新圖像形狀會(huì)是原始圖像形狀的一半

          接下來(lái)讓我們進(jìn)入實(shí)戰(zhàn)部分,使用 OpenCV 執(zhí)行人臉檢測(cè)

          人臉檢測(cè)

          人臉檢測(cè)?乍一看似乎很復(fù)雜,但是通過(guò) OpenCV 就非常容易了,只需要三步走即可!

          第 1 步:我們首先拿到一個(gè)圖像,然后創(chuàng)建一個(gè)級(jí)聯(lián)分類器,它最終會(huì)給出我們?nèi)四樀奶卣?/p>

          第 2 步:這一步涉及使用 OpenCV,它將讀取圖像和特征文件,主要就是操作 NumPy 數(shù)組

          我們需要做的就是搜索人臉 NumPy ndarray 的行和列值,這是帶有人臉矩形坐標(biāo)的數(shù)組

          第 3 步:使用矩形人臉框顯示圖像

          首先,我們創(chuàng)建一個(gè) CascadeClassifier 對(duì)象來(lái)提取人臉的特征,參數(shù)就是包含面部特征的 XML 文件的路徑

          下一步是讀取帶有人臉的圖像,并使用 COLOR_BGR2GREY 將其轉(zhuǎn)換為黑白圖像,接著,我們搜索圖像的坐標(biāo),這是使用 detectMultiScale 來(lái)完成的

          什么是坐標(biāo)呢?就是面部矩形的坐標(biāo)。scaleFactor 用于將形狀值減少 5%,直到找到人臉。因此,總的來(lái)說(shuō) -- 值越小,準(zhǔn)確性越高

          最后展示圖像

          添加人臉框

          一個(gè)比較簡(jiǎn)單的邏輯處理

          我們定義了使用 cv2.rectangle 通過(guò)傳遞圖像對(duì)象、框輪廓的 RGB 值和矩形的寬度等參數(shù)來(lái)創(chuàng)建矩形的方法。

          讓我們看看人臉檢測(cè)的完整代碼:

          import?cv2

          #?Create?a?CascadeClassifier?Object
          face_cascade?=?cv2.CascadeClassifier("haarcascade_frontalface_default.xml")

          #?Reading?the?image?as?it?is
          img?=?cv2.imread("photo.jpg")

          #?Reading?the?image?as?gray?scale?image
          gray_img?=?cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

          #?Search?the?co-ordintes?of?the?image
          faces?=?face_cascade.detectMultiScale(gray_img,?scaleFactor?=?1.05,minNeighbors=5)
          for?x,y,w,h?in?faces:
          ????img?=?cv2.rectangle(img,?(x,y),?(x+w,y+h),(0,255,0),3)

          resized?=?cv2.resize(img,(int(img.shape[1]/7),int(img.shape[0]/7)))

          cv2.imshow("Gray",?resized)

          cv2.waitKey(0)

          cv2.destroyAllWindows()

          接下來(lái)看看如何使用 OpenCV 捕獲帶有計(jì)算機(jī)網(wǎng)絡(luò)攝像頭的視頻

          使用 OpenCV 捕獲視頻

          使用 OpenCV 捕獲視頻也非常簡(jiǎn)單

          一張一張地讀取圖像,由于幀的快速處理已經(jīng)我們眼睛的機(jī)制(生物學(xué)范疇?)使單個(gè)圖像移動(dòng)起來(lái),就生成了視頻

          首先,我們先導(dǎo)入 OpenCV 庫(kù),接下來(lái)我們使用一個(gè)名為 VideoCapture 的方法,用于創(chuàng)建 VideoCapture 對(duì)象,該方法用于觸發(fā)用戶機(jī)器上的攝像頭。此函數(shù)的參數(shù)表示程序應(yīng)使用內(nèi)置攝像頭還是附加攝像頭,“0”表示內(nèi)置攝像頭

          最后的釋放方法用于在幾毫秒內(nèi)釋放系統(tǒng)相機(jī)

          但是當(dāng)我們嘗試執(zhí)行上面的代碼時(shí),會(huì)注意到相機(jī)燈亮起一秒鐘然后關(guān)閉這是因?yàn)闆](méi)有時(shí)間延遲來(lái)保持相機(jī)功能

          我們來(lái)增加延遲

          我們?cè)黾恿?秒鐘的延遲,網(wǎng)絡(luò)攝像頭將開(kāi)啟 3 秒鐘

          添加一個(gè)窗口來(lái)顯示視頻輸出

          在這里,我們定義了一個(gè) NumPy 數(shù)組,我們用它來(lái)表示視頻捕獲的第一張圖像——存儲(chǔ)在幀數(shù)組中

          我們還有一個(gè) check 變量——這是一個(gè)布爾數(shù)據(jù)類型,如果 Python 能夠訪問(wèn)和讀取 VideoCapture 對(duì)象,那么它返回 True

          下面是代碼的輸出情況

          我們得到的輸出為 True,并打印了幀數(shù)組的一部分

          但是我們需要從讀取視頻的第一幀開(kāi)始,以此,我們需要首先創(chuàng)建一個(gè)幀對(duì)象,它將讀取 VideoCapture 對(duì)象的圖像

          如上所示, imshow 方法用于捕獲視頻的第一幀

          直接捕獲視頻

          為了捕獲視頻,我們將使用 while 循環(huán)

          我們使用 cvtColor 函數(shù)將每一幀轉(zhuǎn)換為灰度圖像

          waitKey(1) 將確保在每毫秒間隔后生成一個(gè)新幀

          這里還有一個(gè)用戶事件觸發(fā)器,一旦用戶按下“q”鍵,程序窗口就會(huì)關(guān)閉

          下面我們看看如何使用 OpenCV 做一個(gè)非常有趣的運(yùn)動(dòng)檢測(cè)器

          基于 OpenCV 的運(yùn)動(dòng)檢測(cè)器

          問(wèn)題場(chǎng)景:通過(guò)一個(gè)網(wǎng)絡(luò)攝像頭,可以檢測(cè)到攝像頭前任何運(yùn)動(dòng)物體,并且返回一個(gè)圖表,這個(gè)圖表包含人/物體在相機(jī)前面的時(shí)間

          問(wèn)題場(chǎng)景示意圖如下:

          下面我們來(lái)思考下解決方案

          首先我們將圖像保存在特定幀中

          接下來(lái)將圖像轉(zhuǎn)換為高斯模糊圖像,這樣做是為了確保我們計(jì)算出模糊圖像和實(shí)際圖像之間的明顯差異

          此時(shí),圖像仍然不是對(duì)象,我們定義了一個(gè)閾值來(lái)去除圖像中的瑕疵,例如陰影和其他噪聲等等

          再接下來(lái)定義對(duì)象的邊框,我們?cè)趯?duì)象周圍添加一個(gè)矩形框

          最后,我們計(jì)算對(duì)象出現(xiàn)和退出幀的時(shí)間

          思路還是蠻清晰的

          我們首先導(dǎo)入包并創(chuàng)建 VideoCapture 對(duì)象以確保我們使用網(wǎng)絡(luò)攝像頭捕獲視頻。

          while 循環(huán)遍歷視頻的各個(gè)幀,我們將彩色幀轉(zhuǎn)換為灰度圖像,然后將此灰度圖像轉(zhuǎn)換為高斯模糊模型

          我們使用 if 語(yǔ)句來(lái)存儲(chǔ)視頻的第一個(gè)圖像

          接下來(lái)我們繼續(xù)深入

          我們使用 absdiff 函數(shù)來(lái)計(jì)算第一個(gè)出現(xiàn)的幀與所有其他幀之間的差異

          閾值函數(shù)提供閾值,將小于30的差值轉(zhuǎn)換為黑色。如果差異大于 30,它會(huì)將這些像素轉(zhuǎn)換為白色

          之后我們使用 findContours 函數(shù)來(lái)定義圖像的輪廓區(qū)域

          就像前面說(shuō)的,contourArea 函數(shù)可去除噪聲和陰影。為簡(jiǎn)單起見(jiàn),將只保留那部分為白色,其面積大于我們?yōu)榇硕x的 1000 像素

          幀每 1 毫秒更改一次,當(dāng)用戶輸入“q”時(shí),循環(huán)中斷并關(guān)閉窗口

          最后計(jì)算對(duì)象在相機(jī)前的時(shí)間

          我們使用 DataFrame 來(lái)存儲(chǔ)對(duì)象檢測(cè)和移動(dòng)出現(xiàn)在幀中的時(shí)間值

          在這里我們定義了一個(gè)狀態(tài)標(biāo)志位,我們?cè)阡浿崎_(kāi)始時(shí)使用此狀態(tài)為零,因?yàn)閷?duì)象最初不可見(jiàn)

          當(dāng)檢測(cè)到對(duì)象時(shí),我們將狀態(tài)標(biāo)志更改為 1

          我們將列出每個(gè)掃描幀的狀態(tài),如果發(fā)生更改以及發(fā)生更改的位置,則在列表中使用 datetime 記錄日期和時(shí)間

          我們將時(shí)間值存儲(chǔ)在 DataFrame 中并寫(xiě)入 CSV 文件

          繪制運(yùn)動(dòng)檢測(cè)圖

          最后一步是顯示結(jié)果

          首先,我們從 motion_detector.py 文件中導(dǎo)入DataFrame

          接下來(lái)將時(shí)間轉(zhuǎn)換為可以解析的可讀字符串格式

          最后,使用散景圖在瀏覽器上繪制時(shí)間值的圖表

          好了,這就是今天的 OpenCV 入門(mén)實(shí)戰(zhàn),怎么樣,看過(guò)之后是不是有一種動(dòng)手的沖動(dòng)呢,一起玩起來(lái)吧!

          往期精彩回顧




          站qq群955171419,加入微信群請(qǐng)掃碼:
          瀏覽 144
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产一级黄色 | www.91AV在线免费观看 | 在线国产精品免费福利 | 亚洲视频在线网站 | 有码一区二区三区四区 |