【问题标题】:C++ OpenCV equivalent to Matlab imfill?C ++ OpenCV相当于Matlab imfill?
【发布时间】:2020-03-14 09:29:19
【问题描述】:

我有一张原图

如果我在 Matlab 中使用imfill,结果是

但我在 C++ 中使用以下代码来尝试模仿 Matlab 中的 imfill

cv::Mat BW = cv::imread("smallHoles.bmp", cv::IMREAD_GRAYSCALE);
cv::Mat edgesNeg = BW.clone();
cv::floodFill(edgesNeg, cv::Point(0, 0), cv::Scalar(255));
bitwise_not(edgesNeg, edgesNeg);
cv::Mat filledEdgesOut = (edgesNeg | BW);
cv::imwrite("C:/Users/me/circleCVfill.bmp", filledEdgesOut);

结果是所有黑色对象,甚至是黑色垂直对象,都被白色像素填充,这与 Matlab 结果不匹配:

正确的 C++ OpenCV 代码是什么?

编辑:

我使用的 Matlab 代码:

BW=imread('smallHoles.bmp');
BWfill=imfill(BW,'holes');

EDIT2:

我也试过下面的代码

cv::Mat circle = cv::imread("smallHoles.bmp", cv::IMREAD_GRAYSCALE);
std::vector<std::vector<cv::Point> > contours;
cv::Mat contourOutput = circle.clone();
cv::findContours(contourOutput, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
cv::Mat contourImage(circle.size(), CV_8UC1, cv::Scalar(255));
cv::drawContours(contourImage, contours, -1, cv::Scalar(255));
cv::imwrite("C:/Users/me/output.bmp", contourImage);

但它也给出了与我之前尝试过的 C++ 代码相同的全白图像结果

EDIT3:

我试过了

std::vector<std::vector<cv::Point> > contours;
cv::Mat contourOutput = circle.clone();
cv::findContours(contourOutput, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
cv::drawContours(contourOutput, contours, -1, cv::Scalar(255));
cv::imwrite("C:/me/output.bmp", contourOutput);

它返回原始图像作为输出,其中包含应填充的 4 个小黑洞

【问题讨论】:

  • 您能否提供您正在使用的想要模仿的 Matlab 代码? imfill - mathworks.com/help/images/ref/imfill.html 有许多变体。请注意,您正在从 (0, 0) 的种子点进行泛洪填充,这将填充左侧的黑线——我认为这不是您想要实现的目标。
  • 我在 EDIT 中提供了 Matlab 代码
  • 我不想填写左边的黑线。我只希望 C++ 代码给出与 Matlab imfill 相同的结果
  • CPP 中的等效项对您有用吗? github.com/alkasm/cvtools/blob/master/cvtools/matlab.py#L42
  • 我尝试了EDIT2中的代码。我不确定它是否完全等同于您的 Python 代码

标签: c++ matlab opencv


【解决方案1】:

在尝试您的 EDIT3 时:

cv::Mat circle = cv::imread(argv[1], cv::IMREAD_GRAYSCALE);
std::vector<std::vector<cv::Point> > contours;
cv::Mat contourOutput = circle.clone();
cv::findContours(contourOutput, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
cv::drawContours(contourOutput, contours, -1, cv::Scalar(255));
cv::imwrite("output.bmp", contourOutput);

我得到了以下信息: https://i.stack.imgur.com/T5YBR.png

这是意料之中的。如果你查看函数 drawContours 的文档,它会说

thickness – 绘制轮廓线的粗细。如果为负数(例如,thickness=CV_FILLED),则绘制轮廓内部。

所以我们可以看到所需的形状已被采用,但绘图的默认厚度为 1,但您希望将负值(或 CV_FILLED)作为下一个参数,并且您应该得到所需的解决方案。

虽然我没有使用 floodFill 功能,所以无法帮助您。

【讨论】:

    猜你喜欢
    • 2013-01-27
    • 1970-01-01
    • 2020-11-18
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    • 1970-01-01
    • 2012-05-21
    • 1970-01-01
    相关资源
    最近更新 更多