LoginSignup
0
1

More than 3 years have passed since last update.

Android で OpenCL の Image2D を使って画像変換する

Last updated at Posted at 2020-01-18

Android で OpenCL を試す
の続きです

OpenCL の Image2D

OpenCL では,基本的な1次元の配列の他に,
画像の2次元のデータを取り扱う Image2D というデータ型が用意されている。

使い方
clCreateImage2D を使って画像データから Image2D を作成する。
引数は、画像データが格納された1次元配列のアドレスを示すポインター。

カーネルプログラムからは、
read_imagef と write_imagef を使って読み書きする。

Image2D のサンプル

Image2D のサンプルコードとして、
github に公開されているものを試す。
パソコン向けのC++ 版なので、Android向けに変更する。

このサンプルはガウシアンフィルタを使って画像のぼかしを行う。

重みは 3x3 の基本的なもの

|1|2|1|
|2|4|2|
|1|2|1|

ぼかしの効果は画像を拡大しないとわからない。

ガウスぼかしの効果について記事を書いた。
OpenCL を使って ガウスぼかしをする

Android の画像から Image2D を作成する

当初は、Android の Bitmap から Image2D を作成しようとした。
先人の例があるだろと思ったが、全く見つからない。
結局、うまくいかなかった。

OpenCV の Maから Image2D を作成する例が見つかったので、
Mat を仲介役にした。

Java プログラム

画像を Bitmap 形式にする
Bitmap bitmap = BitmapFactory.decodeFile(pathName);

OpenCV の Mat 形式にする
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    Mat mat = new Mat(height, width, CvType.CV_8UC4);
    Utils.bitmapToMat(bitmap, mat);

native プログラムを呼ぶ
    ImageFilter(
            mat.getNativeObjAddr() );

    public native void ImageFilter(long matAddr);

native プログラム

JNIEXPORT void JNICALL
Java_jp_ohwada_android_opencl5_MainActivity_ImageFilter(
        jlong addr
        ) 
{

// 引数から Mat を復元する
    Mat& mat  = *(Mat*)addr;

    char *buffer = reinterpret_cast<char *>(mat.data);

 Image2D を作成する
    cl_mem image = clCreateImage2D(context,
                            CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
                            &clImageFormat,
                            width,
                            height,
                            0,
                            buffer,
                            &errNum);

アプリを作成する

OpenCL と OpenCV の環境が必要です。

下記を読んでください。

_ AndroidStudio で OpenCV をインポートする

(1) プロジェクトを作成する

(2) OpenCV の Android 用 SDK を用意する

(3) OpenCL のライブラリを用意する

(4) app/src/main/Assets フォルダーにOPenCLのカーネルプログラムファイルを配置する

(5) レイアウトファイルに ImageView を配置する

activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    <ImageView
        android:id="@+id/outputImageView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:src="@drawable/picture" />

(6) MainActivity を作成する

MainActivity.java
public class MainActivity extends Activity

    private native void nativeStepOpenCL (
// 詳細 略

(7) C++ のプログラムファイルを作成する

step.cpp
extern "C" void Java_com_intel_sample_androidbasicocl_MainActivity_nativeStepOpenCL
(
// 詳細 略

(8) CMakeLists.txt を作成する

CMakeLists.txt
add_library( # Sets the name of the library.
             ImageFilter2D

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             ImageFilter2D.cpp )

(9) app/build.gradle を変更する

build.gradle
    externalNativeBuild {
        cmake {
            path 'src/main/cpp/CMakeLists.txt'
        }
    }

アプリを実行する

analyze apk により下記の4つが同封されていることが確認できる。

  • libImageFilter2D.so
  • libOpenCL.so
  • libopencv_java4.so
  • libc++_shared.so

opencl5_analyze_apk.png

スクリーンショット
ぱっと見では、変換前後で違いがわからない。
左が変換前、右が変換後

opencl5_original.png pencl5_filtered.png

画像を拡大すると、ぼかしが効いているのがわかる
左が変換前、右が変換後

 opencl5_comparison.png

サンプルコードをgithub に公開した。
https://github.com/ohwada/Android_Samples/tree/master/OpenCL5

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1