我在 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;
}
这个来自 OpenCV 2.4.2 的 Sample1View.java 类作为一个名为“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 中运行?而且,我该如何做到这一点而不会有延迟?