【Android】【opencv】實現攝像頭拍照和錄影
後面可以疊加物體檢測,參考:https://github.com/kongqw/OpenCVForAndroid
1.0 需求
在安卓開發板上實現視訊監控功能,並能後臺監控。
由於後期可能跑視訊識別,所以考慮用OpenCV實現:通過OpenCV Manager進行動態庫的連結,實現幀的預覽和儲存。
android版本:5.0.1
開發平臺:Android Studio 3.1.2
OpenCV版本:opencv4android 3.2.0
OpenCV Manager:OpenCV_3.2.0_Manager_3.20_armeabi.apk
2.0 步驟
2.1 下載opencv-3.2.0-android-sdk.zip
可以直接去官網下載。如果下載很慢,可以切換源試試
解壓後,會看到OpenCV-android-sdk目錄下有如下目錄:
2.2 開發板安裝對應的OpenCV Manage版本
OpenCV_3.2.0_Manager_3.20_armeabi.apk
2.3 新建工程VideoMonitor並匯入Opencv Module
具體步驟: File --> New --> Import Module選擇opencv-3.2.0-android-sdk下的java目錄
選擇步驟2.1下載的opencv-3.2.0-android-sdk目錄下的如下目錄:
工程匯入完會看到project下有openCVLibrary320:
2.4 新增工程依賴(opencv)
點選Project Structure:
點選Dependencies --> 點選+ --> 選擇module dependency
2.5 把opencv要用到的動態庫放到專案中
將下載解壓得到的檔案中的“sdk\native\libs\”複製一份到專案的“app\src\main\”並重新命名為jniLibs:
2.6 修改佈局檔案
佈局修改如下:
這裡的JavaCameraView就是OpenCV裡的預覽部件,然後我們再新增了一個拍照的按鍵。
注意:之前忘記新增opencv,導致R檔案生成失敗,MainActivity中R類就找不到了。
2.7 新增許可權
開啟AndroidManifest.xml,新增我們需要的許可權,攝像頭和內部儲存,這個也十分重要:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2.8 正式編寫MainActivity
具體程式碼如下:
package cn.com.suredata.videomonitor;
import android.content.pm.ActivityInfo;
import android.icu.text.SimpleDateFormat;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import java.io.File;
import java.util.Date;
public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2 {
private String TAG = "OpenCV_Test";
//OpenCV的相機介面
private CameraBridgeViewBase mCVCamera;
//快取相機每幀輸入的資料
private Mat mRgba;
private Button button;
/**通過OpenCV管理Android服務,初始化OpenCV**/
BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
Log.i(TAG, "OpenCV loaded successfully");
mCVCamera.enableView();
break;
default:break;
}
}
};
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
super.handleMessage(msg);
if(msg.what == 1){
button.performClick();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化並設定預覽部件
mCVCamera = (CameraBridgeViewBase) findViewById(R.id.camera_view);
mCVCamera.setCvCameraViewListener(this);
//拍照按鍵
button = (Button) findViewById(R.id.deal_btn);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mRgba != null) {
if(!mRgba.empty()) {
Mat inter = new Mat(mRgba.width(), mRgba.height(), CvType.CV_8UC4);
Log.e("Mat","...............1...............");
//將四通道的RGBA轉為三通道的BGR,重要!!
Imgproc.cvtColor(mRgba, inter, Imgproc.COLOR_RGBA2BGR);
Log.e("Mat","...............2...............");
File sdDir = null;
//判斷是否存在機身記憶體
boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
if(sdCardExist) {
//獲得機身儲存根目錄
sdDir = Environment.getExternalStorageDirectory();
Log.e("Mat","...............3...............");
}
//將拍攝準確時間作為檔名
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
String filename = sdf.format(new Date());
String savepath=sdDir + "/Pictures/OpenCV/";
File f=new File(savepath);
if(!f.exists()){
f.mkdirs();
}
String filePath = sdDir + "/Pictures/OpenCV/" + filename + ".png";
Log.e("Mat","..............."+filePath+"...............");
//將轉化後的BGR矩陣內容寫入到檔案中
Imgcodecs.imwrite(filePath, inter);
Toast.makeText(MainActivity.this, "圖片儲存到: "+ filePath, Toast.LENGTH_SHORT).show();
}
}
}
});
// moveTaskToBack(true);
// new test().start();
}
private class test extends Thread{
@Override
public void run() {
super.run();
while (true){
try {
Thread.sleep(2000);
Log.e("begin","kaishi.........");
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}catch (Exception e){
Log.e("error",e.getMessage());
}
}
}
}
@Override
protected void onResume() {
/***強制橫屏***/
if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
//橫屏後才載入部件,否則會FC
if(!OpenCVLoader.initDebug()) {
Log.d(TAG, "OpenCV library not found!");
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
super.onResume();
}
@Override
protected void onDestroy() {
if(mCVCamera != null) {
mCVCamera.disableView();
}
super.onDestroy();
}
//物件例項化及基本屬性的設定,包括長度、寬度和影象型別標誌
public void onCameraViewStarted(int width, int height) {
Log.e("Mat","...............4...............");
mRgba = new Mat(height, width, CvType.CV_8UC4);
}
/**影象處理都寫在這裡!!!**/
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba(); //一定要有!!!不然資料儲存不進MAT中!!!
//直接返回輸入視訊預覽圖的RGB資料並存放在Mat資料中
Log.e("Mat","...............5...............");
return mRgba;
}
//結束時釋放
@Override
public void onCameraViewStopped() {
Log.e("Mat","...............6...............");
mRgba.release();
// mTmp.release();
}
}
相關文章
- Android呼叫攝像頭拍照Android
- Android 呼叫攝像頭拍照Android
- C#實現攝像頭呼叫、拍照C#
- android opencv 前置攝像頭AndroidOpenCV
- Android提供的攝像頭拍照Android
- html5呼叫攝像頭實現拍照HTML
- 安卓呼叫攝像頭拍照安卓
- 照片系列之android呼叫攝像頭拍照Android
- Android開發之呼叫攝像頭拍照Android
- 專案實戰:Qt+Ffmpeg+OpenCV相機程式(開啟攝像頭、支援多種攝像頭、解析度調整、翻轉、旋轉、亮度調整、拍照、錄影、回放圖片、回放錄影)QTOpenCV
- Android呼叫攝像頭拍照並顯示照片Android
- Android 呼叫攝像頭功能【拍照與視訊】Android
- python版opencv:如何用筆記本攝像頭拍照儲存PythonOpenCV筆記
- 純JavaScript實現的呼叫裝置攝像頭並拍照的功能JavaScript
- 如何使用HTML5實現利用攝像頭拍照上傳功能HTML
- 《OpenCV設定和獲取攝像頭引數》OpenCV
- OpenCV攝像頭標定(待修改)OpenCV
- 在Android中呼叫攝像頭拍照並顯示出來Android
- Android多媒體應用開發-控制攝像頭拍照Android
- win10如何開啟電腦攝像頭錄影_win10用電腦自帶攝像頭錄影的方法Win10
- Python opencv USB攝像頭 讀寫PythonOpenCV
- Android呼叫攝像頭Android
- Maui Blazor 使用攝像頭實現UIBlazor
- 瀏覽器呼叫攝像頭進行拍照程式瀏覽器
- AngularJS中使用HTML5攝像頭拍照AngularJSHTML
- android 開啟攝像頭Android
- 修正Android攝像頭APIAndroidAPI
- Android如何呼叫攝像頭Android
- Android 用MultiImageSelector實現上傳頭像的拍照跟相簿Android
- Android 圓形頭像 相簿和拍照裁剪選取Android
- C# 使用AForge呼叫筆記本攝像頭拍照C#筆記
- iPhone XS/iPhone XS Max攝像頭拍照解析:蘋果也玩起了AI拍照iPhone蘋果AI
- android studio呼叫攝像頭拍照及具體步驟演示程式碼Android
- win10錄影在哪裡_win10開啟攝像頭錄影的步驟Win10
- 手機攝像頭改裝手機攝像頭監控移動到頂部或者底部USB外接鎖屏錄影後臺錄影教程軟體
- web呼叫攝像頭拍照並上傳到伺服器Web伺服器
- MiniVCap 用普通usb攝像頭做視訊錄影軟體!可長期持續錄影
- [譯]Android的多攝像頭支援Android