我在 OpenCV 中应该有一个简单的练习,但似乎无法让它工作。我正在尝试确定图像一部分中的边缘密度。这是我遵循的过程: 1. 从图像中提取子图像 2. 使用 Canny 在子图像中查找边缘 3. 创建二值图像的阈值 4. 创建二值图像的直方图 5. 获取二值图像中“开启”的像素数(255) 6. 计算“边缘密度”为 numPixelsOn/totalPixels
我已经检查了上面 1,2 和 3 的结果,结果似乎还可以。第 4 步和第 5 步似乎给我带来了麻烦。
这是我计算直方图的代码:
int histSize = 256; // bin size
float range[] = { 0, 256} ;
const float* histRange = { range };
bool uniform = true;
bool accumulate = false;
Mat hist;
/// Compute the histograms:
calcHist( &gray, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate );
Run Code Online (Sandbox Code Playgroud)
这似乎不起作用。当我在调用 calcHist 后检查 hist 时,它没有数据(即 data == 0)......或者我可能不明白我在看什么。
现在为了访问直方图中的“垃圾箱”,我尝试了很多东西。首先我试过这个:
uchar* p;
p = hist.ptr<uchar>(0);
double edgePixels = p[255];
Run Code Online (Sandbox Code Playgroud)
我也尝试使用:
cvQueryHistValue_1D(hist,255); // #include <opencv2/legacy/compat.hpp>
Run Code Online (Sandbox Code Playgroud)
这不会编译。出现 2 个错误:'cv::Mat' 没有重载成员 'operator ->',并且 'bins':不是 'cv::Mat' 的成员
我想我需要一些帮助。
您的第三个参数 - 通道中存在错误,它应该是一个数组,因此您应该像这样调用它
int histSize = 256; // bin size
float range[] = { 0, 256} ;
const float* histRange = { range };
bool uniform = true;
bool accumulate = false;
Mat hist;
int channels[] = {0};
/// Compute the histograms:
calcHist( &gray, 1, channels, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate );
Run Code Online (Sandbox Code Playgroud)
您还应该致电:
hist.at<float>(0);
Run Code Online (Sandbox Code Playgroud)
为了获得您的价值,OpenCV 将它们存储为浮点数,这就是您在使用 uchar 时得到 0 的原因,因为 uchar 小于浮点数,并且数字存储小到无法填充第一口。