OpenCV分割相机进入网格并确定颜色

时间:2015-03-04 00:58:58

标签: c++ opencv

我写了一段代码来拍摄相机,将其分成网格(如棋盘)并评估每个方块的颜色。

我目前的代码如下:

using namespace std;
using namespace cv;



//Standard Dilate and erode functions to improve white/black areas in Binary Image
// Pointer &thresh used so it affects threshImg so it can be used in tracking.
void morphOps(Mat &thresh){

    //Increases size of black to remove unwanted white specks outside of object
    Mat erodeElement = getStructuringElement( MORPH_RECT,Size(3,3));

    //Increases white-area size to remove holes in object
    Mat dilateElement = getStructuringElement( MORPH_RECT,Size(8,8));

    erode(thresh,thresh,erodeElement);
    erode(thresh,thresh,erodeElement);


    dilate(thresh,thresh,dilateElement);
    dilate(thresh,thresh,dilateElement);

}


//Tracking for the Filtered Object
void trackFilteredObject(int noteNum, string colourtype, Mat &thresh ,Mat HSVImage, Mat &cam){

    vector<Brick> Bricks;

    Mat temp;
    thresh.copyTo(temp);

    threshold(temp, thresh, 120, 255, 3);           //3 = Threshold to Zero
    int whitePixs = countNonZero(thresh);
    int cols = thresh.cols;
    int rows = thresh.rows;
    int imgSize = (rows*cols)/0.75;

    if(whitePixs > imgSize){


        Brick Brick;

        Brick.setColour(colourtype);
        Brick.setnoteNum(noteNum);

        Bricks.push_back(Brick);



    }

int main(int argc, char* argv[])
    {

    /// Create a window
    namedWindow("window", CV_WINDOW_AUTOSIZE );

        while(1){
//initialtes camera, sets capture resolution
VideoCapture capture;
capture.open(1);
capture.set(CV_CAP_PROP_FPS, 30);
capture.set(CV_CAP_PROP_FRAME_WIDTH,640);
capture.set(CV_CAP_PROP_FRAME_HEIGHT,480);

Mat cam;


// Saves camera image to Matrix "cam"


capture.read(cam);


//Sets Widths and Heights based on camera resolution (cam.cols/cam.rows retrieves this)

    int Width = cam.cols;
    int gridWidth = Width/16;
    int Height = cam.rows;
    int gridHeight = Height/16;


//Splits image into 256 squares going left to right through rows and descending vertically. (16 squares per row for 4/4 pattern)

    Mat BigImage;
    Mat HSVImage;

    // Converts cam to HSV pallete
    cvtColor(cam, HSVImage, COLOR_BGR2HSV);

    Size smallSize(gridWidth,gridHeight);
   std::vector<Mat> smallImages;

    for (int y = 0; y < HSVImage.rows; y += smallSize.height)
    {
        for (int x = 0; x < HSVImage.cols; x += smallSize.width)
        {
            cv::Rect rect =  cv::Rect(x,y, smallSize.width, smallSize.height);
            //Saves the matrix to vector
            smallImages.push_back(cv::Mat(HSVImage, rect));

        }
    }

    for (int i = 0; i < smallImages.size(); i++){

        Mat HSV;
        smallImages.at(i).copyTo(HSV);
        int noteNum = i;
        Mat threshImg;

        inRange(HSV,Scalar(0,0,0),Scalar(255,255,255),threshImg);
        morphOps(threshImg); //erodes image
        string colour = "Red";
        trackFilteredObject(noteNum,colour,threshImg,HSV,cam);

        inRange(HSV,Scalar(0,0,0),Scalar(255,255,255),threshImg);
        morphOps(threshImg); // threshold = mat after erosion/dilation
        colour = "yellow";
        trackFilteredObject(noteNum,colour,threshImg,HSV,cam);

        inRange(HSV,Scalar(0,0,0),Scalar(255,255,255),threshImg);
        morphOps(threshImg);
        colour = "Black";
        trackFilteredObject(noteNum,colour,threshImg,HSV,cam);

        inRange(HSV,Scalar(0,0,0),Scalar(255,255,255),threshImg);
        morphOps(threshImg); // threshold = mat after erosion/dilation
        colour = "White";
        trackFilteredObject(noteNum,colour,threshImg,HSV,cam);

        inRange(HSV,Scalar(0,0,0),Scalar(255,255,255),threshImg);
        morphOps(threshImg); // threshold = mat after erosion/dilation
        colour = "Green";
        trackFilteredObject(noteNum,colour,threshImg,HSV,cam);


    }
            imshow("window", cam);

        }

    return 0;
}

目前代码需要很长时间才能执行完整循环(约1.5秒),但理想情况下我需要尽可能接近实时音频应用程序。

有人可以建议为什么要执行这么长时间吗?有没有更好的方法来评估每个方块的颜色?

我的课程如下:

//Brick.h
#include <string>

using namespace std;


class Brick{

public:
    Brick(void);
    ~Brick(void);


    string getColour();
    void setColour(string whatColour);

    int getnoteNum();
    void setnoteNum(int whatnoteNum);


private:

    int noteNum;
    string colour;



};

///

Brick.cpp
#include <stdio.h>
#include <Brick.h>


Brick::Brick(void){


}


Brick::~Brick(void){

}



// get/set Colour
////////////////////////////////

string Brick::getColour(){

    return Brick::colour;


}



void Brick::setColour(string whatColour){


    Brick::colour = whatColour;

}





// get/set Note Number
////////////////////////////////

int Brick::getnoteNum(){

    return Brick::noteNum;


}



void Brick::setnoteNum(int whatnoteNum){


    Brick::noteNum = whatnoteNum;

}

我会非常感谢任何回复的人!

谢谢。

1 个答案:

答案 0 :(得分:0)

尽量不要使用腐蚀和扩张。这些操作非常耗时。我非常有信心他们是你计划的瓶颈。

您可以采取一些措施:

  1. 对图像进行缩小(或缩减采样)。理想情况下,您希望缩小图像的像素与网格方块的大小具有相同的数量级。
  2. 去除扩张并侵蚀。
  3. 偏离主题:修正错误。修复使用的inRange()参数。查阅HSV色彩空间图并标准化到您的空间。例如提取&#34;绿色像素&#34;对应于inRange(HSV,Scalar(80f * 255 / 360,0.3 * 255,0.3 * 255),标量(160f * 255 / 360,255,255),threshImg);
  4. HSL and HSV color spaces