12

作为某种“假日项目”,我正在玩 OpenCV 并想要检测和测量东西。

当前工作流程(早期 - 检测):

  1. 转换为灰度(cv::cvtColor)
  2. 应用自适应阈值 (cv::adaptiveThreshold)
  3. 应用精明边缘检测 (cv::Canny)
  4. 寻找轮廓 (cv::findContours)

我的结果有点糟糕,我不确定正确的方向是什么。我已经让 cvBlob 在我当前的设置(OSX 10.7.2,Xcode 4.2.1)下工作,这是一个更好的方法吗?如果是这样,我怎样才能以正确的方式实施它?

还是我需要先进行背景减法?我试过了,但后来找不到轮廓

这是我的图像: 要测量的图像

这就是我的输出,当我将轮廓画回第一张图像时: 输出

更新

我让它在我的程序中工作,我的输出看起来有点不同......</p>

- (IBAction)processImage:(id)sender
{
    cv::Mat forground = [[_inputView image] CVMat];
    cv::Mat result = [self isolateBackground:forground];
    [_outputView setImage:[NSImage imageWithCVMat:result]];
}

- (cv::Mat)isolateBackground:(cv::Mat &)_image
{
    int rh = 255, rl = 100, gh = 255, gl = 0, bh = 70, bl = 0;
    cv::cvtColor(_image, _image, CV_RGB2HSV_FULL);
    cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));
    cv::Mat bgIsolation;
    cv::inRange(_image, cv::Scalar(bl, gl, rl), cv::Scalar(bh, gh, rh), bgIsolation);
    bitwise_not(bgIsolation, bgIsolation);
    erode(bgIsolation, bgIsolation, cv::Mat());
    dilate(bgIsolation, bgIsolation, element);
    return bgIsolation;
}
4

1 回答 1

11

这可能是一种 hack,但由于它是一个“假期项目”,我还是会发布它:)

您是否尝试过隔离背景然后反转蒙版(这会假设任何不是背景的东西都是对象,但它可能适用于您想要的东西)。

下面是我使用 OpenCV inRange函数得到的结果: 在此处输入图像描述

您可能希望使用GuassianBlur平滑图像(预处理)以消除一些锯齿。我使用了比腐蚀内核更大的膨胀内核(5x5 对 3x3)来去除一些嘈杂的像素。平滑可能有助于这也调整阈值可能使侵蚀变得不必要。但是,这应该让你开始。

最后,这是我用来查找此范围的快速小代码片段:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <vector>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    Mat src = imread("test.jpg");


    int rh = 255, rl = 100, gh = 255, gl = 0, bh = 70, bl = 0;

    string windowName = "background";
    namedWindow(windowName);

    createTrackbar("rh", windowName, &rh, 255);
    createTrackbar("rl", windowName, &rl, 255);
    createTrackbar("gh", windowName, &gh, 255);
    createTrackbar("gl", windowName, &gl, 255);
    createTrackbar("bh", windowName, &bh, 255);
    createTrackbar("bl", windowName, &bl, 255);

    // for dilation
    Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));

    Mat bgIsolation;
    int key = 0;
    do
    {
        inRange(src, Scalar(bl, gl, rl), Scalar(bh, gh, rh), bgIsolation);

        bitwise_not(bgIsolation, bgIsolation);

        erode(bgIsolation, bgIsolation, Mat());
        dilate(bgIsolation, bgIsolation, element);

        imshow(windowName, bgIsolation);
        key = waitKey(33);
    } while((char)key != 27);

    waitKey();

    return 0;
}

享受假期项目!挺有趣的 :)

于 2011-12-22T00:48:03.360 回答