adnroid openCv를 이용한 이미지 필터링에 대해 질문이 있습니다.

조회수 3032회

http://webnautes.tistory.com/1054 를 참고하여 C언어를 어떻게 안드로이드에서 사용해야할지 참고하였습니다. 이 예제는 사진을 찍을 때 카메라자체의 필터를 넣는 것이고 제가 하고 싶은 것은 이미 찍힌 이미지를 필터링하고 싶은 것이라 다른 예제를 찾아봤습니다. http://webnautes.tistory.com/1090 이걸보고 참고하였는데요.

이 예제같은 경우 제가 이해한대로 설명드리자면 src/main 경로에 assets 폴더를 생성하여 그 안에 있는 이미지파일을 빌드한 핸드폰의 저장소에 이미지를 복사붙여넣기하여 그 이미지를 c언어 코드상에서 로드하여 비트맵으로 생성하여 이미지필터링을 합니다.

코드는 아래와 같습니다.

filterActivity.java

private void copyFile(String filename) {// 파일 안드로이드에 저장
        String baseDir = Environment.getExternalStorageDirectory().getPath();
        String pathDir = baseDir + File.separator + filename;

        AssetManager assetManager = this.getAssets(); // asset파일에 접근할 수 있도록 하는 객체

        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {
            Log.d("opencv", "copyFile :: 다음 경로로 파일복사 " + pathDir);
            inputStream = assetManager.open(filename);
            outputStream = new FileOutputStream(pathDir);

            byte[] buffer = new byte[1024];
            int read;
            while ((read = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, read);
            }
            inputStream.close();
            inputStream = null;
            outputStream.flush();
            outputStream.close();
            outputStream = null;
        } catch (Exception e) {
            Log.d("opencv", "copyFile :: 파일 복사 중 예외 발생 " + e.toString());
        }

    }

    private void read_image_file() {
        copyFile("ball.jpg");

        img_input = new Mat();
        img_output = new Mat();

        loadImage("ball.jpg", img_input.getNativeObjAddr()); // 저장된 경로로 가서 이미지 로드해옴
    }

    private void imageprocess_and_showResult() { // 이미지 필터 처리

        imageprocessing(img_input.getNativeObjAddr(), img_output.getNativeObjAddr());

        Bitmap bitmapInput = Bitmap.createBitmap(img_input.cols(), img_input.rows(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(img_input, bitmapInput); //  유틸 클래스를 이용하여 bmp클래스로 변환
        filterIv.setImageBitmap(bitmapInput); // 필터링 전

        bitmapCandy = Bitmap.createBitmap(img_output.cols(), img_output.rows(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(img_output, bitmapCandy);
        outlv.setImageBitmap(bitmapCandy); // 필터링 후
    }




#include <jni.h>
#include <opencv2/opencv.hpp>
#include <android/asset_manager_jni.h>
#include <android/log.h>

using namespace cv;
using namespace std;


extern "C" {
JNIEXPORT jstring JNICALL
Java_com_blank_android_crafter_FilterImgActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}
JNIEXPORT void JNICALL
Java_com_sd_android_sd_write_Activity_loadImage(JNIEnv *env, jobject instance,
                                                                 jstring imageFileName_,
                                                                 jlong addrImage) {
    Mat &img_input = *(Mat *) addrImage;

    const char *nativeFileNameString = env->GetStringUTFChars(imageFileName_, JNI_FALSE);

    string baseDir("/storage/emulated/0/");
    baseDir.append(nativeFileNameString);
    const char *pathDir = baseDir.c_str();

    img_input = imread(pathDir, IMREAD_COLOR);
}

JNIEXPORT void JNICALL
Java_com_sd_android_sd_write_Activity_imageprocessing(JNIEnv *env,
                                                                       jobject instance,
                                                                       jlong addrInputImage,
                                                                       jlong addrOutputImage) {

    Mat &img_input = *(Mat *) addrInputImage;
    Mat &img_output = *(Mat *) addrOutputImage;

    cvtColor(img_input, img_input, CV_BGR2RGB);
    cvtColor(img_input, img_output, CV_RGB2GRAY);
    blur(img_output, img_output, Size(5, 5));
    Canny(img_output, img_output, 50, 150, 5);

}
}

저는 카메라로 찍은 사진을 bitmap으로 생성하여 intent로 filterActivity로 bitmap을 넘깁니다.

Intent intent = getIntent();
bm = (Bitmap) intent.getParcelableExtra("bitmap");

이 bitmap으로 이미지필터링하고 싶은데 어떻게 해야할지 모르겠습니다. 우선 bitmapCandy 객체대신 bm을 넣어봤는데 에러가 뜨더라고요.ㅠㅠ

    private void imageprocess_and_showResult() { // 이미지 필터 처리

        imageprocessing(img_input.getNativeObjAddr(), img_output.getNativeObjAddr());

        Bitmap bitmapInput = Bitmap.createBitmap(img_input.cols(), img_input.rows(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(img_input, bitmapInput); //  유틸 클래스를 이용하여 bmp클래스로 변환
        filterIv.setImageBitmap(bitmapInput); // 필터링 전

        bitmapCandy = Bitmap.createBitmap(img_output.cols(), img_output.rows(), Bitmap.Config.ARGB_8888);
        Utils.matToBitmap(img_output, bm);
        outlv.setImageBitmap(bm); // 필터링 후
    }

아무리 찾아봐도 어떻게 해야할지 모르겠습니다 알려주시면 감사하겠습니다.

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 자문자답입니다. intent로 넘어온 bitmap을 예제와 같이 핸드폰에 저장을 하고 이미지필터링하는 식으로 구현하였습니다.

    이 방식말고 저장없이 구현하는 방법아시는 분 답변해주시면 감사하겠습니다.

    • (•́ ✖ •̀)
      알 수 없는 사용자

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)