我在学习openCV轮廓查找部分的快速连通区域分析时,将《学习opencv3》中绘制连通区域的例程(P369)手动敲了一遍,但是出现了如下报错:

经调试发现问题出在connectedComponentsWithStats()函数的使用上。
int nccomps = connectedComponentsWithStats(img_edge, labels, stats, noArray());
重新翻书时发现书中程序注释有这样一句话:最后一个参数输入noArray()可能会导致程序崩溃,建议传入一个矩阵以保证程序的顺利运行。于是我给最后一个参数传入了一个Mat矩阵,问题解决。全部代码如下:
- #include<iostream>
- #include<opencv2opencv.hpp>
- #include<algorithm>
-
- using namespace std;
- using namespace cv;
-
- int main(int argc, char** argv)
- {
- Mat img, img_edge, labels, img_color, stats, centroids;
- if (argc != 2 || (img = imread(argv[1],CV_LOAD_IMAGE_GRAYSCALE)).empty())
- {
- cout << argv[0] << endl << "error..." << endl;
- return -1;
- }
- //labels = Mat(img.size(), CV_8UC3);
- threshold(img, img_edge, 128, 255, CV_THRESH_BINARY);
- imshow("image after threshold", img_edge);
-
- int i;
- int nccomps = connectedComponentsWithStats(img_edge, labels, stats, centroids);//nccomps是轮廓个数
- cout << "total connected components detected:" << nccomps << endl;
-
- vector<Vec3b> colors(nccomps + 1);
- colors[0] = Vec3b(0, 0, 0);//背景颜色为黑色
- for (i = 1; i < nccomps + 1; i++)
- {
- colors[i] = Vec3b(rand() % 256, rand() % 256, rand() % 256);
- if (stats.at<int>(i - 1, CC_STAT_AREA) < 100)
- colors[i] = Vec3b(0, 0, 0);//面积太小的轮廓被填充为背景色
- }
- img_color = Mat::zeros(img.size(), CV_8UC3);
- for (int y = 0; y < img_color.rows; y++)
- {
- for (int x = 0; x < img_color.cols; x++)
- {
- int label = labels.at<int>(y, x);
- CV_Assert(0 <= label &&label <= nccomps);
- img_color.at<Vec3b>(y, x) = colors[label];
- }
- }
- imshow("labeled map", img_color);
- waitKey(0);
- return 0;
- }
因为我在网上没有找到这个问题的解决方式,所以写出来和大家一起交流分享。