这是我的jni文件native.cpp
extern "C"
Java_org_opencv_samples_NativeActivity_CvNativeActivity_CannyJNI(
JNIEnv* env, jobject thiz,
jint height, jint width, jintArray in, jintArray out)
{
//get the data pointer.
jint* _in = env->GetIntArrayElements(in, 0);
jint* _out = env->GetIntArrayElements(out, 0);
//Build the Mat structure for input data
Mat mSrc(height, width, CV_8UC4, (unsigned char *)_in);
//Build the Mat structure for output data
Mat bgr(height, width, CV_8UC4, (unsigned char *)_out);
//Convert Mat to IplImage
IplImage mSrcImg = mSrc;
IplImage mOutImg = bgr;
//Create the gray image for input data.
IplImage * mSrcGrayImg = cvCreateImage(cvGetSize(&mSrcImg), mSrcImg.depth, 1);
IplImage * mOutGrayImg = cvCreateImage(cvGetSize(&mSrcImg), mSrcImg.depth, 1);
IplImage *b,*g,*r;
b = cvCreateImage( cvGetSize(mSrcGrayImg), 8, 1 );
g = cvCreateImage( cvGetSize(mSrcGrayImg), 8, 1 );
r = cvCreateImage( cvGetSize(mSrcGrayImg), 8, 1 ) ;
cvSplit(&mSrcImg, b, g, r, 0 );
cvEqualizeHist( b, b );
cvEqualizeHist( g, g );
cvEqualizeHist( r, r );
cvMerge(b,g,r,0,&mOutImg);
//release the pointer.
env->ReleaseIntArrayElements(in, _in, 0);
env->ReleaseIntArrayElements(out, _out, 0);
return true;
}
当我添加这两行时,我的每个jni部分都适合我
cvCvtColor(mOutGrayImg, mSrcGrayImg, CV_BGR2YCrCb);
cvCvtColor(mSrcGrayImg, &mOutImg , CV_YCrCb2BGR);
从上面的代码中添加
cvMerge(b,g,r,0,mOutGrayImg);
cvCvtColor(mOutGrayImg, mSrcGrayImg, CV_BGR2YCrCb);
cvCvtColor(mSrcGrayImg, &mOutImg , CV_YCrCb2BGR);
它运行,和我的其他代码一样,任何人都可以告诉我Why and How
吗?以及我如何摆脱这两行,只需cvMerge(b,g,r,0,mOutGrayImg);
这些行发送输出图像以及如何为此代码设置C ++接口。
这是我的jave文件包含CvNativeActivity.java
public class CvNativeActivity extends Activity implements CvCameraViewListener2
{
public native boolean BrightnessJNI(int width, int height, int [] mPhotoIntArray, int [] mCannyOutArray);
static
{
System.loadLibrary("native_activity");
}
/** Called when the activity is first created. */
ImageView imageview_1;
ImageView imageview_2;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
imageview_1=(ImageView) findViewById(R.id.imageView1);
imageview_2=(ImageView) findViewById(R.id.imageView2);
InputStream is;
is = this.getResources().openRawResource(R.drawable.foot);
Bitmap bmInImg = BitmapFactory.decodeStream(is);
int [] mPhotoIntArray;
int [] mCannyOutArray;
mPhotoIntArray = new int[bmInImg.getWidth() * bmInImg.getHeight()];
// Copy pixel data from the Bitmap into the 'intArray' array
bmInImg.getPixels(mPhotoIntArray, 0, bmInImg.getWidth(), 0, 0, bmInImg.getWidth(), bmInImg.getHeight());
//create the Brightness result buffer
mCannyOutArray = new int[bmInImg.getWidth() * bmInImg.getHeight()];
//
// Do Brightness
//
BrightnessJNI(bmInImg.getHeight(), bmInImg.getWidth(), mPhotoIntArray, mCannyOutArray);
//
// Convert the result to Bitmap
//
Bitmap bmOutImg = Bitmap.createBitmap(bmInImg.getWidth(), bmInImg.getHeight(), Config.ARGB_8888);
bmOutImg.setPixels(mCannyOutArray, 0, bmInImg.getWidth(), 0, 0, bmInImg.getWidth(), bmInImg.getHeight());
imageview_2.setImageBitmap(bmOutImg);
//
// Save the result to file
//
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
String outFileName = extStorageDirectory + "/Brightness";
OutputBitmapToFile(bmOutImg, outFileName);
}
void OutputBitmapToFile(Bitmap InBm, String Filename)
{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
InBm.compress(Bitmap.CompressFormat.PNG, 100, bytes);
File f = new File(Filename);
try
{
f.createNewFile();
//write the bytes in file
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
由于
答案 0 :(得分:2)
好吧,我发现了这个问题。它没有显示图像,因为您已在alpha channel
中将cvMerge
设为0。位图是RGBA格式。并且alpha为0.因此完整的黑色图像。
这是C API实现代码。这很有效。
#include <jni.h>
#include <stdio.h>
#include "opencv2/core/core.hpp"
#include <opencv2/imgproc/imgproc_c.h>
using namespace std;
using namespace cv;
extern "C"
{
JNIEXPORT jint JNICALL
Java_com_fenchtose_equalizehist_EqActivity_eqhist(
JNIEnv* env, jobject,
jint width, jint height, jintArray in, jintArray out)
{
jint* _in = env->GetIntArrayElements(in, 0);
jint* _out = env->GetIntArrayElements(out, 0);
Mat mSrc(height, width, CV_8UC4, (unsigned char*)_in);
Mat bgra(height, width, CV_8UC4, (unsigned char*)_out);
IplImage mSrcImg = mSrc;
IplImage mOutImg = bgra;
IplImage *b, *g, *r, *a;
b = cvCreateImage(cvSize(width, height), mSrcImg.depth, 1);
g = cvCreateImage(cvSize(width, height), mSrcImg.depth, 1);
r = cvCreateImage(cvSize(width, height), mSrcImg.depth, 1);
a = cvCreateImage(cvSize(width, height), mSrcImg.depth, 1);
cvSplit(&mSrcImg, b, g, r, a);
cvEqualizeHist(b, b);
cvEqualizeHist(g, g);
cvEqualizeHist(r, r);
cvMerge(b, g, r, a, &mOutImg); // merge alpha layer too
jint retVal;
int ret = 1;
retVal = jint(retVal);
env->ReleaseIntArrayElements(in, _in, 0);
env->ReleaseIntArrayElements(out, _out, 0);
return retVal;
}
}
老答案: 我复制了你的Java文件。做了一些小改动。 (在imageView1中显示原始图像,更改了本机函数调用)。
这是JNI文件。
#include <jni.h>
#include <stdio.h>
#include "opencv2/core/core.hpp"
#include <opencv2/imgproc/imgproc.hpp>
#include <vector>
using namespace std;
using namespace cv;
extern "C"
{
JNIEXPORT jint JNICALL
Java_com_example_equalizehist_EqActivity_eqhist(
JNIEnv* env, jobject,
jint width, jint height, jintArray in, jintArray out)
{
jint* _in = env->GetIntArrayElements(in, 0);
jint* _out = env->GetIntArrayElements(out, 0);
Mat mSrc(height, width, CV_8UC4, (unsigned char*)_in);
Mat bgra(height, width, CV_8UC4);
vector<Mat> sChannels;
split(mSrc, sChannels);
for(int i=0; i<sChannels.size(); i++)
{
equalizeHist(sChannels[i], sChannels[i]);
}
merge(sChannels, bgra);
for(int i=0; i<height; i++)
{
memcpy(&(_out[i*width]), &(bgra.data[i*bgra.step]), width*bgra.channels());
}
env->ReleaseIntArrayElements(in, _in, 0);
env->ReleaseIntArrayElements(out, _out, 0);
jint retVal;
int ret = 1;
retVal = jint(retVal);
return retVal;
}
}
mSrc
Mat。bgra
Mat的数据复制到像素数组。对于此用途memcpy
。迭代bgra
Mat的每一行并复制每个通道的数据。这是CV_8UC4 Mat。每个通道都有2个字节的数据。因此每个像素将包含8个字节的数据。以下是该应用的截图。
我已在GitHub上提出此代码。如果遇到任何问题,您可能需要检查它。
注意:如果您使用此代码,请确保正确声明本机功能。
如果您不想使用memcpy
,可以直接分配
#include <jni.h>
#include <stdio.h>
#include "opencv2/core/core.hpp"
#include <opencv2/imgproc/imgproc.hpp>
#include <vector>
using namespace std;
using namespace cv;
extern "C"
{
JNIEXPORT jint JNICALL
Java_com_example_equalizehist_EqActivity_eqhist(
JNIEnv* env, jobject,
jint width, jint height, jintArray in, jintArray out)
{
jint* _in = env->GetIntArrayElements(in, 0);
jint* _out = env->GetIntArrayElements(out, 0);
Mat mSrc(height, width, CV_8UC4, (unsigned char*)_in);
Mat bgra(height, width, CV_8UC4, (unsigned char*)_out);
vector<Mat> sChannels;
split(mSrc, sChannels);
for(int i=0; i<sChannels.size(); i++)
{
equalizeHist(sChannels[i], sChannels[i]);
}
merge(sChannels, bgra);
env->ReleaseIntArrayElements(in, _in, 0);
env->ReleaseIntArrayElements(out, _out, 0);
jint retVal;
int ret = 1;
retVal = jint(retVal);
return retVal;
}
}
即使这样也能正常工作。