本文介绍了OpenCV C ++/Obj-C:正确的对象检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为某种假日项目",我正在玩OpenCV,并希望检测和评估内容.

As some kind of "holiday project" I'm playing around with OpenCV and want to detect and measure stuff.

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

Current workflow (early stage - detection):

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

我的结果有点糟糕,我不确定前进的方向.我已经在当前设置(OSX 10.7.2,Xcode 4.2.1)下运行cvBlob,这是一种更好的方法吗?如果是这样,我该如何正确实施呢?

My outcome is kinda crappy and I'm not sure what's the right direction to go. I already got cvBlob working under my current setup (OSX 10.7.2, Xcode 4.2.1) is it a better way to go? If so, how can I implement it the right way?

还是我需要先进行背景扣除?我尝试过,但是后来找不到轮廓

Or do I need background subtraction first? I tried that but wasn't able to find contours afterwards

这是我的形象:

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

And that's my output, when I draw my contours back into the first image:

更新

我在程序中运行它,我的输出看起来有点不同……

I got it working in my programm and my output looks a bit different …

- (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;
}

推荐答案

这可能是一种hack,但是由于它是一个假日项目",所以我还是会把它发布:)

This might be kind of a hack, but since it's a "holiday project", I'll post it anyway :)

您是否尝试过隔离背景,然后反转遮罩(这将假定不是背景的任何物体都是物体,但是它可能适用于您想要的东西).

Have you tried isolating the background and then inverting the mask (this would assume anything not background is an object, but it might work for what you want).

以下是我使用OpenCV获得的结果 inRange 函数:

Below is the result I got using the OpenCV inRange function:

您可能要使用 GuassianBlur 摆脱了一些麻烦.我使用了比侵蚀内核更大的膨胀内核(5x5与3x3)来消除一些嘈杂的像素.平滑可能有助于此,并且调整阈值可能使腐蚀变得不必要.但是,这应该可以帮助您入门.

You might want to smooth the image (pre-process) with GuassianBlur to get rid of some of the jagginess. I used a bigger dilation kernel than erosion kernel (5x5 vs. 3x3) to get rid of some noisy pixels. The smoothing might help this also tweaking the thresholds could make the erosion unnecessary. But, that should get you started.

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

Finally, here is my quick little code snippet I used to find this range:

#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;
}

享受假期项目!看起来很有趣:)

Enjoy the holiday project! Looks fun :)

这篇关于OpenCV C ++/Obj-C:正确的对象检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 08:05