2012-04-16 15 views
0

私は現在openCV-lib(バージョン2.1)を使ってC++でアプリケーションを書いています。 タスクは、このライブラリの機能の一部を使用して、学生用プロジェクトとして小さなデータベースを実装することでした。私の独自のmedian-filterとboxcar-filterの実装では、cv :: Mat :: atメソッドを使用して、読み込み操作と書き込み操作の両方で指定された画像の単一ピクセルにアクセスします。OpenCV lib with C++ - 詳細詳細cv :: Mat :: atは大きな画像でSIGSEGVを発生させます

これは興味深いことです:小さな画像では完璧に機能します。 しかし、より大きいイメージだけが常に同じ座標上にSIGSEGVを生成します。

これは既知のバグですか、何か間違っていますか?ここ

は、私が書いた最もsignificants機能です:

class point { 
public: 
    int x,y; 
}; 

class ImageEntry { 
    friend class ImageDB; 
private: 
    string _key; 
    string _filename; 
    Mat *_data; 
    ImageEntry* _next; 
    void show(void); 
public: 
    void operator<<(ImageFilter* x); 
    ~ImageEntry(); 
    ImageEntry(string filename, string key); 
    Vec3b GetPoint(int x, int y); 
    point GetSize(void); 
    void SetPoint(int x, int y, Vec3b color); 
}; 


point ImageEntry::GetSize(void) { 
    point iRet; 
    iRet.x = _data->cols; 
    iRet.y = _data->rows; 
    return iRet; 
} 

Vec3b ImageEntry::GetPoint(int x, int y) { 
    Vec3b iRet; 
    iRet = _data->at<Vec3b>(x,y); 
    return iRet; 
} 

void ImageEntry::SetPoint(int x, int y, Vec3b color) { 
    _data->at<Vec3b>(x,y) = color; 
} 

void MedianFilter::filterImage(ImageEntry* img) { 
    Vec3b Points[9]; 
    Vec3b NewColor; 

    unsigned char ActChan[9]; 
    point range = img->GetSize(); 
    for (int act_x = 1; act_x < (range.x - 1); act_x++) { 
     for (int act_y = 1; act_y < range.y - 1; act_y++) { 
      Points[0] = img->GetPoint(act_x-1,act_y-1); 
      Points[1] = img->GetPoint(act_x,act_y-1); 
      Points[2] = img->GetPoint(act_x+1,act_y-1); 
      Points[3] = img->GetPoint(act_x-1,act_y); 
      Points[4] = img->GetPoint(act_x,act_y); 
      Points[5] = img->GetPoint(act_x+1,act_y); 
      Points[6] = img->GetPoint(act_x-1,act_y+1); 
      Points[7] = img->GetPoint(act_x,act_y+1); 
      Points[8] = img->GetPoint(act_x+1,act_y+1); 

      for (int act_color = 0; act_color < 3; act_color++) { 
       for (int i = 0; i < 9; i++) ActChan[i] = Points[i][act_color]; 
       SelSort9(ActChan); 
       NewColor[act_color] = ActChan[4]; 
      } 
      img->SetPoint(act_x,act_y,NewColor); 
     } 
    } 
} 

私は本当に任意の提案をいただければ幸いです。 ありがとうございました!

+0

「大きめ」の大きさと、常にSIGSEGVを生成する座標は何ですか? – molbdnilo

+0

イメージは850x649ピクセルです。 SISGSEVはx = 711およびy = 8(SetPoint関数内)に表示​​されます。別の画像は2244x626ピクセルです。イメージでGetPointで "at"にx = 1144、y = 1のエラーが発生する – TLuc

+0

コピーコンストラクタと代入演算子が不足している可能性があります。 – molbdnilo

答えて

2

あなたがdocumentation of OpenCvに、あなたが設定値()メソッドで使用機能at()、見てみるならば、それは言う:指定された行列要素に

template<typename _Tp> _Tp& Mat::at(int i, int j) 

戻り参照を。 パラメータ:act_y = 1 to iRet.yからループにループする方法filterImage()使用aにおいて

あなたのgetSize()メソッドを見れば
i – The 0-based row index 
j – The 0-based column index 

はまた、あなたが設定iRet.y = _data->rowsしてから。 2番目のループは、行をループします。この方法の最後にSetPoint(act_x, act_y)と呼びますが、それは基本的にはat(act_x, act_y)です。

act_yは行のインデックスであったが、現在は列のインデックスとして使用されていることを思い出してください。私はこの提案があなたの問題を解決するために必要なすべてであることを願っています。

+0

ああああ....そのトリックでした。 タンクは非常に非常に大変です! 2 + 2が4であることを伝える人が必要な場合もあります... – TLuc