2011-11-04 15 views
6

Delphi/Lazarusアプリケーションからロードされた輪郭検出のための共有ライブラリを作成しました。メインアプリケーションは、ライブラリ内の関数によって処理されるビットマップへのポインタを渡します。OpenCVのビットマップ処理へのポインタ

ここにライブラリ内の機能があります。パラメータ "img"は私のビットマップへのポインタです。デルファイ側から

extern "C" { 

    void detect_contour(int imgWidth, int imgHeight, unsigned char * img, int &x, int &y, int &w, int &h) 
    { 
    Mat threshold_output; 
    vector<vector<Point> > contours; 
    vector<Vec4i> hierarchy; 

    Mat src_gray; 
    int thresh = 100; 
     int max_thresh = 255; 
    RNG rng(12345); 

    /// Load source image and convert it to gray 
    Mat src(imgHeight, imgWidth, CV_8UC4); 
    int idx; 

    src.data = img; 

    /// Convert image to gray and blur it 
    cvtColor(src, src_gray, CV_BGRA2GRAY); 

    blur(src_gray, src_gray, Size(10,10)); 

    /// Detect edges using Threshold 
    threshold(src_gray, threshold_output, thresh, 255, THRESH_BINARY); 
    /// Find contours 
    findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0)); 

    /// Approximate contours to polygons + get bounding rects and circles 
    vector<vector<Point> > contours_poly(contours.size()); 
    vector<Rect> boundRect(contours.size()); 
    vector<Point2f>center(contours.size()); 
    vector<float>radius(contours.size()); 

    int lArea = 0; 
    int lBigger = -1; 

    for(int i = 0; i < contours.size(); i++) 
     { 
     approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true); 
     boundRect[i] = boundingRect(Mat(contours_poly[i])); 
     if(lArea < boundRect[i].width * boundRect[i].height) 
     { 
      lArea = boundRect[i].width * boundRect[i].height; 
      lBigger = i; 
     } 
     } 

    if(lBigger > -1) 
    { 
     x = boundRect[lBigger].x; 
     y = boundRect[lBigger].y; 
     w = boundRect[lBigger].width; 
     h = boundRect[lBigger].height; 
    } 
    } 
} 

、私は、この構造体の配列へのポインタを渡している:

TBGRAPixel = packed record 
    blue, green, red, alpha: byte; 
end; 

私はロードしないよ理由です、メモリ内のビットマップを処理する必要がありますライブラリ内のファイル。

質問:ビットマップをcv :: Matに割り当てる正しい方法ですか?

コードはLinuxでは問題なく動作しますが、MingwでコンパイルされたWindowsでは失敗するため、この質問をします。

注:それは、このライン上のSIGSEGVで失敗します。

blur(src_gray, src_gray, Size(10,10)); 

はEDIT:SIGSEGVが、私はリリースモードでのOpenCVをコンパイルする場合にのみ提起デバッグモードで、それがうまく動作します。

ありがとうございます。 Leonardo。

答えて

1

だから、画像をこのように作成されています

Mat src(imgHeight, imgWidth, CV_8UC4); 
int idx; 

src.data = img; 

新しいイメージと自動的に追跡し、参照カウンタのためのメモリを割り当てます最初の宣言とインスタンス化 マットSRC(imgHeight、imgWidth、CV_8UC4)割り当てられたメモリへの参照数の 次に、インスタンス変数を

に変更します。

src.data = img;

インスタンスのsrcが有効範囲外になると、デストラクタが呼び出され、割り当てられたsrc.dataのメモリの割り当てを解除しようとしている可能性が高く、セグメンテーション違反が発生する可能性があります。それを行うための正しい方法は、オブジェクトのインスタンス変数を変更しないことですが、あなたは、SRCをインスタンス化するとき、単に右のコンストラクタを使用する:

Mat src(imgHeight, imgWidth, CV_8UC4, img); 

この方法で、あなただけの行列のヘッダなし参照カウンタまたは割り当て解除を作成しますsrcのデストラクタによって実行されます。

幸運を祈る!

EDIT:実際にセグメンテーションがメモリの割り当てを誤って割り当てられているとは確信していませんが、インスタンス変数に直接割り当てることでデータ抽象化を破らないことをお勧めします。

+0

ありがとうございました。私はあなたの提案を試みましたが、それはLinux上で動作しますが、SIGSEGVはWindows上にまだあります。 – leonardorame

関連する問題