astrgan 2 Жалоба Опубликовано December 14, 2013 Подскажите пожалуйста. Как я понимаю программа начинается с метода . mOpenCvCameraView.setCvCameraViewListener(this); это установка "слушителя" который будет следить за изменением чего-то. Если так, то где обработчик. В общем если не трудно объясните в каком порядке будут вызывается методы или хотя бы что будет работать после метода onCreate. public class Tutorial1Activity extends Activity implements CvCameraViewListener2 { private static final String TAG = "OCVSample::Activity"; private CameraBridgeViewBase mOpenCvCameraView; private boolean mIsJavaCamera = true; private MenuItem mItemSwitchCamera = null; 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(); } break; default: { super.onManagerConnected(status); } break; } } }; public Tutorial1Activity() { Log.i(TAG, "Instantiated new " + this.getClass()); } /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { Log.i(TAG, "called onCreate"); super.onCreate(savedInstanceState); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.tutorial1_surface_view); if (mIsJavaCamera) mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view); else mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_native_surface_view); mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); mOpenCvCameraView.setCvCameraViewListener(this); } @Override public void onPause() { super.onPause(); if (mOpenCvCameraView != null) mOpenCvCameraView.disableView(); } @Override public void onResume() { super.onResume(); OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback); } public void onDestroy() { super.onDestroy(); if (mOpenCvCameraView != null) mOpenCvCameraView.disableView(); } @Override public boolean onCreateOptionsMenu(Menu menu) { Log.i(TAG, "called onCreateOptionsMenu"); mItemSwitchCamera = menu.add("Toggle Native/Java camera"); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { String toastMesage = new String(); Log.i(TAG, "called onOptionsItemSelected; selected item: " + item); if (item == mItemSwitchCamera) { mOpenCvCameraView.setVisibility(SurfaceView.GONE); mIsJavaCamera = !mIsJavaCamera; if (mIsJavaCamera) { mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_java_surface_view); toastMesage = "Java Camera"; } else { mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial1_activity_native_surface_view); toastMesage = "Native Camera"; } mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); mOpenCvCameraView.setCvCameraViewListener(this); mOpenCvCameraView.enableView(); Toast toast = Toast.makeText(this, toastMesage, Toast.LENGTH_LONG); toast.show(); } return true; } public void onCameraViewStarted(int width, int height) { } public void onCameraViewStopped() { } public Mat onCameraFrame(CvCameraViewFrame inputFrame) { return inputFrame.rgba(); } } Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано December 14, 2013 Вызывется onCreate -> onResume -> OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback); Из mLoaderCallback когда opencv загружена вызывается public void onManagerConnected В этом методе и после того как он отработал можно инициализировать матрицы и вызывать методы opencv, до этого нельзя (можно только объявлять матрицы и т.д.). из этой же функции инициализируется захват с камеры mOpenCvCameraView.enableView(); Так как класс реализует методы CvCameraViewListener2 у него есть калбэки: OnCameraViewStarted - говорит само за себя. public Mat onCameraFrame(CvCameraViewFrame inputFrame) - тоже. Вообще почитайте про жизненный цикл приложения андроид, там все не так уж сложно. 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
astrgan 2 Жалоба Опубликовано December 14, 2013 А это "mOpenCvCameraView.setCvCameraViewListener(this);" инициализируется обработчик камеры? Метод "onCameraFrame" запускается всякий раз когда с камеры приходит новое изображение? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
astrgan 2 Жалоба Опубликовано December 14, 2013 P.S. Большое спасибо!) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано December 14, 2013 Так как класс нашего Activity реализует (implements) CvCameraViewListener2, то это означает что мы можем указать его в качестве приемника событий камеры (в виде this) когда вызываем mOpenCvCameraView.setCvCameraViewListener(this); Этим самым мы вешаем методы onCamera.... на события камеры. Да, метод onCameraFrame вызывается по приходу каждого кадра. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
astrgan 2 Жалоба Опубликовано December 15, 2013 Хочу обрезать изображение и вывести его на экран. Пытаюсь сделать так: public Mat onCameraFrame(CvCameraViewFrame inputFrame) { Mat roiM = inputFrame.gray(); Rect roi = new Rect(300, 50, 50, 10); return roiM.submat(roi); } но приложение не работает( Подскажите пожалуйста как сделать правильно. P.S. переделываю стандартный пример "tutorial-1-camerapreview" Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
astrgan 2 Жалоба Опубликовано December 15, 2013 Пробовал еще так: public Mat onCameraFrame(CvCameraViewFrame inputFrame) { Rect roi = new Rect(300, 50, 50, 10); Mat roiM = new Mat (inputFrame.gray(),roi); return roiM; } Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано December 15, 2013 Думается мне, что размер возвращаемого кадра должен совпадать с исходным. Ведь он потом показывается на поверхности вывода. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
astrgan 2 Жалоба Опубликовано December 15, 2013 А вообще если я хочу скопировать некую прямоугольную часть изображения в др. экземпляр класса mat, то такой код верен? Rect roi = new Rect(300, 50, 50, 10); imageRIO = image.submat(roi); или так: Rect roi = new Rect(300, 50, 50, 10); imageRIO.copyTo(image.submat(roi)); Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
astrgan 2 Жалоба Опубликовано December 15, 2013 А поверхность вывода прописана в xml? Что и где мне надо подправить если я хочу выводить на экран не все картинку, а только некоторую ее часть (например 1/3 от размера оригинала). Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано December 15, 2013 Должно работать, я бы еще clone() в конце приписал, но может я и не прав, я в андроиде с Opencv почти не работал . Если нужен вывод в своем собственном размере нужно написать свой класс наподобие CameraBridgeViewBase. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
astrgan 2 Жалоба Опубликовано December 15, 2013 А как получить доступ к самому массиву с изображениям? Вот здесьвроде описано, но актуально ли? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах