0

我目前正在使用 openCV-lib(2.1 版)在 C++ 中编写应用程序。任务是使用这个库的一些特性来实现一个小型数据库作为学生项目。我自己实现的中值滤波器和 boxcar 滤波器使用 cv::Mat::at 方法通过读取和写入操作访问给定图像中的单个像素。

奇怪的是:它在较小的图像上效果很好。但只有更大的图像它总是会生成一个 SIGSEGV,总是在相同的坐标上。

这是一个已知的错误还是我真的做错了什么?

这是我写的最重要的功能:

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

我真的很感激任何建议。感谢您的时间!

4

1 回答 1

2

如果您在OpenCvat()的文档中查看您在 SetPoint() 方法中使用的函数,它会说:

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

返回对指定矩阵元素的引用。参数:

i – The 0-based row index
j – The 0-based column index

此外,如果您查看 GetSize() 方法,您设置iRet.y = _data->rows然后在该方法中filterImage()使用 for 循环从act_y = 1 to iRet.y. 第二个循环,遍历行。在这个方法结束时,你调用SetPoint(act_x, act_y),它at(act_x, act_y)基本上又调用了。

回想一下,那act_y是行的索引,但现在被用作列的索引。我希望这个建议是您解决问题所需要的。

于 2012-04-16T23:52:28.320 回答