2011-11-04 19 views
6

Bir Delphi/Lazarus uygulamasından yüklenen kontur algılaması için paylaşılan bir kitaplık oluşturdum. Ana uygulama, kitaplık içindeki bir işlev tarafından işlenecek bir bitmap'e bir işaretçi geçirir.OpenCV bitmap işlemeye işaretçi

Kitaplıktaki işlev İşte. "Img" parametresi, bitmapimin işaretçisidir. Delphi taraftan

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

, bu yapının bir diziye gösterici geçiyorum:

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

ben bellek bitmap işlemek gerekir, ben yükleme değilim yüzden kütüphanenin içinden dosya.

Sorun şudur: Bu bir cv :: Mat için bir bitmap atamak için doğru yol mu?

Bunu sorun çünkü kod, Linux'ta sorunsuz çalışıyor ancak Windows'ta Mingw ile derlenemiyor.

Not: Bu satırda bir SIGSEGV başarısız:

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

EDIT: SIGSEGV ben hata ayıklama modunda ok çalışır, Yayın modunda OpenCV derleme yalnızca yükseltilir.

Şimdiden teşekkür ederiz, Leonardo.

cevap

1

Yani bir Resim şu şekilde yaratıyor:

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

src.data = img; 

yeni görüntü ve otomatik izler referans sayacı için bellek tahsis edecek ilk beyanı ve örnekleme Mat src (imgHeight, imgWidth, CV_8UC4) Atanan belleğe yapılan referansların sayısı. Sonra bir örnek değişkeni

src.data = img;

Örnek src kapsam dışına çıktığında, yıkıcı çağrılır ve büyük olasılıkla, atadığınız src.data'daki belleği ayırmaya çalışır ve bu bölümleme hatasına neden olabilir. Doğru yolu bir nesnenin örnek değişkeni değişmez etmektir yapmak, ancak src örneğini zaman sadece sağ kurucusunu kullanmak:

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

Bu şekilde, sadece bir matris başlığını ve hiçbir referans sayaç veya serbest bırakılmasına oluşturmak src destructor tarafından yapılacaktır.

İyi şanslar!

DÜZENLEME: Segmentin yanlış bir şekilde bellek ayırma denemesinden kaynaklandığından emin değilim, ancak örnek değişkenlere doğrudan atayarak veri soyutlamayı kırmamanın iyi bir uygulamasıdır.

+0

Teşekkürler Jonas. Önerinizi denedim ve Linux üzerinde çalışıyor, ancak SIGSEGV hala Windows'ta var. – leonardorame