首页 文章

分水岭算法后有太多的边界框和圆圈

提问于
浏览
0

使用分水岭后,我在查找边界框和圆圈时遇到问题 . 我已经使用Opencv 2计算机视觉应用程序设计指南手册中的分水岭算法和opencv.org示例来创建边界框和圆圈 .

我的问题是我的对象得到了太多的盒子和圆圈 . 另外,为什么它会为图像添加边框?

我正在使用OpenCV 2.4.11和Visual Studio Express 2013 .

这是我的代码:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "header.h"

using namespace cv;
using namespace std;

int main()
{
    // Read Input Image
    Mat src = imread("toy.png");

    // Convert the input image to gray-scale
    Mat src_gray;
    cvtColor(src, src_gray, CV_BGR2GRAY);

    // Threshold the gray-input image
    Mat src_thresh;
    threshold(src_gray, src_thresh, 100, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

    // Detect the foreground.
    Mat fg;
    erode(src_thresh, fg, Mat(), Point(-1, -1), 6);

    // Detect the background
    Mat bg;
    dilate(src_thresh, bg, Mat(), Point(-1, -1), 6);
    threshold(bg, bg, 1, 128, THRESH_BINARY_INV);

    // Get the markers
    Mat markers(src_thresh.size(), CV_8U, Scalar(0));
    markers = fg + bg;

    // Create watershed segmentation object
    WatershedSegmenter segmenter;

    // Set markers and process
    segmenter.setMarkers(markers);
    segmenter.process(src);

    // Get segmentation result
    Mat seg = segmenter.getSegmentation();

    // Get watersheds
    Mat ws = segmenter.getWatersheds();

    // Display the result
    imshow("Watershed", ws);

    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    /// Find contours
    findContours(ws, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    /// Approximate contours to polygons + get bounding rects and circles
    vector<vector<Point> > contours_poly(contours.size());
    vector<Rect> boundRect(contours.size());
    vector<Point2f>center(contours.size());
    vector<float>radius(contours.size());

    for (int i = 0; i < contours.size(); i++)
    {
        approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);
        boundRect[i] = boundingRect(Mat(contours_poly[i]));
        minEnclosingCircle((Mat)contours_poly[i], center[i], radius[i]);
    }


    /// Draw polygonal contour + bonding rects + circles
    Mat drawing = Mat::zeros(ws.size(), CV_8UC3);
    for (int i = 0; i< contours.size(); i++)
    {
        drawContours(drawing, contours_poly, i, Scalar(0, 0, 255), 1, 8, vector<Vec4i>(), 0, Point());
        rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), Scalar(255, 0, 0), 2, 8, 0);
        circle(drawing, center[i], (int)radius[i], Scalar(0, 255, 0), 2, 8, 0);
    }

    /// Show in a window
    imshow("Contours", drawing);

    waitKey();
    return 0;

}

这是header.h文件:

#if !defined WATERSHS
#define WATERSHS

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

class WatershedSegmenter {

private:

    cv::Mat markers;

public:

    void setMarkers(const cv::Mat& markerImage) {

        // Convert to image of ints
        markerImage.convertTo(markers, CV_32S);
    }

    cv::Mat process(const cv::Mat &image) {

        // Apply watershed
        cv::watershed(image, markers);

        return markers;
    }

    // Return result in the form of an image
    cv::Mat getSegmentation() {

        cv::Mat tmp;
        // all segment with label higher than 255
        // will be assigned value 255
        markers.convertTo(tmp, CV_8U);

        return tmp;
    }

    // Return watershed in the form of an image
    cv::Mat getWatersheds() {

        cv::Mat tmp;
        markers.convertTo(tmp, CV_8U, 255, 255);

        return tmp;
    }
};


#endif

toy.png:
toy.png

watershed.png:
watershed.png

contours.png:
contours.png

谢谢 .

1 回答

  • 2

    问题是你传递给 findContour 二进制图像,其中边(前景)设置为 0 ,其余(背景)设置为 255 .

    findContours 期望前景是 >0 ,背景是 0 . 所以你需要反转你传递给 findContour 的二进制图像,如:

    /// Find contours
    Mat ws_negate = ~ws;
    findContours(ws_negate, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
    

    结果图片将是:

    enter image description here

相关问题