2016-12-27 3 views
-1

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); 

そして、ここでさでそれを使用するクラスを作成しましたエラー enter image description here

デバッグ時には、mixChannels関数が原因であることがわかります。コメントするとすべてが問題ありません。なぜそれが間違っているのか分かりません。 Plsヘルプ!みんな、ありがとう!

+0

コードをMVCE – Danh

答えて

0

機能します。 :

0

ソースとデスティネーションの行列は同じサイズで同じ深さでなければなりません。

もし

マットDST = src.clone()のようなソース行列から先行列のサイズをクローニングすることができます。それは前mixChannelsにこれを渡す元の画像と同じ大きさと深さを有する宛先フィールドに

私はソースマットは、単に1つのマットが含まれているため、ちょうど1の2番目のパラメータを変更し、解決策を見つけた

+0

に減らそうとしています。私が言ったように試みましたが、それでもエラーが出ます:( http://imgur.com/a/ZnKMW –

関連する問題