我们如何在Android中使用opencv(Opencv4Android)在摄像机的实时流视频帧上执行某些基本的图像处理技术?
答案 0 :(得分:6)
有了这些信息,我们无能为力。但是,我会发布一些代码,用于对相机流执行简单的图像处理技术:将帧转换为灰度。
您需要声明以下内容:
private CameraBridgeViewBase mOpenCvCameraView;
public CvCameraViewListener2 camListener;
然后,您需要初始化OpenCV。在调用onCreate()
方法之前,您需要添加以下代码块:
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i("TAG", "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
System.loadLibrary("nameOfYourNativeLibrary"); // if you are working with JNI
run();
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
你可以打电话
if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback)){
Log.e("ERR", "Cannot connect to OpenCV Manager");
}else Log.i("SUCCESS", "opencv successfull");
在onCreate()
方法中,但真正需要的是覆盖onResume()
方法:
@Override
public void onResume()
{
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
mOpenCvCameraView.enableView();
}
mOpenCvCameraView
是JavaCameraView
。如果您不熟悉这些内容,这是xml
的{{1}}布局:
MainActivity
因此,您的<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:opencv="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.yourapp.MainActivity$PlaceholderFragment" >
<org.opencv.android.JavaCameraView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
android:id="@+id/HelloOpenCvView"
opencv:show_fps="false"
opencv:camera_id="any" />
</RelativeLayout>
方法应如下所示:
onCreate()
在缺少@Override
public void onCreate(Bundle savedInstanceState) {
Log.i("APP", "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.fragment_main);
mOpenCvCameraView = (CameraBridgeViewBase)findViewById(R.id.HelloOpenCvView);
if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback)){
Log.e("OPENCV", "Cannot connect to OpenCV Manager");
}else Log.i("OPENCV", "opencv successfull");
}
方法中,您应该添加要执行的图像处理。在这种情况下,我们将帧转换为灰度并显示它们:
run()
我希望这会有所帮助。如果您还有其他需要,请告诉我。
<强>更新强>
如果要访问private void run(){
camListener = new CvCameraViewListener2() {
@Override
public void onCameraViewStopped() {
// TODO Auto-generated method stub
}
@Override
public void onCameraViewStarted(int width, int height) {
// TODO Auto-generated method stub
}
@Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
rgb = inputFrame.rgba();
// here you could just return inputframe.gray(), but for illustration we do the following
Mat gray = new Mat();
Imgproc.cvtColor(rgb, gray, Imgproc.COLOR_RGB2GRAY);
return gray;
}
};
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(camListener);
}
对象的像素值,则需要以下内容:
Mat
请注意,在这种情况下,我的double mean = 0;
double size = mat.rows()*mat.cols();
for(int k=0; k<mat.rows(); k++){
for(int j=0; j<mat.cols(); j++){
mean += mat.get(k, j)[0]/size;
}
}
对象只有一个频道(这意味着如果您尝试访问Mat
,您将获得mat.get(k, j)[1]
。对于RGB Array out of bounds exception
个对象您应该可以访问所有Mat
,mat.get(k, j)[0]
和mat.get(k, j)[1]