Well, I found the issue. It's not showing the image because you have put alpha channel
as 0 in cvMerge
. Bitmap is of RGBA format. And the alpha is 0. Hence complete black image.
Here's the C API implementation code. This works.
#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;
}
}
OLD ANSWER: I copied your Java file. Made some minor changes. (Showed original image in imageView1, changed native function call).
Here's the JNI File.
#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;
}
}
- Step1: Pass Pixel(int arrays) to native function.
- Step2: Create Mat with input pixels.
- Step3: Create an empty vector to hold each channel of
mSrc
Mat. - Step4: Split mSrc Mat to sChannels vector.
- Step5: Apply equalizeHist function on each channel. Loop over sChannels vector.
- Step6: Merge all the channels in bgra Mat.
- Step7: Copy data of
bgra
Mat to the array of pixels. For this usememcpy
. Iterate over each row ofbgra
Mat and copy data of each channel. This is CV_8UC4 Mat. Each channel will have data of 2 bytes. So Each pixel will contain 8 bytes of data. - Step8: Release arrays.
Here's the screenshot of the app.
I have put up this code on GitHub. You might want to check it if you run into any issues.
NOTE: If you're using this code, make sure that you declare the native function correctly.
If you don't want to use memcpy
, you can directly allocate
#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;
}
}
Even this is working properly.