Java — растровые изображения в Android и Mat в OpenCV

У меня есть этот код в OpenCV C ++:

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;

int main(){
Mat src = imread("image.jpg");
if (src.empty())
return -1;
pyrMeanShiftFiltering(src,src,10,20,1);
imshow("src", src);
waitKey(0);
return 0;
}

И этот класс Sample1View.java из OpenCV 2.4.2 в качестве примера с именем «OpenCV Tutorial 1 — Add OpenCV»:

import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;

class Sample1View extends SampleViewBase {
public static final int     VIEW_MODE_RGBA  = 0;
public static final int     VIEW_MODE_GRAY  = 1;
public static final int     VIEW_MODE_CANNY = 2;
private Mat mYuv;
private Mat mRgba;
private Mat mGraySubmat;
private Mat mIntermediateMat;
private Bitmap mBitmap;
private int mViewMode;

public Sample1View(Context context) {
super(context);
mViewMode = VIEW_MODE_RGBA;
}

@Override
protected void onPreviewStarted(int previewWidth, int previewHeight) {
synchronized (this) {
// initialize Mats before usage
mYuv = new Mat(getFrameHeight() + getFrameHeight() / 2, getFrameWidth(), CvType.CV_8UC1);
mGraySubmat = mYuv.submat(0, getFrameHeight(), 0, getFrameWidth());
mRgba = new Mat();
mIntermediateMat = new Mat();
mBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Bitmap.Config.ARGB_8888);
}
}

@Override
protected void onPreviewStopped() {
if(mBitmap != null) {
mBitmap.recycle();
}

synchronized (this) {
// Explicitly deallocate Mats
if (mYuv != null)
mYuv.release();
if (mRgba != null)
mRgba.release();
if (mGraySubmat != null)
mGraySubmat.release();
if (mIntermediateMat != null)
mIntermediateMat.release();
mYuv = null;
mRgba = null;
mGraySubmat = null;
mIntermediateMat = null;
}
}

@Override
protected Bitmap processFrame(byte[] data) {
mYuv.put(0, 0, data);
final int viewMode = mViewMode;

switch (viewMode) {
case VIEW_MODE_GRAY:
Imgproc.cvtColor(mGraySubmat, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
break;
case VIEW_MODE_RGBA:
Imgproc.cvtColor(mYuv, mRgba, Imgproc.COLOR_YUV420sp2RGB, 4);
Core.putText(mRgba, "OpenCV + Android", new Point(10, 100), 3/* CV_FONT_HERSHEY_COMPLEX */, 2, new Scalar(255, 0, 0, 255), 3);
break;
case VIEW_MODE_CANNY:
Imgproc.Canny(mGraySubmat, mIntermediateMat, 80, 100);
Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_GRAY2BGRA, 4);
break;
}

Bitmap bmp = mBitmap;

try {
Utils.matToBitmap(mRgba, bmp);
} catch(Exception e) {
Log.e("org.opencv.samples.tutorial1", "Utils.matToBitmap() throws an exception: " + e.getMessage());
bmp.recycle();
bmp = null;
}
return bmp;
}

public void setViewMode(int viewMode) {
mViewMode = viewMode;
}
}

Теперь я хочу, чтобы мой код работал на Android, поэтому я заменил эту строку:

case VIEW_MODE_GRAY:
Imgproc.cvtColor(mGraySubmat, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
break;

к этому:

case VIEW_MODE_GRAY:
Imgproc.cvtColor(mGraySubmat, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
Imgproc.pyrMeanShiftFiltering(mRgba,mRgba,10,20);
break;

но я получаю это:

10-20 11:08:45.929: I/Sample::Activity(12846): Menu Item selected Preview GRAY
10-20 11:08:46.049: W/dalvikvm(12846): threadid=9: thread exiting with uncaught exception (group=0x4013a560)
10-20 11:08:46.059: E/AndroidRuntime(12846): FATAL EXCEPTION: Thread-10
10-20 11:08:46.059: E/AndroidRuntime(12846): CvException [org.opencv.core.CvException: ..\..\modules\imgproc\src\segmentation.cpp:345: error: (-210) Only 8-bit, 3-channel images are supported in function void cvPyrMeanShiftFiltering(const CvArr*, CvArr*, double, double, int, CvTermCriteria)
10-20 11:08:46.059: E/AndroidRuntime(12846): ]
10-20 11:08:46.059: E/AndroidRuntime(12846):    at org.opencv.imgproc.Imgproc.pyrMeanShiftFiltering_1(Native Method)
10-20 11:08:46.059: E/AndroidRuntime(12846):    at org.opencv.imgproc.Imgproc.pyrMeanShiftFiltering(Imgproc.java:7247)
10-20 11:08:46.059: E/AndroidRuntime(12846):    at com.duckie.a.Sample1View.processFrame(Sample1View.java:80)
10-20 11:08:46.059: E/AndroidRuntime(12846):    at com.duckie.a.SampleViewBase.run(SampleViewBase.java:185)
10-20 11:08:46.059: E/AndroidRuntime(12846):    at java.lang.Thread.run(Thread.java:1019)

В чем проблема? Как мне заставить мой код работать в Android? И как мне сделать это без задержки?

1

Решение

Кажется, что cvPyrMeanShiftFiltering ожидает 3-канальное изображение, и вы генерируете 4-канальное изображение с:

Imgproc.cvtColor(mGraySubmat, mRgba, Imgproc.COLOR_GRAY2RGBA, 4);
3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector