Android JNIとOpenCVでアプリを開発しようとしていて、ひどいエラーが発生しました:libc:Fatal signal 11(SIGSEGV)、code 1、faultこのアルゴリズムを実装するためにthis articleに続いて、ビジュアルスタジオ2015で実行するとうまくいきます。しかし、Android JNIで実装しようとすると、以下のエラーが発生します。ここでmixChannels関数(opencv)を使用しているときに "致命的なシグナル11(SIGSEGV)、コード1"
は私のコードです:
#include <jni.h>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
extern "C" {
JNIEXPORT void JNICALL
Java_com_noah_demojniexp_MainActivity_autofix(JNIEnv *env, jobject instance, jlong matAddr,
jlong dstAddr, jfloat clipHistPercent) {
Mat &src = *((Mat *) matAddr);
Mat &dst = *((Mat *) dstAddr);
CV_Assert(clipHistPercent >= 0);
CV_Assert((src.type() == CV_8UC1) || (src.type() == CV_8UC3) || (src.type() == CV_8UC4));
int histSize = 256;
float alpha, beta;
double minGray = 0, maxGray = 0;
//to calculate grayscale histogram
Mat gray;
if (src.type() == CV_8UC1) gray = src;
else if (src.type() == CV_8UC3) cvtColor(src, gray, CV_BGR2GRAY);
else if (src.type() == CV_8UC4) cvtColor(src, gray, CV_BGRA2GRAY);
if (clipHistPercent == 0)
{
// keep full available range
minMaxLoc(gray, &minGray, &maxGray);
}
else
{
Mat hist; //the grayscale histogram
float range[] = { 0, 256 };
const float* histRange = { range };
bool uniform = true;
bool accumulate = false;
calcHist(&gray, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);
// calculate cumulative distribution from the histogram
std::vector<float> accumulator(histSize);
accumulator[0] = hist.at<float>(0);
for (int i = 1; i < histSize; i++)
{
accumulator[i] = accumulator[i - 1] + hist.at<float>(i);
}
// locate points that cuts at required value
float max = accumulator.back();
clipHistPercent *= (max/100.0); //make percent as absolute
clipHistPercent /= 2.0; // left and right wings
// locate left cut
minGray = 0;
while (accumulator[minGray] < clipHistPercent)
minGray++;
// locate right cut
maxGray = histSize - 1;
while (accumulator[maxGray] >= (max - clipHistPercent))
maxGray--;
}
// current range
float inputRange = maxGray - minGray;
alpha = (histSize - 1)/inputRange; // alpha expands current range to histsize range
beta = -minGray * alpha; // beta shifts current range so that minGray will go to 0
// Apply brightness and contrast normalization
// convertTo operates with saurate_cast
src.convertTo(dst, -1, alpha, beta);
// restore alpha channel from source
if (dst.type() == CV_8UC4)
{
int from_to[] = { 3, 3};
mixChannels(&src, 4, &dst,1, from_to, 1);
}
return;
}
}
私はorg.opencv.core.Mat
public class SMat extends Mat {
public void autofix(Mat m,float clip){
MainActivity.native_autofix(nativeObj,m.nativeObj,clip);
}
}
を拡張し、mainactivity
Bitmap bm1 = BitmapFactory.decodeResource(getResources(),R.mipmap.s3);
SMat mat1 = new SMat();
SMat mat2 = new SMat();
Utils.bitmapToMat(bm1,mat1);
mat1.autofix(mat2,5);
Bitmap bm2 = Bitmap.createBitmap(bm1);
Utils.matToBitmap(mat1,bm2);
iv2.setImageBitmap(bm2);
デバッグ時には、mixChannels関数が原因であることがわかります。コメントするとすべてが問題ありません。なぜそれが間違っているのか分かりません。 Plsヘルプ!みんな、ありがとう!
コードをMVCE – Danh