如何在Android NDK上使用OpenGL ES 2.0渲染OpenCV Mat?

时间:2017-09-27 05:54:37

标签: android opencv opengl-es android-ndk textureview

我已经在Android NDK中使用了cv :: Mat

cv::Mat grayMat;
grayMat.create(480, 720, CV_8UC1);

和JAVA中的TextureView。

public class MainActivity extends Activity implements TextureView.SurfaceTextureListener{
   private TextureView mTextureView;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      mTextureView = new TextureView(this);
      mTextureView.setSurfaceTextureListener(this);
   }
   ....
}

为什么:我在NDK中使用OpenCV进行一些图像处理。现在,我正在使用将结果保存为.jpg并在ImageView上显示的方法。但下一步我将使用相机预览进行一些处理。我不想保存每个帧以查看结果。

目标:在Android上显示cv :: Mat

问题:如何在NDK中使用OpenGL ES 2.0显示cv :: Mat?

1 个答案:

答案 0 :(得分:0)

如果要在Android中显示Mat,可以将Mat转换为像素,然后将像素传递给Android。在Android中,您可以将像素转换为位图以进行显示。

这是获取Mat中像素的代码。

int* getPixel(Mat src){
    int w = src.cols;
    int h = src.rows;
    int* result = new int[w*h];

    int channel = src.channels();
    if(channel == 1){
        for (int i = 0; i < w; i++) {
            for (int j = 0; j < h; j++) {
                int value = (int)(*(src.data + src.step[0] * j + src.step[1] * i));
                result[j*w+i] = rgb(value, value, value);
            }
        }
    }else if(channel == 3 || channel == 4){
        for (int i = 0; i < w; i++){
            for (int j = 0; j < h; j++){
                int r = (int)(*(src.data + src.step[0] * j + src.step[1] * i + src.elemSize1() * 2));
                int g = (int)(*(src.data + src.step[0] * j + src.step[1] * i + src.elemSize1()));
                int b = (int)(*(src.data + src.step[0] * j + src.step[1] * i));
                result[j*w+i] = rgb(r, g, b);
            }
        }
    }
    return result;
}

int rgb(int red, int green, int blue) {
    return (0xFF << 24) | (red << 16) | (green << 8) | blue;
}

获取带有像素的位图(也需要宽度和高度)。

Bitmap bmpReturn = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
bmpReturn.setPixels(matPixels, 0, width, 0, 0, width, height);