我在尝试对阈值图像进行泛洪填充。我创建了一个简单的泛洪函数。该函数从第一个图像中找到白色,然后在另一个空白图像中填充它们的位置。这是一个递归函数,所以一旦它找到一个白色,它不会退出它,直到签署所有的斑点。函数首先检查像素的右侧,然后是下侧,然后是左侧,最后是上侧。
x1c 0d1x的数据
问题是,当我将“up”部分包含到floodfill函数中时,它会在imshow函数中引发异常。但是当我删除它的时候,根本没有例外。我不知道为什么会这样。
例外情况:
Unhandled exception at 0x00007FF82DCCA2AF (opencv_world343d.dll) in DIP.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x0000002040E73FE0).
字符串
淹没填充功能:
void floodFill(cv::Mat src_8uc1,cv::Mat& index_8uc1,cv::Mat& done_8uc1,int y,int x,int index) {//recursive floodfill function
cv::imshow("INDEX IN FLOODFILL", index_8uc1); //IT THROWS THE EXCEPTION RIGHT HERE!!!
cv::waitKey(8);
index_8uc1.at<unsigned char>(y, x) = index;
//right
if ((y < src_8uc1.rows) && (x+1 < src_8uc1.cols)) {
if (src_8uc1.at<unsigned char>(y, x + 1) == 255) {
if (index_8uc1.at<unsigned char>(y, x + 1) == 0) {
x += 1;
floodFill(src_8uc1, index_8uc1, done_8uc1, y, x, index);
}
}
}
//down
if ((y+1 < src_8uc1.rows) && (x < src_8uc1.cols)) {
if (src_8uc1.at<unsigned char>(y + 1, x) == 255) {
if (index_8uc1.at<unsigned char>(y + 1, x) == 0) {
y += 1;
floodFill(src_8uc1, index_8uc1, done_8uc1, y, x, index);
}
}
}
//left
if ((y < src_8uc1.rows) && (x - 1 < src_8uc1.cols)) {
if (x > 0) {
if (src_8uc1.at<unsigned char>(y, x - 1) == 255) {
if (index_8uc1.at<unsigned char>(y, x - 1) == 0) {
x -= 1;
floodFill(src_8uc1, index_8uc1, done_8uc1, y, x, index);
}
}
}
}
//up
if ((y - 1 < src_8uc1.rows) && (x < src_8uc1.cols)) {
if (y > 0) {
if (src_8uc1.at<unsigned char>(y - 1, x) == 255) {
if (index_8uc1.at<unsigned char>(y - 1, x) == 0) {
y -= 1;
floodFill(src_8uc1, index_8uc1, done_8uc1, y, x, index);
}
}
}
}
}
型
我定义图像的地方:
int main( int argc, char** argv )
{
// Read image
cv::Mat src = cv::imread("images2/train.png", cv::IMREAD_GRAYSCALE);
cv::Mat dst2;
// Thresholding with threshold value set 127
threshold(src, dst2, 127, 255, cv::THRESH_BINARY);
if (dst2.empty()) {
printf("Unable to read input file (%s, %d).", __FILE__, __LINE__);
}
cv::Mat src_8uc1 = src.clone(); //FIRST IMAGE
cv::Mat index_8uc1 = src.clone();
index_8uc1 = cv::Mat::zeros(src.rows, src.cols, CV_8UC1); //indexed image (0)
cv::Mat done_8uc1 =src.clone(); //result
int index = 40;
for (int y = 0; y <= src_8uc1.size().height; y++)
for (int x = 0; x <= src_8uc1.size().width; x++)
{
if ((y < src_8uc1.rows) && (x < src_8uc1.cols)) {
if (dst2.at<uchar>(y, x) == 255) {
if (index_8uc1.at<unsigned char>(y, x) == 0) {
//done_8uc1.at<uchar>((x, y))= 255;
floodFill(dst2, index_8uc1, done_8uc1, y, x, index);
index += 1;
}
}
}
}
cv::waitKey(0); // wait until keypressed
}
型
-更新!!!-----------------------------
这不是一个精确的解决方案,但我不得不通过增加调试器设置中的“堆栈保留大小”来绕过错误。参见here
1条答案
按热度按时间yhuiod9q1#
floodFill
是一个递归函数。每个递归调用都向堆栈添加一个帧。堆栈使用的最大深度取决于图像的大小。当堆栈超过它的大小时,你会得到一个堆栈溢出异常。由于线程中的所有函数调用共享堆栈,因此很可能在调用imshow时堆栈已经几乎满了。1.您可以尝试减小图像大小,以验证这确实是问题的原因。
1.您可以尝试迭代实现而不是递归实现,以避免堆栈溢出。
1.为什么你需要在一个递归函数中调用imshow,这个函数被递归地调用了很多次?