我在学习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;
}
因为我在网上没有找到这个问题的解决方式,所以写出来和大家一起交流分享。