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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

)类 新建javafx程序时_第三章 第一个OpenCV的JavaFX应用程序.md

發(fā)布時(shí)間:2024/7/19 java 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 )类 新建javafx程序时_第三章 第一个OpenCV的JavaFX应用程序.md 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

# 第三章 第一個(gè)OpenCV的JavaFX應(yīng)用程序

---

***注意***:我們假設(shè)您現(xiàn)在已經(jīng)閱讀了之前的教程。如果沒有,請(qǐng)?jiān)赱http://opencv-java-tutorials.readthedocs.org/en/latest/index.html](http://opencv-java-tutorials.readthedocs.org/en/latest/index.html)查看。您還可以在

[https://github.com/opencv-java/](https://github.com/opencv-java/)找到源代碼和資源。

---

## 3.1 OpenCV的JavaFX應(yīng)用程序

??本教程將指導(dǎo)你使用Eclipse中的OpenCV庫(kù)來(lái)創(chuàng)建一個(gè)簡(jiǎn)單的JavaFX GUI應(yīng)用程序。

## 3.2 在本教程中要做什么

??在本教程中,我們將:

?????安裝**e(fx)clipse**插件和 _Scene Builder_ (*Scene Builder*安裝不做硬性要求);

?????使用 _Scene Builder_ ;

?????編寫并運(yùn)行應(yīng)用程序。

## 3.3 JavaFX中的第一個(gè)應(yīng)用程序

??本教程編寫出來(lái)的應(yīng)用程序?qū)⒉东@來(lái)自網(wǎng)絡(luò)攝像機(jī)的視頻流并將其顯示在圖形用戶界面(GUI)上。

??我們是使用Scene Builder來(lái)創(chuàng)建GUI的。創(chuàng)建完畢后,GUI將具有一個(gè)按鈕和一個(gè)簡(jiǎn)單的圖像視圖框,前者用于播放/關(guān)閉視頻流,后者用于放置視頻流幀。

## 3.4 安裝e(fx)clipse插件和Scene Builder

