OpenCV学习笔记(五十六)——InputArray和OutputArray的那些事core OpenCV学习笔记(五十七)——在同一窗口显示多幅图片 OpenCV学习笔记(五十八)——读《Mast
OpenCV學(xué)習(xí)筆記(五十六)——InputArray和OutputArray的那些事core
看過OpenCV源代碼的朋友,肯定都知道很多函數(shù)的接口都是InputArray或者OutputArray型的,這個接口類還是很強大的,今個就來說說它們的那些事。
InputArray這個接口類可以是Mat、Mat_<T>、Mat_<T, m, n>、vector<T>、vector<vector<T>>、vector<Mat>。也就意味著當(dāng)你看refman或者源代碼時,如果看見函數(shù)的參數(shù)類型是InputArray型時,把上訴幾種類型作為參數(shù)都是可以的。
有時候InputArray輸入的矩陣是個空參數(shù),你只需要用cv::noArray()作為參數(shù)即可,或者很多代碼里都用cv::Mat()作為空參。
這個類只能作為函數(shù)的形參參數(shù)使用,不要試圖聲明一個InputArray類型的變量
如果在你自己編寫的函數(shù)中形參也想用InputArray,可以傳遞多類型的參數(shù),在函數(shù)的內(nèi)部可以使用_InputArray::getMat()函數(shù)將傳入的參數(shù)轉(zhuǎn)換為Mat的結(jié)構(gòu),方便你函數(shù)內(nèi)的操作;必要的時候,可能還需要_InputArray::kind()用來區(qū)分Mat結(jié)構(gòu)或者vector<>結(jié)構(gòu),但通常是不需要的。例如:
[cpp] view plain copy至于有的源代碼里使用InputArrayOfArrays作為形參,不用慌張,其實它和InputArray是一樣一樣一樣的。
OutputArray是InputArray的派生類。使用時需要注意的問題和InputArray一樣。和InputArray不同的是,需要注意在使用_OutputArray::getMat()之前一定要調(diào)用_OutputArray::create()為矩陣分配空間。可以用_OutputArray::needed()來檢測輸出的矩陣是否需要被計算。有時候傳進去的參不是空就不需要計算
還有就是OutputArrayOfArrays、InputOutputArray、InputOutputArrayOfArrays都是OutputArray的別名而已
OpenCV學(xué)習(xí)筆記(五十七)——在同一窗口顯示多幅圖片
好久沒更新blog里,看到OpenCV官網(wǎng)做的越來越好,心里也是很高興的,真有些沖動將來加入到這個組織里做些事。估計2.4.3要在國慶左右跟大家見面,讓我們多期待一下吧。
閑話少說,今天不介紹復(fù)雜的算法了,來個簡單的,大家寫文章做圖經(jīng)常用Matlab,在Matlab里經(jīng)常在一個窗口里打開多幅圖片。遺憾的是OpenCV沒有集成這樣的功能,但這難不倒大家,讓我試試用ROI來解決這個問題。
沒啥好講的,上代碼好了:
[cpp] view plain copy附上效果圖一張:
工程的下載鏈接為http://download.csdn.net/detail/yang_xian521/4531610
OpenCV學(xué)習(xí)筆記(五十八)——讀《Master OpenCV》初感
好久沒更新這個系列了。去年12月初的時候就知道出了一本OpenCV的新書《Master OpenCV with Practical Computer Vision Projects》,一直沒來得及看,春節(jié)前也不想做什么任務(wù),就把這書讀一讀吧。大概看了一下,和OpenCV的其他書對比了一下,感覺如下:
《Learning OpenCV》是一本經(jīng)典的老書了,是一個入門教材,讀完可以知道OpenCV能做些什么,但里面的具體代碼個人覺得還是有點out,但好處就是中文資料很全,網(wǎng)上可以找到很多參考資料。
《OpenCV Cookbook》是我以前推薦過的一本書,是基于2.2版本寫的。我的感覺是一本上手教材,書的目的是讓大家知道應(yīng)該如何去調(diào)用OpenCV的函數(shù),如何用OpenCV的類去實現(xiàn)簡單的視覺任務(wù)。需要一定的C++基礎(chǔ)。
《Master OpenCV》感覺更像是一個上層建筑,是基于2.4版本寫的。是教會大家如何用OpenCV去實現(xiàn)復(fù)雜的任務(wù),去完成OpenCV自帶函數(shù)沒有提供的功能。(因為大家經(jīng)常會因為“OpenCV里面有xxx的函數(shù)么?”的否定答案而苦惱,這本書就是告訴大家OpenCV只是個工具,如何去駕馭這個工具進行二次開發(fā)是要動腦的)
這本《Master OpenCV》書第一章沒有很復(fù)雜的東西。
第一章就是介紹了一個邊緣檢測、膚色檢測、一個填充算法,并把這個功能移植到android平臺,邊緣檢測和填充算法都是OpenCV自帶的函數(shù)功能。這里隨便說說讀完第一章的幾點收獲:
1、具體任務(wù)要具體分析。這里因為要做到嵌入式平臺中,算法的復(fù)雜度被放在了首位,所以雙邊濾波做了簡化、填充算法也只是在原圖的縮小1/2的圖上進行的計算。膚色檢測也沒有先用經(jīng)典的人臉檢測算法,而是用了一種土鱉的方案,都是為了在嵌入式平臺上能運行的高效。這種處理問題的方法值得借鑒學(xué)習(xí)
2、面向?qū)ο缶幊痰乃枷搿_@章里也提到了顯示FPS,只是人家是在一個類中實現(xiàn),再對比自己之前寫的OpenCV學(xué)習(xí)筆記(三十八)——顯示當(dāng)前FPS,高下自分。實在是自慚形愧啊~~。
3、貌似把自己的c++工程移植到android平臺并不需要改寫自己的代碼,只要做個JNI function作為接口就可以調(diào)用c++的程序了,感覺有點像Matlab中的mex。android下的OpenCV開發(fā)基本不懂,這里就不亂講了。
這幾天抓緊把這書讀完,把后幾章的閱讀筆記也寫出來分享一下。希望大家多多指正交流
OpenCV學(xué)習(xí)筆記(五十九)——marker檢測識別"Master
第二章原本是講如何將基于標(biāo)定的增強現(xiàn)實在ios平臺實現(xiàn),包括以下4個方面:
1、在ios平臺建立opencv工程
2、Marker檢測識別
3、攝像機標(biāo)定及Marker姿態(tài)估計
4、在Marker基礎(chǔ)上渲染一個3維虛擬物體
這里面第一部分是IOS平臺的開發(fā),我不是太關(guān)注,略去;第四部分是基于OpenGL的3維虛擬物體建立,也是基于IOS平臺,因為第三章里還要用到OpenGL,這里留著第三章再解剖。所以這里主要分析第二部分和第三部分。這一篇介紹第二部分。感覺這個東西有點像二維碼識別。不知道2維碼是怎么做的哦
MarkerDetection類任務(wù)processFrame:圖1
轉(zhuǎn)為灰度圖、2值化(固定閾值法threshold:受光照等影響明顯;自適應(yīng)閾值法adaptiveThreshold:更好)(我這里用OpenCV243里的adaptiveThreshold函數(shù)未能實現(xiàn)自適應(yīng)濾波的效果,效果像邊緣檢測的算法,很困惑。。最后用threshold函數(shù)代替,這個問題未能解決,希望高手指點,ps:網(wǎng)上高手多啊,這個問題已經(jīng)解決了),檢測后的結(jié)果如圖threshold(圖1左上)
findMarkerContours函數(shù)進行輪廓檢測findContours(用多邊形的頂點最好,去掉小于閾值的點(對小的輪廓不感興趣),把每個輪廓的點按照逆時針排序,并去掉距離太近的輪廓),結(jié)果如圖contours(圖1中上)
接下來findMarkerCandidates函數(shù)對輪廓進行篩選,先用approxPolyDP得到輪廓近似的多邊形。進行篩選,為凸多邊形且頂點為4的才有可能是marker,并檢測這個4邊形的邊長,最小邊長如果小于10pixel,也不認為是一個marker。然后把得到的可能的marker的輪廓點按照逆時針排序。并且檢測是否檢測到重復(fù)的marker,如果檢測到重復(fù)的marker,去掉周長更短的那個。這步之后效果如下markerCandidate(圖1左下)
detectMarkers函數(shù)有3個任務(wù),去除投影變換的影響(getPerspectiveTransform得到投影矩陣,warpPerspective得到正面的視角的圖像),得到marker正面的視圖。
然后對這個marker的正面圖進行解碼,threshold對marker使用THRESH_OTSU進行2值化。效果圖:
接下來對這個marker進行識別marker.decode。檢測編碼marker(對marker解碼,marker編碼為7*7的柵格,中心5*5為ID,周圍一圈為黑色邊界,檢測的時候先檢測周圍一圈是否為黑色邊界,然后再對中心5*5解碼(注意,只有5*5具有旋轉(zhuǎn)不變形才能得到唯一的碼),是5bit*5word,每個word中的5bit,2位為id(2位4位),3位為校驗碼(用來保證旋轉(zhuǎn)),所以5word一共有2^10=1024個不同id,而且第一位要置反,目的是要防止一個word全黑,不易檢測。舉例,我這里使用的marker的5個word的id分別為10、01、11、11、11。那么如何從剛剛得到的marker圖提取出7*7的2值柵格呢,這里用個Mat(Rect)取marker中的小方塊,用countNonZero來判斷這個方塊為0or1。因為marker有4個方向,哪個方向才是我對應(yīng)的marker的id的,這里用id和我驗證用的id的hamming距離來做依據(jù),漢明距最小的即marker的方向。
確認為一個marker后再得到輪廓的細致的corner,使用cornerSubPix,這時才進行細化,是因為這個函數(shù)相對耗時,如果之前就對各corner細化,由于候選目標(biāo)很多,會加重計算負擔(dān)。)效果圖marker(圖1右下)。
最后我試了其他的marker編碼,都能正確解碼出id信息,效果圖如下:第一幅圖的id為0011010101,第二幅圖為第一圖的旋轉(zhuǎn),id相同,第三圖id為0011000110,第四圖不是一個marker,故沒有檢測出來。
代碼的下載地址:http://download.csdn.net/detail/yang_xian521/5040634
在下一篇里,將介紹如何用這個marker的輪廓位置,和輪廓(紅色)的方向(黃點)來在marker上建立一個3維的虛擬物體。
OpenCV"chp.2 OpenCV學(xué)習(xí)筆記(六十一)——建立支持OpenGL的OpenCV工程“Master OpenCV”chp.3
從OpenCV2.4beta版本,OpenGL就可以有接口到highgui的模塊中了。結(jié)合Master OpenCV第三章的閱讀,這里說說如何在OpenCV的顯示中嵌入OpenGL的虛擬物體。
要注意的一點:如果想使OpenCV支持OpenGL,不能使用預(yù)編譯好的library,要用cmake rebuild工程,注意ENABLE_OPENGL = YES,(在2.4.2版本中,默認ENABLE_OPENGL = NO),標(biāo)簽的改變在CMake的高級版本都是圖形界面的,只需把WITH_OPENGL的對號勾選即可。
這里實戰(zhàn)過程中我還遇到了一個問題,用這個CMake得到的vs工程(添加了WITH_OPENGL)無法編譯通過,郁悶了好久。因為opengl在vs中是支持的,不需要安裝,最后找到了這個bug,需要把\modules\core\src\opengl_interop.cpp文件中使用<gl\gl.h>前面添加#include <windows.h>,(其實#include <gl.h>前都需要添加#include <windows.h>)這樣才能編譯通過,這里我只重新編譯opencv_core243d.lib 和opencv_highgui243d.lib
已經(jīng)得到了支持OpenGL的OpenCV lib,接下來就是如何用OpenCV建立OpenGL窗口,基本的調(diào)用方式很像OpenCV中鼠標(biāo)的使用,都是通過回調(diào)函數(shù)實現(xiàn),核心代碼如下:
[cpp] view plain copy以前我們調(diào)用 namedWindow最后一個參數(shù)通常會用默認或者使用WINDOW_AUTOSIZE,這回用 WINDOW_OPENGL,然后調(diào)用 setOpenGLContext建立窗口關(guān)聯(lián),為了在這個窗口上畫虛擬物體,需要使用回調(diào)函數(shù),建立方法就是 setOpenGLDrawCallback,注意這個函數(shù)第一個參數(shù)是窗口名稱,第二個參數(shù)是回調(diào)函數(shù)名,第三個參數(shù)是回調(diào)函數(shù)的參數(shù),因為我這里回調(diào)函數(shù)onDraw是無參函數(shù),所以這里為NULL。跟MFC重繪需要調(diào)用Invalidate或者uadate類似,在需要重繪的時候還要調(diào)用 updateWindow。
把我做的一個最基礎(chǔ)的OpenGL演示上傳:http://download.csdn.net/detail/yang_xian521/5023063(附上我rebulid的支持OpenGL的lib),效果圖如下:
OpenCV學(xué)習(xí)筆記(六十二)——《OpenCV Computer Version with Python》閱讀摘要
現(xiàn)在python火啊,每次OpenCV自帶的ml模塊都讓我直呼坑爹,索性準(zhǔn)備用python來做OpenCV后期的機器學(xué)習(xí)算法的處理。于是趕緊拿起這本書讀讀。
適合OpenCV和python都有一定基礎(chǔ)的。。。。由于都比較熟悉這兩個東西,我閱讀之前比較關(guān)心的只有幾個問題,具體的應(yīng)用實例沒有仔細看。
1.如何在python中安裝opencv
2.OpenCV的Mat數(shù)據(jù)結(jié)構(gòu)能否方便的轉(zhuǎn)換成numpy的array結(jié)構(gòu)
3.OpenCV的GUI模塊在python里好用么
4.二者還能擦出什么我想不到的火花么。。。。
書中提到在windows系統(tǒng)中,python-32bit表現(xiàn)的比64bit要好,推薦安裝32位的python
第一個問題在windows下很簡單,OpenCV安裝好之后,找到目錄<build_folder>\lib\Release\cv2.pyd(from a Visual Studio build) 這個文件,然后copy到C:\Python2.7\Lib\site-packages。搞定了,就這么簡單。畢竟腳本語言,簡直無情,\sources\samples下有很多python的例子,跑幾個試試就知道是否安裝好了。import cv2這句就可以導(dǎo)入cv2模塊了
第二個問題也不用擔(dān)心了,因為python不用聲明變量的類型,實驗了一下,發(fā)現(xiàn)得到的矩陣的數(shù)據(jù)類型就是array,穩(wěn)了,直接拿來用。
第三個問題也超簡單,圖像顯示讀寫的模塊、攝像頭模塊、鼠標(biāo)鍵盤的響應(yīng)模塊都可以,跟c++的版本使用起來也差不多。
第四個問題我簡單粗看了一遍書,沒發(fā)現(xiàn)什么亮點,只是書中提到一個pygame可以用來做hgui效果還行,支持畫畫和編輯文本,不過好像對CV也沒啥幫助,所以就沒研究了。
補充幾個我學(xué)習(xí)的時候遇見的問題:
opencv里的Rect數(shù)據(jù)結(jié)構(gòu)在python里是沒有對應(yīng)類型的,這個要注意調(diào)用的時候需要注意。比如rectangle函數(shù)輸入的就是矩形兩個點的坐標(biāo),不是Rect。
還有就是opencv里的很多宏在python里需要加上cv2.cv前綴就可以生效了。
from: http://blog.csdn.net/yang_xian521/article/category/910716
總結(jié)
以上是生活随笔為你收集整理的OpenCV学习笔记(五十六)——InputArray和OutputArray的那些事core OpenCV学习笔记(五十七)——在同一窗口显示多幅图片 OpenCV学习笔记(五十八)——读《Mast的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV学习笔记(五十一)——img
- 下一篇: 美团O2O排序解决方案——线上篇