如何使用OpenCV进行多种颜色对象检测

时间:2017-06-27 16:46:51

标签: opencv

我试图检测一些彩色物体的位置,将其发送给机器人。对象是这样的彩色笔记本:

like this

我的方法是单独进行阈值处理以分别找到红色,绿色和蓝色,然后对每个颜色应用Canny滤镜,然后对每种颜色应用findcontours,而与其他颜色无关。 我觉得这种思维方式很差,效率很低,所以任何帮助都会受到高度赞赏。

代码是

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

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    VideoCapture cap;
    cap.open(0);
    Mat src,gthreshold,rthreshold,bthreshold,hsv;
    Mat ggray, rgray, bgray,gray;

    namedWindow("src", CV_WINDOW_AUTOSIZE);
    namedWindow("gthreshol", 1);
    namedWindow("rthreshol", 1);
    namedWindow("bthreshol", 1);
    namedWindow("ggray", 1);
    namedWindow("rgray", 1);
    namedWindow("bgray", 1);

    cout << "windows created" << endl;

    vector<vector<Point>>gcontours;
    vector<vector<Point>>rcontours;
    vector<vector<Point>>bcontours;
    vector<Vec4i> hierarchy;

    while (true)
    {

        cap.read(src);

        if (!cap.isOpened())
        {cout << "not opened camera" << endl;}


        cvtColor(src, hsv, COLOR_BGR2HSV);   // converts the RGB image to HSV 
        inRange(hsv, Scalar(32, 51, 34), Scalar(100, 250, 138), gthreshold); // finds out the green objects 
        inRange(hsv, Scalar(148, 49, 0), Scalar(179, 255, 205), rthreshold);
        inRange(hsv, Scalar(93, 53, 0), Scalar(157, 255, 123), bthreshold);

        erode(gthreshold, gthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));    // noise reduction 
        dilate(gthreshold, gthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
        dilate(gthreshold, gthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
        erode(gthreshold, gthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
        blur(gthreshold, gthreshold, Size(3, 3));

        erode(rthreshold, rthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));    // noise reduction 
        dilate(rthreshold, rthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
        dilate(rthreshold, rthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
        erode(rthreshold, rthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
        blur(rthreshold, rthreshold, Size(3, 3));

        erode(bthreshold, bthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));    // noise reduction 
        dilate(bthreshold, bthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
        dilate(bthreshold, bthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
        erode(bthreshold, bthreshold, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
        blur(bthreshold, bthreshold, Size(3, 3));

        imshow("gthreshol", gthreshold);
        imshow("rthreshol", rthreshold);
        imshow("bthreshol", bthreshold);

        Canny(gthreshold, ggray, 20, 255, 3);
        Canny(rthreshold, rgray, 20, 255, 3);
        Canny(bthreshold, bgray, 20, 255, 3);

        imshow("ggray", ggray);
        imshow("rgray", rgray);
        imshow("bgray", bgray);

        findContours(ggray, gcontours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
        findContours(rgray, rcontours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
        findContours(bgray, bcontours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);


        for (int i = 0; i < gcontours.size(); i++)
        {
            int area = contourArea(gcontours[i], false);
            if (area > 1000)
            {
                cout << "green area = " << area << endl; break;
            }


                cout << "green" << endl;


        }

        for (int k = 0; k < rcontours.size(); k++)
        {
            int rarea = contourArea(gcontours[k], false);

            if (rarea > 1000) {
                cout << "red area = " << rarea << endl; break;
            }


        }

        for (int n = 0; n < rcontours.size(); n++)
        {
            int barea = contourArea(gcontours[n], false);

            if (barea > 100) {
                cout << "blue area = " << barea << endl; break;
            }


        }


        imshow("src", src);


        if (waitKey(30) == 27)
        {
            cout << "esc is pressed" << endl;
            break;
        }
    }

    cout << "the end :) " << endl;
    return(0);

}

0 个答案:

没有答案