본문 바로가기

Android

Android OpenCV 샘플코드

 

현재 나만의 프로젝트 생성으로 OpenCV 를 import 하여 영상처리할 수 있는 환경을 구축하지는 못했다.

대부분의 블로그들이 OpenCV 샘플코드를 이용하여 개발환경이 되었다고 하였는데 이는 완벽한 환경이 아니지 않나..?

 

나중에 알게되면..포스팅을하겠지만 자료가 너무나도 부족해 일단은

샘플코드를 분석해본다.

 

native 코드가 포함된 샘플소스인 tutorial 2 Advanced - 1.Add Native OpenCV 프로젝트를 사용해보았다.

 

개인적으로 opencv라이브러리를 include 하면 경로문제로 힘들었는데 이 샘플에선 문제없나보다..

일단 기본적인 native 함수 원형 생성은 넘어가겠다..

내용에 있어서 보아하니 Mat 구조체를 쓰나보다....

주로 Opencv2.1에서 벗어나지 못하다가 최근 버전업을 해보았는데

방금 알아보니 이미지 픽셀데이터 접근방식이 벡터방식(C++) 로 바뀌었다고 한다....

Mat 구조체의 접근방식을 알아봐야한다.

 

 


#include <jni.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <vector>

using namespace std;
using namespace cv;

extern "C" {
JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial3_Sample3View_FindFeatures

(JNIEnv* env, jobject thiz, jint width, jint height, jbyteArray yuv, jintArray bgra)
{
    jbyte* _yuv  = env->GetByteArrayElements(yuv, 0);
    jint*  _bgra = env->GetIntArrayElements(bgra, 0);
 
 
    Mat myuv(height + height/2, width, CV_8UC1, (unsigned char *)_yuv);
    Mat mbgra(height, width, CV_8UC4, (unsigned char *)_bgra);

  //_bgra int형 배열로부터 8bit 4채널로 바꿔 mbgra라는 Mat 구조체
    Mat mgray(height, width, CV_8UC1, (unsigned char *)_yuv); 

//_bgra int형 배열로부터 8bit 1채널로 바꿔 mbgra라는 Mat 구조체

    //Please make attention about BGRA byte order
    //ARGB stored in java as int array becomes BGRA at native level
    cvtColor(myuv, mbgra, CV_YUV420sp2BGR, 4); //YUV로 들어온 색상체계를 BGR로 바꾼다.

   //일부 CV_YUV420sp2BGR이 안먹힌다. sp를 i로 바꿔서 해도 무방할듯..?

    vector<KeyPoint> v;

    FastFeatureDetector detector(50); //특징점 추출 함수 호출
    detector.detect(mgray, v);  //특징점 추출 함수 호출
    for( size_t i = 0; i < v.size(); i++ ) //특징점이 저장된 v 벡터를 중점으로 CIRCLE을 그려준다.
        circle(mbgra, Point(v[i].pt.x, v[i].pt.y), 10, Scalar(0,0,255,255));

 

 

//픽셀데이터 접근 추가사항(본인이 추가한 내용이다.)

for(int co=0; co<mbgra.cols; co++)
{
 for(int ro=0; ro<mbgra.rows; ro++)
 {
  mbgra.at<Vec4b>(ro,co)[0] = 255; // 블루(Blue)값을 255로 바꿔준다.
 // mbgra.at<Vec4b>(ro,co)[1] = 255; //이것들까지 바꾸면 하얀색 화면을 보게될것이다.
 // mbgra.at<Vec4b>(ro,co)[2] = 255;
 }

}

 

 

//메모리 해제

   env->ReleaseIntArrayElements(bgra, _bgra, 0);
    env->ReleaseByteArrayElements(yuv, _yuv, 0);
}

}

 


정확하지 않고 구글링과 개인적인 추측으로만 위 코드를 해설하자면,,,,


jbyte* 와 jint* 는 포인터형으로 들어온 배열로부터 각 요소들을 참조하여 각각 _yuv, _bgra 를 만들었다.

Mat 형 구조체를 만들어 들어온 data[]와 rgba[] 주소를 참조하게 정의하였다. Mat 함수형은 아주 많은 오버로딩이 되어있었다..

myuv는 입력데이터 주소를 읽어 1채널로 만든것이고

mbgra는 4채널 8bit로 최종데이터 int형 배열 주소를 참조하도록하였다. (비어있는 상태)

cvtColor 함수를 사용하여 myuv데이터를 YUV상태에서 BGR 체계로 변환한다. (4채널이다.)

변환 결과데이터는 mbgra에 넣도록 하였다.

vector 선언하고 detector을 이용하여 특징점을 추출한다.

v.size만큼 돌면서 v[벡터 인덱스] 의 포인터를 중심으로 서클을 그려준다.


추가로 픽셀데이터에 접근을 하는 방법을 찾아보았다.

 Mat image 가 선언되었다는 가정하에.

주로 쓰이는 방법으로는

image.at<Vec3b>(x,y)[0] //B 

image.at<Vec3b>(x,y)[1] //G

image.at<Vec3b>(x,y)[2] //R


내가 이전에 데이터에 접근하는 방식과 유사한 방법으로 보인다.

아직 이방법은 확인을 못했다. 화면이 정상적으로 안나오는데 이것때문인지는 확인못했다.

image.data[image.channels()*image.cols*y + x + 0] // B

image.data[image.channels()*image.cols*y + x + 1] // G

image.data[image.channels()*image.cols*y + x + 2] // R


3차원으로는

image.at<uchar>(0,0,0) 처럼 쓰일 수도 있나보다(?)


 

 

 간단한 샘플소스 + 이미지 데이터 접근으로 

 

<기본 샘플을 안드로이드에서 돌려봤을때이다.>

 

 

 <위 소스에서 필자가 추가한 데이터에서 Blue값을 255로 주었을 때 화면이다.>




 


 

 

 

'Android' 카테고리의 다른 글

[JNI] JNI 형식 및 데이터 구조  (0) 2012.07.03
[JNI] GetByteArrayElements  (0) 2012.07.03
Eclipse에서 JavaCV 설치/사용  (4) 2012.06.10
카메라 뷰와 촬영 예제  (3) 2012.06.07
Android + NDK + OpenCV  (0) 2012.06.01