我正在尝试泛色填充一个阈值化的图像。我创建了一个简单的泛色填充函数。该函数从第一张图像中找到白色,然后在另一张空白图像中填充它们的位置。这是一个递归函数,所以一旦它找到一个白点,它不会退出它,直到签署所有的斑点。函数首先检查像素的右侧,然后向下,然后向左,最后向上。
问题是,当我在floodfill函数中包含“up”部分时,它会在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
}
------------------------------------更新!!!---------------------------------
这不是一个精确的解决方案,但我不得不通过增加调试器设置中的“堆栈保留大小”来绕过错误。
1条答案
按热度按时间gab6jxml1#
floodFill
是一个递归函数。每次递归调用都会向堆栈添加一个帧。堆栈使用的最大深度取决于图像的大小。当堆栈超过其大小时,您将获得堆栈溢出异常。由于线程内的所有函数调用都共享堆栈,因此很可能在调用imshow时堆栈已经几乎满了。1.您可以尝试减小图像大小,以验证这确实是问题的原因。
1.您可以尝试迭代实现而不是递归实现,以避免堆栈溢出。
1.为什么你需要在一个递归函数中调用imshow,这个函数被递归地调用了很多次?