日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenCV学习笔记(五十六)——InputArray和OutputArray的那些事core OpenCV学习笔记(五十七)——在同一窗口显示多幅图片 OpenCV学习笔记(五十八)——读《Mast

發布時間:2025/3/21 编程问答 24 豆豆

OpenCV學習筆記(五十六)——InputArray和OutputArray的那些事core

看過OpenCV源代碼的朋友,肯定都知道很多函數的接口都是InputArray或者OutputArray型的,這個接口類還是很強大的,今個就來說說它們的那些事。

InputArray這個接口類可以是Mat、Mat_<T>、Mat_<T, m, n>、vector<T>、vector<vector<T>>、vector<Mat>。也就意味著當你看refman或者源代碼時,如果看見函數的參數類型是InputArray型時,把上訴幾種類型作為參數都是可以的。

有時候InputArray輸入的矩陣是個空參數,你只需要用cv::noArray()作為參數即可,或者很多代碼里都用cv::Mat()作為空參。

這個類只能作為函數的形參參數使用,不要試圖聲明一個InputArray類型的變量

如果在你自己編寫的函數中形參也想用InputArray,可以傳遞多類型的參數,在函數的內部可以使用_InputArray::getMat()函數將傳入的參數轉換為Mat的結構,方便你函數內的操作;必要的時候,可能還需要_InputArray::kind()用來區分Mat結構或者vector<>結構,但通常是不需要的。例如:

