在非空 std::list 上使用 std::list.back<int>() 时"Segmentation Fault"
"Segmentation Fault" while using std::list.back() on a non-empty std::list<int>
(注意:对不起,我的英语不好...
大家好, 我需要帮助我的代码(C++):我需要使用 OpenCV 标记灰度图像中的区域。
为此,我将一个新矩阵初始化为零。
我搜索第一个 0(未标记像素),获取坐标并开始递归: 我看着它的 8 个邻居。对于每个:如果像素存在(如果我当前使用的像素不在边缘上),那么如果当前像素与其邻居之间的"距离"低于阈值,那么我将其放在同一区域(相同的标签)并将其放入列表中。
只要列表不为空,我就会从同一区域中选取另一个像素并重新开始(列表中的像素)。
当一个区域不再有像素可以使用时,如果所有像素都没有标记,我会开始一个新区域,依此类推。
所以问题是,在几个像素之后,我得到了一个分段错误,根据 gdb,这是一个来自 std::list.back() 的问题,带有"无法访问内存地址......"。
我开始使用 std:list of pair。我现在只使用带有 2 个push_front的 std::list 在列表中添加坐标,然后返回 2 个(后跟 pop_back)将它们取回。
我尝试使用矢量没有任何好结果。
当我使用小图片(64x64)时,它可以正常工作。但是当涉及到更大的图片/非方形图片时,我总是得到一个分割错误(使用 gdb,它似乎在"int b = listePix.back()")。
谢谢。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/contrib/contrib.hpp>
#include <iostream>
#include <stdio.h>
#include <utility>
#include <list>
using namespace cv;
using namespace std;
void agregation(Mat src, Mat dst);
void expendReg(Mat src, Mat dst, int compteur);
pair<int,int> premiereOcc(Mat dst);
std::list <int> listePix;
int seuil = 20;
int main( int argc, char** argv )
{
Mat image;
image = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
Mat reg = Mat::zeros(image.rows, image.cols, 0);
agregation(image,reg);
cout << "WORKED" << endl;
waitKey(0);
return 0;
}
void agregation(Mat src, Mat dst){
bool flag = 0;
int compteur = 0;
do{
compteur++;
pair<int,int> coord = premiereOcc(dst);
if(coord.first == -1 || coord.second == -1){
flag = 1;
}
else{
int pm = coord.first;
int pn = coord.second;
dst.at<uchar>(pm,pn) = compteur;
listePix.push_front(pn);
listePix.push_front(pm);
expendReg(src,dst,compteur);
listePix.clear();
}
}while(!flag);
}
void expendReg(Mat src, Mat dst, int compteur){
if(listePix.size()>=2){
int b = listePix.back();
listePix.pop_back();
int a = listePix.back();
listePix.pop_back();
int dist;
if((a+1)<dst.rows){
dist = abs(src.at<uchar>(a,b) - src.at<uchar>(a+1,b));
int temp = dst.at<uchar>(a+1,b);
if((dist<=seuil) && (temp == 0)){
dst.at<uchar>(a+1,b) = compteur;
listePix.push_front(b);
listePix.push_front(a+1);
}
}
if((b+1)<dst.cols){
dist = abs(src.at<uchar>(a,b) - src.at<uchar>(a,b+1));
int temp = dst.at<uchar>(a,b+1);
if((dist<=seuil) && (temp == 0)){
dst.at<uchar>(a,b+1) = compteur;
listePix.push_front(b+1);
listePix.push_front(a);
}
}
expendReg(src,dst,compteur);
}
}
pair<int,int> premiereOcc(Mat dst){
//Return the coord of the first pixel without region
for(int i = 0; i<dst.rows; i++){
for(int j = 0; j<dst.cols; j++){
int tmp = dst.at<uchar>(i,j);
if(tmp == 0){
pair<int,int> coord = make_pair(i,j);
return coord;
}
}
}
pair<int,int> coord = make_pair(-1,-1);
return coord;
}
编辑2:我正在使用的图像:https://www.bogotobogo.com/Matlab/images/MATLAB_DEMO_IMAGES/blobs.png
我怀疑这里可能发生堆栈溢出,因为:
- 它只发生在大图像上 堆栈溢出可能会导致分段错误
- :为什么堆栈溢出会导致分段错误,而不是 Linux 中的堆栈溢出?
- 扩展Reg函数是递归的
可能的修复
- 避免递归并使用迭代方法
- 限制递归深度
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 使用"std::unordereded_map"映射到"std::list"对象
- 使用std::list创建循环链表
- '[](std::list& list)<int>{return std::move(list)}(list)' 是否保证将 'list' 留空?
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?
- 为什么这个 std::queue/指向结构的指针列表直到 List.Size() == 0 才释放内存?
- "std::list::splice(std::const_iterator pos, std::list&& other)"是否保证将"其他"留空?
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- 内存未释放 std::list<std::shared_ptr<std::string>> C++
- 像 std::list<std::p air<string, string>> 这样的结构在返回时会被复制吗?
- std::list<std::shared_ptr>::擦除得到了一个SIGSEGV
- 将 std::list<std::unique_ptr> 移动到向量中会尝试引用已删除的函数
- C++ DLL 返回指向 std::list<std::wstring 的指针>
- 您将如何为 std::list<std::string> 创建一个类型映射,以在<String> List in C++ 中为 Java 在 SWIG 中创建?
- std::list<std::unique_ptr>:空初始值设定项列表与默认构造函数
- 错误 C2440:"=":无法从"std::list<std::string,std::分配器<_Ty>> *'转换为"std::string*"
- 无法理解如何将新对象添加到 std::list<std::unique_ptr<classname>>
- std::list<std::future>析构函数不阻塞
- 无法反序列化 std::list<std::string>