用于彩色物体检测的凸壳和阈值处理

时间:2014-10-21 20:45:52

标签: c++ opencv detection

我目前正在尝试使用OpenCV版本2.4.10来检测红色杯子。我是OpenCV的新手,所以我从示例代码开始,并尝试从那里开始工作。我的想法是利用阈值来首先在框架上找到任何红色物体。从那里我希望找到那些物体的凸包来检测哪些是实际的杯子(底部轮廓线比顶部小)。我无法将凸包代码与我之前使用过的阈值代码相结合。有人可以告诉我我做错了什么,并且如果我对这个项目的处理方法似乎没有指出我也指出了正确的方向吗?谢谢!

到目前为止,这是我的代码:

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace cv;
using namespace std;

int thresh = 100;
int max_thresh = 255;
RNG rng(12345);

int main(int argc, char** argv)
{
    cout << "Program Starts Here." << endl;
    VideoCapture cap(0); //capture the video from webcam

    if (!cap.isOpened())  // if not success, exit program
    {
        cout << "Cannot open the web cam" << endl;
        return -1;
    }

    //namedWindow("Control", CV_WINDOW_AUTOSIZE); //create a window called "Control"

    int iLowH = 170;
    int iHighH = 179;
    int iLowS = 150;
    int iHighS = 255;

    int iLowV = 60;
    int iHighV = 255;

    //Create trackbars in "Control" window
//  createTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179)
//  createTrackbar("HighH", "Control", &iHighH, 179);

//  createTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255)
//  createTrackbar("HighS", "Control", &iHighS, 255);

//  createTrackbar("LowV", "Control", &iLowV, 255);//Value (0 - 255)
//  createTrackbar("HighV", "Control", &iHighV, 255);

    int iLastX = -1;
    int iLastY = -1;

    //Capture a temporary image from the camera
    Mat imgTmp;
    cap.read(imgTmp);

    //Create a black image with the size as the camera output
    Mat imgLines = Mat::zeros(imgTmp.size(), CV_8UC3);;


    while (true)
    {
        Mat imgOriginal;

        bool bSuccess = cap.read(imgOriginal); // read a new frame from video



        if (!bSuccess) //if not success, break loop
        {
            cout << "Cannot read a frame from video stream" << endl;
            break;
        }

        Mat imgHSV;

        cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV

        Mat imgThresholded;

        inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), imgThresholded); //Threshold the image

        //morphological opening (removes small objects from the foreground)
        erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
        dilate(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));

        //morphological closing (removes small holes from the foreground)
        dilate(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
        erode(imgThresholded, imgThresholded, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
/////////////////////////////////////////////////////////////////////////////////////////////////////
//////START OF ADDED CONVEX HULL CODE       
        Mat threshold_output;
        vector<vector<Point> > contours;
        vector<Vec4i> hierarchy;

        /// Detect edges using Threshold
        threshold(imgThresholded, threshold_output, thresh, 255, THRESH_BINARY);

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

        /// Find the convex hull object for each contour
        vector<vector<Point> >hull(contours.size());
        for (int i = 0; i < contours.size(); i++)
        {
            convexHull(Mat(contours[i]), hull[i], false);
        }
        /// Draw contours + hull results
        Mat drawing = Mat::zeros(threshold_output.size(), CV_8UC3);
        for (int i = 0; i< contours.size(); i++)
        {
            Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
            drawContours(drawing, contours, i, color, 1, 8, vector<Vec4i>(), 0, Point());
            drawContours(drawing, hull, i, color, 1, 8, vector<Vec4i>(), 0, Point());
        }

        /// Show in a window
        namedWindow("Convex Hull", CV_WINDOW_AUTOSIZE);
        imshow("Convex Hull", drawing);
///END OF ADDED CODE
/////////////////////////////////////////////////////////////////////////////////////////////////////
        //Calculate the moments of the thresholded image
        Moments oMoments = moments(imgThresholded);

        double dM01 = oMoments.m01;
        double dM10 = oMoments.m10;
        double dArea = oMoments.m00;

        // if the area <= 10000, I consider that the there are no object in the image and it's because of the noise, the area is not zero 
        if (dArea > 10000)
        {
            //calculate the position of the object
            int posX = dM10 / dArea;
            int posY = dM01 / dArea;
            cout << "X = " << posX << endl;
            cout << "Y = " << posY << endl;
            if (posX > 275 && posX < 325){
                cout << "Object Straight Ahead." << endl;
            }
            else if (posX < 275){
                cout << "Turn Left." << endl;
            }
            else if (posX > 325){
                cout << "Turn Right." << endl;
            }

            if (iLastX >= 0 && iLastY >= 0 && posX >= 0 && posY >= 0)
            {
                //Draw a red line from the previous point to the current point (for visual debugging)
                line(imgLines, Point(posX, posY), Point(iLastX, iLastY), Scalar(0, 0, 255), 2);
            }

            iLastX = posX;
            iLastY = posY;
        }

        imshow("Thresholded Image", imgThresholded); //show the thresholded image

        imgOriginal = imgOriginal + imgLines;
        imshow("Original", imgOriginal); //show the original image

        if (waitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
        {
            cout << "esc key is pressed by user" << endl;
            break;
        }

    }

    return 0;
}

0 个答案:

没有答案