小編給大家分享一下java怎么實(shí)現(xiàn)基于opencv全景圖合成的示例,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
公司主營(yíng)業(yè)務(wù):網(wǎng)站設(shè)計(jì)制作、網(wǎng)站制作、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出武江免費(fèi)做網(wǎng)站回饋大家。
全景圖概述
每當(dāng)一個(gè)平面圖像映射到一個(gè)彎曲的表面就會(huì)發(fā)生圖象投影,反之亦然,這中現(xiàn)象特別常見于全景攝影。例如地球的球面可以映射到一塊平坦的紙張。由于在我們周圍的整個(gè)視場(chǎng)的可以被認(rèn)為是作為球體的表面(對(duì)于所有觀測(cè)角度),我們需要一種能將球形投影到2-D平面以便照片打印的方法。
小的視角相對(duì)容易進(jìn)行形變并投影到平坦的紙上。但是,當(dāng)試圖把一個(gè)球形圖像映射到一個(gè)平面上,有些變形是不可避免的。因此,每一種類型的投影僅僅嘗試避免一種類型的失真,這是以犧牲其他失真為代價(jià)的。隨著視場(chǎng)角增大,觀測(cè)弧(viewing arc)變得更彎曲,從而全景投影類型之間的差異變得更加顯著。什么時(shí)候使用那一種投影,在很大程度上取決于每個(gè)投影應(yīng)用。 在這里,我們集中介紹在幾個(gè)最常用。
前言
因項(xiàng)目需要,自己做了demo,從中學(xué)習(xí)很多,所以分享出來,希望有這方面需求的少走一些彎路,opencv怎么安裝網(wǎng)上教程多多,這里不加詳細(xì)說明,我安裝的opencv-3.3.0
如上圖所示,找到相應(yīng)的jar包,這里講一下如何這個(gè)jar如何導(dǎo)入Maven倉(cāng)庫(kù)
mvn install:install-file -Dfile=D:\opencv-3.0.0\opencv\build\java\opencv-300.jar -DgroupId=com.suibian -DartifactId=opencv-300 -Dversion=3.3.0 -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true
com.suibian opencv-300 3.3.0
好了,這樣java可以通過這個(gè)jar操作opencv,那我們看一下,當(dāng)然你能這樣想,說明你很單純,讓我們看一下opencv 中includ中的路徑和jar中包的對(duì)比
哈哈,全景圖的關(guān)鍵stitching并沒有,而且面向java的2015以后就一直沒有更新,如下圖所示一個(gè)全景圖(傻瓜)合成的關(guān)鍵類沒有,但是C++給我提供了
那怎么辦呢,如何用java調(diào)用C++的代碼,我們知道和操作系統(tǒng)打交道,C/C++無疑比Java更合適,opencv圖形處理的這方面的應(yīng)用,大多數(shù)是C++開發(fā)比較多,java中的一個(gè)關(guān)鍵字native大家都不陌生吧,然而我們想點(diǎn)進(jìn)去,想看看是怎么實(shí)現(xiàn)的,怎么也點(diǎn)不進(jìn)去,因?yàn)樗筒皇莏ava寫的,可能是C/C++,native對(duì)應(yīng)都是java中jre下bin目錄的XXX.dll文件,所以把我們要使用的C++代碼打包成dll格式的文件放到bin目錄即可,當(dāng)然這涉及到方法的參數(shù)和返回值,廢話不多說,安裝visual studio 2017,安裝教程網(wǎng)上教程很多
點(diǎn)擊 文件-->新建--->項(xiàng)目--->windows桌面-->動(dòng)態(tài)鏈接庫(kù)(Dll),這樣項(xiàng)目就新建成功,接下來上代碼
這是全景圖合成的C++代碼
#include "stdafx.h" #include#include #include #include #include using namespace std; using namespace cv; bool try_use_gpu = false; vector imgs; string result_name = "D:/result1.jpg"; int _tmain(int argc, char * argv[]) { Mat img1 = imread("D:/quanjingtu/hh/1.jpg"); Mat img2 = imread("D:/quanjingtu/hh/2.jpg"); Mat img3 = imread("D:/quanjingtu/hh/3.jpg"); Mat img4 = imread("D:/quanjingtu/hh/4.jpg"); Mat img5 = imread("D:/quanjingtu/hh/5.jpg"); Mat img6 = imread("D:/quanjingtu/hh/6.jpg"); Mat img7 = imread("D:/quanjingtu/hh/7.jpg"); Mat img8 = imread("D:/quanjingtu/hh/8.jpg"); Mat img9 = imread("D:/quanjingtu/hh/9.jpg"); Mat img10 = imread("D:/quanjingtu/hh/10.jpg"); //Mat img6 = imread("6.jpg"); if (img1.empty() || img2.empty()) { cout << "Can't read image" << endl; return -1; } imgs.push_back(img1); imgs.push_back(img2); imgs.push_back(img3); imgs.push_back(img4); imgs.push_back(img5); imgs.push_back(img6); imgs.push_back(img7); imgs.push_back(img8); imgs.push_back(img9); imgs.push_back(img10); //imgs.push_back(img6); Stitcher stitcher = Stitcher::createDefault(try_use_gpu); // 使用stitch函數(shù)進(jìn)行拼接 Mat pano; Stitcher::Status status = stitcher.stitch(imgs, pano); imwrite(result_name, pano); Mat pano2 = pano.clone(); // 顯示源圖像,和結(jié)果圖像 //imshow("全景圖像", pano); if (waitKey() == 27) return 0; //imwrite(result_name, pano); }
那么java如何和C++進(jìn)行交互呢,通過java中jni技術(shù)
讓我們了解一下java中JNI
Java Native Interface(簡(jiǎn)稱JNI),Java是跨平臺(tái)語言,有時(shí)候需要調(diào)用本地代碼,Sun公司提供JNI接口,通過這個(gè)接口與操作系統(tǒng)本地代碼相互調(diào)用,如下圖所示是Java中native的調(diào)用原理
脈絡(luò)都理通了,那就開始吧
public class OpenCVUtil { static { //這里的system.load用來加載C++生成的動(dòng)態(tài)鏈接庫(kù),加載實(shí)際自己也可以決定不一定非的是靜態(tài)的。 System.loadLibrary("OpenCVUtil"); } public static native String changeArrValue(String str); public static void main(String[] args) throws UnsupportedEncodingException { String base="D:/quanjingtu/gg"+"/"; int length=5; String url=""; for (int i=1;i<=length;i++){ if (i==1){ url=url+base+i+".jpg"; }else { url=url+","+base+i+".jpg"; } } //System.out.println(url); String temp =new String(changeArrValue(url).getBytes(),"GBK"); System.out.println(temp); ; } }
定義native方法,將該java文件編譯成.class文件
進(jìn)入cmd命令窗口,打開對(duì)應(yīng)編譯好的class文件目錄執(zhí)行javah命令
生成對(duì)應(yīng)com_lianxi_securitytest_opencv_OpenCVUtil.h文件
#include/* Header for class com_lianxi_securitytest_opencv_OpenCVUtil */ #ifndef _Included_com_lianxi_securitytest_opencv_OpenCVUtil #define _Included_com_lianxi_securitytest_opencv_OpenCVUtil #ifdef __cplusplus extern "C" { #endif /* * Class: com_lianxi_securitytest_opencv_OpenCVUtil * Method: changeArrValue * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_lianxi_securitytest_opencv_OpenCVUtil_changeArrValue (JNIEnv *, jclass, jstring); #ifdef __cplusplus } #endif #endif
只把native方法處理了,復(fù)制該文件,到vs 2017項(xiàng)目所在的位置
#include "stdafx.h" #include "com_lianxi_securitytest_opencv_OpenCVUtil.h" #include#include #include #include #include #include #include using namespace std; using namespace cv; bool try_use_gpu = false; vector imgs; string result_name = "D:/result.jpg"; JNIEXPORT jstring JNICALL Java_com_lianxi_securitytest_opencv_OpenCVUtil_changeArrValue (JNIEnv *env, jclass obj, jstring prompt) { //這是接收過來的字符串,多個(gè)路徑 const char* str; //.................................................................... //........................... //imgs.push_back(img6); Stitcher stitcher = Stitcher::createDefault(try_use_gpu); // 使用stitch函數(shù)進(jìn)行拼接 Mat pano; Stitcher::Status status = stitcher.stitch(imgs, pano); imwrite(result_name, pano); Mat pano2 = pano.clone(); // 顯示源圖像,和結(jié)果圖像 //imshow("全景圖像", pano); if (waitKey() == 27) if (status != Stitcher::OK) { return env->NewStringUTF("picture failure!!!"); } //return env->NewStringUTF(result_name.c_str); string newstr = "picture success!!!URL=" + result_name; return env->NewStringUTF(const_cast (newstr.c_str())); }
上面就是對(duì)應(yīng)C++代碼
點(diǎn)擊生成--->重新生成解決方案 生成對(duì)應(yīng)的dll文件,然后放到JDK的jre/bin目錄里
運(yùn)行java程序,結(jié)果如下
看一下合成的全景圖吧
看完了這篇文章,相信你對(duì)“java怎么實(shí)現(xiàn)基于opencv全景圖合成的示例”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!