OpenCV組件結構java
關於OpenCV的組件結構「淺墨」大神給出了詳細的解釋,詳細的參照:一覽衆山小:OpenCV 2.4.8 or OpenCV 2.4.9組件結構全解析 但在OpenCV3.1中仍是有些變化的,在opencv/build/include/opencv2目錄下有OpenCV的全部模塊,安全
一共有這麼多模塊,在淺墨的文章中也作了詳細的介紹,有些模塊已經沒有了。而後再看看java中所包含的模塊,能夠從opencv.jar中看到所實現的模塊:ui
明顯看到跟C++版本的少了不少模塊,可是基本的功能模塊都已經有了,官方應該也在不斷晚上java版本的接口,不久的未來也應該會擁有跟C++版本如出一轍的功能吧。能夠到各個模塊中查看所實現的方法,通常的方法中都有註釋,並且方法的名字都是跟C++中是同樣的。spa
咱們知道一幅圖片都是有不一樣的像素點組成的,每一個像素點的值表明了一個顏色,好比一副灰度圖像,從0(黑色)到255(白色)來表明顏色的深淺。而一般一幅彩色圖像又是由紅綠藍三種顏色組成,俗稱RGB圖像。更多關於圖像與顏色能夠參考數字圖像處理方面的書籍,這是介紹OpenCV是如何來表示不一樣的圖像的。在core->CvType中定義了不少關於圖像類型的常量,基本結構是:.net
CV_<位數>{U|S|F}C(<通道數>) 位數=8|16|32|64 通道數=1|2|3|4 最多隻有四通道。 下面以一通道的來作詳細的說明。對象
你能夠使用這樣的方式來建立一幅圖片:
Mat image = new Mat(new Size(3,4), CvType.CV_8UC3, new Scalar(new double[]{128,3,4})); blog
Mat有不少中構造方法,這裏只是其中一種,這樣構造的mat對象含義是寬度爲3個像素,高度爲4個像素,8位無符號三通道圖像,第一通道也就是Red全爲128,第二通道Green全爲3,第三通道Blue全是4,咱們能夠使用以下的代碼打印出這個對象的信息以及每一個像素點的數據。接口
Mat image = new Mat(new Size(3, 4), CvType.CV_8UC3, new Scalar(new double[]{128, 3, 4})); System.out.println(image + " width=" + image.width() + " height=" + image.height()); System.out.println(image.dump());
直接使用Mat對象的toString()方法,將會打印出mat對象的基本信息,dump()返回每一個像素點的值,注意當像素寬高太大時,可能耗時比較長。輸出結果:圖片
Mat [ 4*3*CV_8UC3, isCont=true, isSubmat=false, nativeObj=0x50aaf0, dataAddr=0x4dce00 ] width=3 height=4 [128, 3, 4, 128, 3, 4, 128, 3, 4; 128, 3, 4, 128, 3, 4, 128, 3, 4; 128, 3, 4, 128, 3, 4, 128, 3, 4; 128, 3, 4, 128, 3, 4, 128, 3, 4]
因爲圖像過小,顯示出來也是特別小,基本看不出來,能夠把寬高設置大一些而後顯示,就是一片深藍色,也就是red=128,green=3,blue=4的顏色。內存
一些須要注意的點:
java中沒有無符號這個說法,全部的基本數據類型都是有符號的,好比對於CV_8UC1來講,須要表示的像素是從0到255,在C++中只須要一個byte就夠了,可是java中確不能用一個字節來表示0到255,因此是隻能向上類型轉換了。咱們先來看一段代碼:
Mat image = new Mat(new Size(3, 4), CvType.CV_8UC1, new Scalar(new double[]{234})); image.put(1, 2, new byte[]{123}); System.out.println(image); System.out.println(image.dump()); image.put(1, 2, new byte[]{200 - 256}); System.out.println(image.dump());
這段代碼先建立了一個3*4的8位單通道無符號的圖像,每一個像素點都是234,而後將[1,2]這個位置(注意從[0,0]座標點開始計數)值置爲123,而後打印出來像素,沒問題,123<127因此能夠put成功,可是若是咱們想改一個大於127的值呢,byte數據會直接報錯,編譯都沒法經過,那是否是就沒法建立一個大於127的值呢,固然不是,將大於127的值減去一個256,好比如今我想設置成200,怎麼作呢,直接用200-256,也就是存一個-56,而後再打印出來看看是否是能夠。結果固然是能夠的,200已經設置成功了。那若是是一個CV_8SC1的圖像呢,該是多少直接設置成多少就能夠了。爲何能打印出200呢,不是byte值得嗎?不妨看看image.get(1,2)這個方法,這個方法返回了一個double[]類型,當時能保存200了,而dump返回的是String,在內部已經將-56轉成了200的字符串.
因此對於得到一幅圖像的像素點的時候不用考慮太多,可是若是你要設置某個像素點,而且這個像素點的數據類型或是位寬小於你要設置的值得位寬時,就得注意了,不過也有更安全的作法,那就是全都使用double設置,在內部會自動轉換。後面會看到在java版本的OpenCV的方法中不少地方都是使用的是double,這個確實是浪費了不少內存,不少時候咱們處理的都是8位無符號的3通道彩色圖像,映射到java程序中,若是要把這個圖像的數據dump過來,那就得8倍的內存來保存(C++中一個字節就夠但java就須要用double表示,double佔了8位)。
下一遍開始就正式要開始介紹使用OpenCV來處理圖像了。