[cpp] view plain copy
  • void?myAffineTransform(InputArray?_src,?OutputArray?_dst,?InputArray?_m)??
  • {??
  • ??
  • ????Mat?src?=?_src.getMat(),?m?=?_m.getMat();??
  • ????CV_Assert(?src.type()?==?CV_32FC2?&&?m.type()?==?CV_32F?&&?m.size()?==?Size(3,?2)?);??
  • ????_dst.create(src.size(),?src.type());??
  • ????Mat?dst?=?_dst.getMat();??
  • ????for(?int?i?=?0;?i?<?src.rows;?i++?)??
  • ????????for(?int?j?=?0;?j?<?src.cols;?j++?)??
  • ????????{??
  • ????????????Point2f?pt?=?src.at<Point2f>(i,?j);??
  • ????????????dst.at<Point2f>(i,?j)?=?Point2f(m.at<float>(0,?0)?*?pt.x?+??m.at<float>(0,?1)?*???pt.y?+?m.at<float>(0,?2);??
  • ????????}??
  • }??

  • 至于有的源代碼里使用InputArrayOfArrays作為形參,不用慌張,其實它和InputArray是一樣一樣一樣的。

    OutputArray是InputArray的派生類。使用時需要注意的問題和InputArray一樣。和InputArray不同的是,需要注意在使用_OutputArray::getMat()之前一定要調用_OutputArray::create()為矩陣分配空間。可以用_OutputArray::needed()來檢測輸出的矩陣是否需要被計算。有時候傳進去的參不是空就不需要計算

    還有就是OutputArrayOfArrays、InputOutputArray、InputOutputArrayOfArrays都是OutputArray的別名而已



    OpenCV學習筆記(五十七)——在同一窗口顯示多幅圖片

    好久沒更新blog里,看到OpenCV官網做的越來越好,心里也是很高興的,真有些沖動將來加入到這個組織里做些事。估計2.4.3要在國慶左右跟大家見面,讓我們多期待一下吧。

    閑話少說,今天不介紹復雜的算法了,來個簡單的,大家寫文章做圖經常用Matlab,在Matlab里經常在一個窗口里打開多幅圖片。遺憾的是OpenCV沒有集成這樣的功能,但這難不倒大家,讓我試試用ROI來解決這個問題。

    沒啥好講的,上代碼好了:

    [cpp] view plain copy
  • void?imshowMany(const?std::string&?_winName,?const?vector<Mat>&?_imgs)??
  • {??
  • ????int?nImg?=?(int)_imgs.size();??
  • ??????
  • ????Mat?dispImg;??
  • ??
  • ????int?size;??
  • ????int?x,?y;??
  • ??
  • ????//?w?-?Maximum?number?of?images?in?a?row???
  • ????//?h?-?Maximum?number?of?images?in?a?column???
  • ????int?w,?h;??
  • ????//?scale?-?How?much?we?have?to?resize?the?image??
  • ????float?scale;??
  • ????int?max;??
  • ??
  • ????if?(nImg?<=?0)???
  • ????{??
  • ????????printf("Number?of?arguments?too?small....\n");??
  • ????????return;??
  • ????}??
  • ????else?if?(nImg?>?12)??
  • ????{??
  • ????????printf("Number?of?arguments?too?large....\n");??
  • ????????return;??
  • ????}??
  • ??????
  • ????else?if?(nImg?==?1)??
  • ????{??
  • ????????w?=?h?=?1;??
  • ????????size?=?300;??
  • ????}??
  • ????else?if?(nImg?==?2)??
  • ????{??
  • ????????w?=?2;?h?=?1;??
  • ????????size?=?300;??
  • ????}??
  • ????else?if?(nImg?==?3?||?nImg?==?4)??
  • ????{??
  • ????????w?=?2;?h?=?2;??
  • ????????size?=?300;??
  • ????}??
  • ????else?if?(nImg?==?5?||?nImg?==?6)??
  • ????{??
  • ????????w?=?3;?h?=?2;??
  • ????????size?=?200;??
  • ????}??
  • ????else?if?(nImg?==?7?||?nImg?==?8)??
  • ????{??
  • ????????w?=?4;?h?=?2;??
  • ????????size?=?200;??
  • ????}??
  • ????else??
  • ????{??
  • ????????w?=?4;?h?=?3;??
  • ????????size?=?150;??
  • ????}??
  • ??
  • ????dispImg.create(Size(100?+?size*w,?60?+?size*h),?CV_8UC3);??
  • ??
  • ????for?(int?i=?0,?m=20,?n=20;?i<nImg;?i++,?m+=(20+size))??
  • ????{??
  • ????????x?=?_imgs[i].cols;??
  • ????????y?=?_imgs[i].rows;??
  • ??
  • ????????max?=?(x?>?y)??x:?y;??
  • ????????scale?=?(float)?(?(float)?max?/?size?);??
  • ??
  • ????????if?(i%w==0?&&?m!=20)??
  • ????????{??
  • ????????????m?=?20;??
  • ????????????n?+=?20+size;??
  • ????????}??
  • ??
  • ????????Mat?imgROI?=?dispImg(Rect(m,?n,?(int)(x/scale),?(int)(y/scale)));??
  • ????????resize(_imgs[i],?imgROI,?Size((int)(x/scale),?(int)(y/scale)));??
  • ????}??
  • ??
  • ????namedWindow(_winName);??
  • ????imshow(_winName,?dispImg);??
  • }??

  • 附上效果圖一張:


    工程的下載鏈接為http://download.csdn.net/detail/yang_xian521/4531610



    OpenCV學習筆記(五十八)——讀《Master OpenCV》初感

    好久沒更新這個系列了。去年12月初的時候就知道出了一本OpenCV的新書《Master OpenCV with Practical Computer Vision Projects》,一直沒來得及看,春節前也不想做什么任務,就把這書讀一讀吧。大概看了一下,和OpenCV的其他書對比了一下,感覺如下:

    《Learning OpenCV》是一本經典的老書了,是一個入門教材,讀完可以知道OpenCV能做些什么,但里面的具體代碼個人覺得還是有點out,但好處就是中文資料很全,網上可以找到很多參考資料。

    《OpenCV Cookbook》是我以前推薦過的一本書,是基于2.2版本寫的。我的感覺是一本上手教材,書的目的是讓大家知道應該如何去調用OpenCV的函數,如何用OpenCV的類去實現簡單的視覺任務。需要一定的C++基礎。

    《Master OpenCV》感覺更像是一個上層建筑,是基于2.4版本寫的。是教會大家如何用OpenCV去實現復雜的任務,去完成OpenCV自帶函數沒有提供的功能。(因為大家經常會因為“OpenCV里面有xxx的函數么?”的否定答案而苦惱,這本書就是告訴大家OpenCV只是個工具,如何去駕馭這個工具進行二次開發是要動腦的)

    這本《Master OpenCV》書第一章沒有很復雜的東西。

    第一章就是介紹了一個邊緣檢測、膚色檢測、一個填充算法,并把這個功能移植到android平臺,邊緣檢測和填充算法都是OpenCV自帶的函數功能。這里隨便說說讀完第一章的幾點收獲:

    1、具體任務要具體分析。這里因為要做到嵌入式平臺中,算法的復雜度被放在了首位,所以雙邊濾波做了簡化、填充算法也只是在原圖的縮小1/2的圖上進行的計算。膚色檢測也沒有先用經典的人臉檢測算法,而是用了一種土鱉的方案,都是為了在嵌入式平臺上能運行的高效。這種處理問題的方法值得借鑒學習

    2、面向對象編程的思想。這章里也提到了顯示FPS,只是人家是在一個類中實現,再對比自己之前寫的OpenCV學習筆記(三十八)——顯示當前FPS,高下自分。實在是自慚形愧啊~~。

    3、貌似把自己的c++工程移植到android平臺并不需要改寫自己的代碼,只要做個JNI function作為接口就可以調用c++的程序了,感覺有點像Matlab中的mex。android下的OpenCV開發基本不懂,這里就不亂講了。

    這幾天抓緊把這書讀完,把后幾章的閱讀筆記也寫出來分享一下。希望大家多多指正交流



    OpenCV學習筆記(五十九)——marker檢測識別"Master

    第二章原本是講如何將基于標定的增強現實在ios平臺實現,包括以下4個方面:

    1、在ios平臺建立opencv工程

    2、Marker檢測識別

    3、攝像機標定及Marker姿態估計

    4、在Marker基礎上渲染一個3維虛擬物體

    這里面第一部分是IOS平臺的開發,我不是太關注,略去;第四部分是基于OpenGL的3維虛擬物體建立,也是基于IOS平臺,因為第三章里還要用到OpenGL,這里留著第三章再解剖。所以這里主要分析第二部分和第三部分。這一篇介紹第二部分。感覺這個東西有點像二維碼識別。不知道2維碼是怎么做的哦

    MarkerDetection類任務processFrame:圖1


    轉為灰度圖、2值化(固定閾值法threshold:受光照等影響明顯;自適應閾值法adaptiveThreshold:更好)(我這里用OpenCV243里的adaptiveThreshold函數未能實現自適應濾波的效果,效果像邊緣檢測的算法,很困惑。。最后用threshold函數代替,這個問題未能解決,希望高手指點,ps:網上高手多啊,這個問題已經解決了),檢測后的結果如圖threshold(圖1左上)

    findMarkerContours函數進行輪廓檢測findContours(用多邊形的頂點最好,去掉小于閾值的點(對小的輪廓不感興趣),把每個輪廓的點按照逆時針排序,并去掉距離太近的輪廓),結果如圖contours(圖1中上)

    接下來findMarkerCandidates函數對輪廓進行篩選,先用approxPolyDP得到輪廓近似的多邊形。進行篩選,為凸多邊形且頂點為4的才有可能是marker,并檢測這個4邊形的邊長,最小邊長如果小于10pixel,也不認為是一個marker。然后把得到的可能的marker的輪廓點按照逆時針排序。并且檢測是否檢測到重復的marker,如果檢測到重復的marker,去掉周長更短的那個。這步之后效果如下markerCandidate(圖1左下)

    detectMarkers函數有3個任務,去除投影變換的影響(getPerspectiveTransform得到投影矩陣,warpPerspective得到正面的視角的圖像),得到marker正面的視圖。

    然后對這個marker的正面圖進行解碼,threshold對marker使用THRESH_OTSU進行2值化。效果圖:


    接下來對這個marker進行識別marker.decode。檢測編碼marker(對marker解碼,marker編碼為7*7的柵格,中心5*5為ID,周圍一圈為黑色邊界,檢測的時候先檢測周圍一圈是否為黑色邊界,然后再對中心5*5解碼(注意,只有5*5具有旋轉不變形才能得到唯一的碼),是5bit*5word,每個word中的5bit,2位為id(2位4位),3位為校驗碼(用來保證旋轉),所以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個方向,哪個方向才是我對應的marker的id的,這里用id和我驗證用的id的hamming距離來做依據,漢明距最小的即marker的方向。

    確認為一個marker后再得到輪廓的細致的corner,使用cornerSubPix,這時才進行細化,是因為這個函數相對耗時,如果之前就對各corner細化,由于候選目標很多,會加重計算負擔。)效果圖marker(圖1右下)。

    最后我試了其他的marker編碼,都能正確解碼出id信息,效果圖如下:第一幅圖的id為0011010101,第二幅圖為第一圖的旋轉,id相同,第三圖id為0011000110,第四圖不是一個marker,故沒有檢測出來。


    代碼的下載地址:http://download.csdn.net/detail/yang_xian521/5040634

    在下一篇里,將介紹如何用這個marker的輪廓位置,和輪廓(紅色)的方向(黃點)來在marker上建立一個3維的虛擬物體。



    OpenCV"chp.2 OpenCV學習筆記(六十一)——建立支持OpenGL的OpenCV工程“Master OpenCV”chp.3

    從OpenCV2.4beta版本,OpenGL就可以有接口到highgui的模塊中了。結合Master OpenCV第三章的閱讀,這里說說如何在OpenCV的顯示中嵌入OpenGL的虛擬物體。

    要注意的一點:如果想使OpenCV支持OpenGL,不能使用預編譯好的library,要用cmake rebuild工程,注意ENABLE_OPENGL = YES,(在2.4.2版本中,默認ENABLE_OPENGL = NO),標簽的改變在CMake的高級版本都是圖形界面的,只需把WITH_OPENGL的對號勾選即可。

    這里實戰過程中我還遇到了一個問題,用這個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

    已經得到了支持OpenGL的OpenCV lib,接下來就是如何用OpenCV建立OpenGL窗口,基本的調用方式很像OpenCV中鼠標的使用,都是通過回調函數實現,核心代碼如下:

    [cpp] view plain copy
  • //?callback?function??
  • void?onDraw(void*?param)??
  • {??
  • ????//?Draw?something?using?OpenGL?here??
  • }??
  • ??
  • int?main(void)??
  • {??
  • ????string?openGLWindowName?=?"OpenGL?Test";??
  • ????namedWindow(openGLWindowName,?WINDOW_OPENGL);??
  • ????resizeWindow(openGLWindowName,?640,?480);??
  • ????setOpenGlContext(openGLWindowName);??
  • ????setOpenGlDrawCallback(openGLWindowName,?onDraw,?NULL);??
  • ??
  • ????updateWindow(openGLWindowName);?//?when?needed??
  • ????return?0;??
  • }??

  • 以前我們調用 namedWindow最后一個參數通常會用默認或者使用WINDOW_AUTOSIZE,這回用 WINDOW_OPENGL,然后調用 setOpenGLContext建立窗口關聯,為了在這個窗口上畫虛擬物體,需要使用回調函數,建立方法就是 setOpenGLDrawCallback,注意這個函數第一個參數是窗口名稱,第二個參數是回調函數名,第三個參數是回調函數的參數,因為我這里回調函數onDraw是無參函數,所以這里為NULL。跟MFC重繪需要調用Invalidate或者uadate類似,在需要重繪的時候還要調用 updateWindow

    把我做的一個最基礎的OpenGL演示上傳:http://download.csdn.net/detail/yang_xian521/5023063(附上我rebulid的支持OpenGL的lib),效果圖如下:



    OpenCV學習筆記(六十二)——《OpenCV Computer Version with Python》閱讀摘要

    現在python火啊,每次OpenCV自帶的ml模塊都讓我直呼坑爹,索性準備用python來做OpenCV后期的機器學習算法的處理。于是趕緊拿起這本書讀讀。

    適合OpenCV和python都有一定基礎的。。。。由于都比較熟悉這兩個東西,我閱讀之前比較關心的只有幾個問題,具體的應用實例沒有仔細看。

    1.如何在python中安裝opencv

    2.OpenCV的Mat數據結構能否方便的轉換成numpy的array結構

    3.OpenCV的GUI模塊在python里好用么

    4.二者還能擦出什么我想不到的火花么。。。。

    書中提到在windows系統中,python-32bit表現的比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這句就可以導入cv2模塊了

    第二個問題也不用擔心了,因為python不用聲明變量的類型,實驗了一下,發現得到的矩陣的數據類型就是array,穩了,直接拿來用

    第三個問題也超簡單,圖像顯示讀寫的模塊、攝像頭模塊、鼠標鍵盤的響應模塊都可以,跟c++的版本使用起來也差不多。

    第四個問題我簡單粗看了一遍書,沒發現什么亮點,只是書中提到一個pygame可以用來做hgui效果還行,支持畫畫和編輯文本,不過好像對CV也沒啥幫助,所以就沒研究了。

    補充幾個我學習的時候遇見的問題:

    opencv里的Rect數據結構在python里是沒有對應類型的,這個要注意調用的時候需要注意。比如rectangle函數輸入的就是矩形兩個點的坐標,不是Rect。

    還有就是opencv里的很多宏在python里需要加上cv2.cv前綴就可以生效了


    from: http://blog.csdn.net/yang_xian521/article/category/910716




    總結

    以上是生活随笔為你收集整理的OpenCV学习笔记(五十六)——InputArray和OutputArray的那些事core OpenCV学习笔记(五十七)——在同一窗口显示多幅图片 OpenCV学习笔记(五十八)——读《Mast的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。