gpt4 book ai didi

c++ - 如何在 OpenCV connectedComponents 函数后分割对象

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:16:28 24 4
gpt4 key购买 nike

我用 C++ OpenCV 的 connectedComponents 函数获得了一个标签,如图所示:

enter image description here

这是 ccLabels 变量的输出,它是一个与原始图像大小相同的 cv::Mat

所以我需要做的是:

  1. 计算每个数字出现的次数,然后选择出现次数出现超过 N 次,这是“大”的。
  2. segmentation “大”组件的区域,然后计算 4 和0 在该区域内。

我的最终目标是计算图像中的孔洞数量,因此我的目标是从 (0 的数量/4 的数量) 中推断出孔的数量。这可能不是最漂亮的方式,但图像在大小和照明方面非常均匀,所以它会满足我的需要。

但我是 OpenCV 的新手,我不太清楚如何完成这项任务。

这是我到目前为止所做的:

cv::Mat1b outImg;
cv::threshold(grayImg, outImg, 150, 255, 0); // Thresholded -binary- image
cv::Mat ccLabels;
cv::connectedComponents(outImg, ccLabels); // Each non-zero pixel is labeled with their connectedComponent ID's
// write the labels to file:
std::ofstream myfile;
myfile.open("ccLabels.txt");
cv::Size s = ccLabels.size();
myfile << "Size: " << s.height << " , " << s.width <<"\n";
for (int r1 = 0; r1 < s.height; r1++) {
for (int c1 = 0; c1 < s.height; c1++) {
myfile << ccLabels.at<int>(r1,c1);
}
myfile << "\n";
}
myfile.close();

因为我知道如何在矩阵内部迭代,计算数字应该没问题,但首先我必须分离(消除/忽略)“背景”像素,它们是 0 的外面连接的组件。然后计数应该很容易。

如何分割这些“大”组件?也许获得掩码,并且只考虑 mask(x,y) = 1 的像素?

感谢您的帮助!

编辑

这是阈值图像:

enter image description here

这就是我在 Canny 边缘检测之后得到的结果:

enter image description here

这是实际图像(阈值): enter image description here

最佳答案

这是一个简单的程序,可以从您的阈值图像开始找到骰子上的数字

  1. 寻找外部轮廓
  2. 对于每个轮廓
    • 最终丢弃小 Blob
    • 绘制填充的蒙版
    • 使用AND和XOR隔离内部空洞
    • 再次找到轮廓
    • 计数轮廓

结果:

Number: 5
Number: 2

图片:

代码:

#include <opencv2\opencv.hpp>
#include <iostream>
#include <vector>
using namespace std;
using namespace cv;

int main(void)
{
// Grayscale image
Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);

// Minimum area of the contour
double minContourArea = 10;

// Prepare outpot
Mat3b result;
cvtColor(img, result, COLOR_GRAY2BGR);

// Find contours
vector<vector<Point>> contours;
findContours(img.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

for (int i = 0; i < contours.size(); ++i)
{
// Check area
if (contourArea(contours[i]) < minContourArea) continue;

// Black mask
Mat1b mask(img.rows, img.cols, uchar(0));
// Draw filled contour
drawContours(mask, contours, i, Scalar(255), CV_FILLED);

mask = (mask & img) ^ mask;

vector<vector<Point>> cntrs;
findContours(mask, cntrs, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

cout << "Number: " << cntrs.size() << endl;

// Just for showing results
drawContours(result, cntrs, -1, Scalar(0,0,255), CV_FILLED);
}

imshow("Result", result);
waitKey();

return 0;
}

关于c++ - 如何在 OpenCV connectedComponents 函数后分割对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32996963/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com