??請(qǐng)按照本教程的指導(dǎo)在Eclipse中安裝**e(fx)clipse**插件,本教程內(nèi)容詳見[http://www.eclipse.org/efxclipse/install.html#fortheambitious](http://www.eclipse.org/efxclipse/install.html#fortheambitious)。

??如果不想安裝此類插件,只需創(chuàng)建一個(gè)慣用的**Java項(xiàng)目**——*JavaFX Scene Builder 2.0*即可。請(qǐng)從[http://www.oracle.com/technetwork/java/javafxscenebuilder-1x-archive-2199384.html](http://www.oracle.com/technetwork/java/javafxscenebuilder-1x-archive-2199384.html)下載安裝*JavaFX Scene Builder 2.0*。

??現(xiàn)在可以來(lái)新建一個(gè)JavaFX項(xiàng)目了,具體操作為:

?????轉(zhuǎn)到“File > New > Project...”,選擇“JavaFX project....”;

![U8Puid.png](https://images.gitee.com/uploads/images/2020/0716/170447_07d86fe4_1464254.png)

?????輸入項(xiàng)目名稱(名稱自選),單擊“Next”;

![U8P7wD.png](https://images.gitee.com/uploads/images/2020/0716/170455_2965d862_1464254.png)

?????添加OpenCV用戶庫(kù)到剛剛創(chuàng)建的項(xiàng)目,單擊“Next”;

![U8iv4J.png](https://images.gitee.com/uploads/images/2020/0716/170447_73b87349_1464254.png)

?????分別選定Package名稱、*FXML文件*名稱以及*控制器類*名稱。關(guān)于你創(chuàng)建的GUI的描述將以FXML語(yǔ)言的形式包含在FXML文件中。而GUI組件與用戶交互時(shí)所必須調(diào)用、管理的方法和事件都將由*控制器類*處理。

## 3.5 使用Scene Builder

??如果之前已經(jīng)安裝過*Scene Builder*,就可以直接在Eclipse中右鍵單擊FXML文件然后選擇“Open with SceneBuilder”。

?? _Scene Builder_ 是通過與圖形界面交互來(lái)幫助構(gòu)建你的GUI的。這樣一來(lái),你就可以實(shí)時(shí)預(yù)覽你的窗口效果。此外,只需編輯圖形預(yù)覽即可實(shí)現(xiàn)GUI組件內(nèi)容的修改以及位置的調(diào)整。

??不妨來(lái)具體地看一看我到底在講些什么。

??*FXML文件*最開始只有一個(gè)*AnchorPane*。AnchorPane中,允許存在一個(gè)偏離距離,位于AnchorPane子節(jié)點(diǎn)邊緣錨定的位置與AnchorPane自身邊緣所在的位置之間。如果AnchorPane設(shè)置了border和(或)padding,則偏離距離要從它們的內(nèi)邊緣開始算起。對(duì)于受到AnchorPane管理的子節(jié)點(diǎn),無(wú)論它們是否可見,都將被AnchorPane一一展開。而非托管子節(jié)點(diǎn)則不會(huì)被AnchorPane展開。

??當(dāng)然,你也可以刪除AnchorPane并添加BorderPane。BorderPane在TOP、LEFT、RIGHT、BOTTOM以及CENTER這5個(gè)固定位置展開子節(jié)點(diǎn)。

![U8k6w8.png](https://images.gitee.com/uploads/images/2020/0716/170450_ecd69550_1464254.png)

??從“Container”菜單中拖拽一個(gè)BorderPane并將其放到“Hierarchy”菜單中,即可添加一個(gè)BorderPane。BorderPane添加完畢后,我們?cè)賮?lái)添加一個(gè)Button,它之后可以用來(lái)播放/關(guān)閉視頻流。從“Contols”菜單中拖拽一個(gè)Button并將其放到我們剛剛添加的BP(即BorderPane)的**BOTTOM**區(qū)域,Button就添加完成了。

??我們現(xiàn)在可以看到,界面的右方區(qū)域有3個(gè)菜單(“Properties”、“Layout”、“Code”),用于自定義被選中組件。例如,我們可以在“Properties”菜單下的“Text”區(qū)域修改之前添加的Button內(nèi)容為“StartCamera”,還可以在“Code”菜單下的“fx:id”區(qū)域修改Button的id(比如改成“start_btn”)。接下來(lái)在從**控制器**方法編輯button屬性時(shí),我們就需要用到button的id。

??在界面中還可以看到,button現(xiàn)在離窗口的距離特別近。因此要為button設(shè)置一定的下邊距。我們可以在“Layout”菜單中進(jìn)行相應(yīng)操作。

![U8kzOx.png](https://images.gitee.com/uploads/images/2020/0716/170449_80184d49_1464254.png)

![U8AEpd.png](https://images.gitee.com/uploads/images/2020/0716/170448_d93bfe99_1464254.png)

??為了能讓button正常運(yùn)行,我們必須在“Code”菜單下的“OnAction”這一欄設(shè)定好方法名稱(比如“startCamera”),此處設(shè)定的方法將執(zhí)行我們預(yù)想的功能。

![U8EPuq.png](https://images.gitee.com/uploads/images/2020/0716/170449_b1f17c57_1464254.png)

??然后從“Controls”菜單中拖拽一個(gè)*ImageView*添加到BP的**CENTER**區(qū)域中。同樣地,為ImageView設(shè)置一定的邊距并對(duì)其id加以修改(比如改成“currentFrame”)。

![U8EzdK.png](https://images.gitee.com/uploads/images/2020/0716/170450_2dc463fe_1464254.png)

??最后,必須指定一個(gè)控制器類去管理我們的GUI。為此,需添加我們之前選定的控制器類名稱到位于窗口左下方的“Controller”菜單下的“Controller class”這一欄。

??我們剛剛使用Scene Builder創(chuàng)建了我們第一個(gè)GUI。如果你現(xiàn)在保存文件回到Eclipse,你會(huì)看到Eclipse已經(jīng)自動(dòng)生成了某些FXML代碼。

## 3.6 JavaFX中的一些重要概念

??**Stage**:應(yīng)用程序顯示的地方(比如Windows窗口);

??**Scene**:即節(jié)點(diǎn)容器,此容器中的節(jié)點(diǎn)構(gòu)成了你的應(yīng)用程序的某個(gè)“頁(yè)面”;

??**Node**:Scene中的一個(gè)元素,具有可視化、可交互的特點(diǎn)。節(jié)點(diǎn)可能是以分層嵌套的形式存在于Scene中。

??在*Main類*中,我們需要將自身的*primary stage*傳遞給*start*函數(shù):

```

public void start(Stage primaryStage)

```

??也是在*Main類*中,我們還要載入FXML文件,該文件將會(huì)填充我們的Stage、Scene的*root element*以及控制器類:

```

FXMLLoader loader = new FXMLLoader(getClass().getResource("FXHelloCV.fxml"));

BorderPane root = (BorderPane) loader.load();

FXController controller = loader.getController();

```

## 3.7 使用控制器類管理GUI交互

??關(guān)于我們的JavaFX應(yīng)用程序,我們需要做兩件最基本的事:一是控制按下Button;二是控制刷新ImageView。為了實(shí)現(xiàn)上述操作,我們需要在GUI組件和控制器類變量間創(chuàng)建一個(gè)引用:

```

@FXML

private Button button;

@FXML

private ImageView currentFrame;

```

??**@FXML**標(biāo)簽用于鏈接變量到FXML文件中的某個(gè)元素,并且該變量值應(yīng)等于相鏈接的元素的id。

??**@FXML**標(biāo)簽用于某個(gè)元素設(shè)定的方法時(shí),功能同上。例如:

????對(duì)于:

```

```

????我們?cè)O(shè)置:

```

@FXML

protected void startCamera(ActionEvent event) { ...

```

## 3.8 視頻捕獲

??VideoCapture類基本上已經(jīng)整合了視頻處理所需要的一切函數(shù)。這是建立在FFmpeg開源庫(kù)的基礎(chǔ)上的。

```

private VideoCapture capture = new VideoCapture();

```

??一段視頻由若干連續(xù)的圖像組成,其中的這些圖像我們稱之為幀。視頻文件中,用幀率來(lái)明確兩幀之間的間隔時(shí)長(zhǎng)。而對(duì)于攝像機(jī)來(lái)說,每秒可數(shù)字化的幀數(shù)通常是有限制的。在這里,我們?cè)O(shè)置幀率為30幀/秒。為此我們需要初始化一個(gè)計(jì)時(shí)器(即`ScheduledExecutorService`),該計(jì)時(shí)器每33毫秒將會(huì)啟動(dòng)一次后臺(tái)任務(wù)。

```

Runnable frameGrabber = new Runnable() { ... }

this.timer = Executors.newSingleThreadScheduledExecutor();

this.timer.scheduleAtFixedRate(frameGrabber, 0, 33, TimeUnit.

?→ MILLISECONDS);

```

??要檢查VideoCapture類是否成功綁定了視頻源的話,我們需要使用**isOpened**函數(shù):

```

if (this.capture.isOpened()) { ... }

```

??視頻在其析構(gòu)函數(shù)被調(diào)用時(shí)就會(huì)自動(dòng)關(guān)閉。可是如果你想在此之前就關(guān)閉視頻的話,就需要調(diào)用其釋放函數(shù)了:

```

this.capture.release();

```

??鑒于視頻幀純粹就是圖像而已,所以我們只需要將它們從VideoCapture對(duì)象中提取出來(lái)再放入Mat 1即可。

```

Mat frame = new Mat();

```

??從“read”或“overloaded >> operator”讀取幀時(shí),由于視頻流都是連續(xù)的,所以幀可能是順次而出。

```

this.capture.read(frame);

```

??我們還需要將我們的圖像從*BGR*格式轉(zhuǎn)換成*灰度*圖。OpenCV中有一個(gè)非常好的函數(shù)可以完成此類轉(zhuǎn)換:

```

Imgproc.cvtColor(frame, frame, Imgproc.COLOR_BGR2GRAY);

```

??**從上面這行代碼可以看到,cvtColor用到以下參數(shù):**

???????**源圖像(frame);**

???????**目標(biāo)圖像(frame),用來(lái)保存轉(zhuǎn)換后的灰度圖;**

???????**附加參數(shù),用于指示將要執(zhí)行何種轉(zhuǎn)換。在這里使用的附加參數(shù)是COLOR_BGR2GRAY (不使用imread是因?yàn)閷?duì)于彩色圖像imread默認(rèn)使用BGR通道順序)。**

??為了能將捕獲的幀放入ImageView中,我們需要將矩陣轉(zhuǎn)換成圖像。具體操作如下:

?????首先,我們創(chuàng)建一個(gè)緩沖區(qū),用于存儲(chǔ)矩陣。

```

MatOfByte buffer = new MatOfByte();

```

?????然后,使用**imencode**函數(shù),將捕獲的幀放入緩沖區(qū),下列這行代碼便會(huì)將圖像編碼到內(nèi)存緩沖區(qū)中:

```

Imgcodecs.imencode(".png", frame, buffer);

```

????**imencode**函數(shù)壓縮圖像并存儲(chǔ)到內(nèi)存緩沖區(qū)中,內(nèi)存緩沖區(qū)會(huì)自適應(yīng)壓縮后圖像的大小。

---

**注意:** **imencode**函數(shù)返回**CV_8UC1**型的單行矩陣,被編碼成字節(jié)數(shù)組的圖像就包含在返回的矩陣中。

---

????**imencode函數(shù)用到3個(gè)參數(shù):**

???????**“.png”,即文件擴(kuò)展名,用于定義輸出格式;**

??????**?frame,即待寫入圖像;**

??????**?buffer,即輸出緩存區(qū),可以自適應(yīng)壓縮后圖像的大小。**

??將捕獲的幀放入緩存區(qū)后,我們就要用到**ByteArrayInputStream**來(lái)流式傳輸緩存區(qū)中被壓縮的圖像:

```

new Image(new ByteArrayInputStream(buffer.toArray()));

```

??通過流式傳輸?shù)玫叫碌膱D像后,我們就可以將其放到ImageView中。不過使用Java 1.8版本時(shí),我們是無(wú)法在與主線程不同的線程中更新GUI的元素的。因此我們需要先從其他的線程中獲取新幀,然后在主線程中刷新我們的ImageView:

```

Image imageToShow = grabFrame();

Platform.runLater(new Runnable() {

@Override public void run() { currentFrame.setImage(imageToShow); }

});

```

![U8u2zF.png](https://images.gitee.com/uploads/images/2020/0716/170452_e1829e8e_1464254.png)

一鍵復(fù)制

編輯

Web IDE

原始數(shù)據(jù)

按行查看

歷史

總結(jié)

以上是生活随笔為你收集整理的)类 新建javafx程序时_第三章 第一个OpenCV的JavaFX应用程序.md的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。