puku0x / cvdrone

CV Drone (= OpenCV + AR.Drone)
https://github.com/puku0x/cvdrone/wiki/How-to-build
Other
203 stars 93 forks source link

multicolor tracking #37

Open rezaprasetyo opened 8 years ago

rezaprasetyo commented 8 years ago

hello there, you help me alot on my final project.

can you help me about tracking multicolor? because i need to track like green,blue,red, and black in ar drone camera.

thanks :)

puku0x commented 8 years ago

This is it !

#include "ardrone/ardrone.h"

// Thresholds
class Thresholds {
public:
    Thresholds() {
        minH = minS = minV = 0;
        maxH = maxS = maxV = 255;
    }
    int minH, maxH;
    int minS, maxS;
    int minV, maxV;
};

// Find the largest object in a binalized image
cv::Rect findLargestBoundingRect(cv::Mat img)
{
    cv::Rect rect;
    cv::Mat tmp = img.clone();

    // De-noising
    cv::Mat kernel = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
    cv::morphologyEx(tmp, tmp, cv::MORPH_CLOSE, kernel);

    // Detect contours
    std::vector< std::vector<cv::Point> > contours;
    cv::findContours(tmp, contoursRed, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);

    // Find largest contour
    int contour_index = -1;
    double max_area = 0.0;
    for (size_t i = 0; i < contours.size(); i++) {
        double area = fabs(cv::contourArea(contours[i]));
        if (area > max_area) {
            contour_index = i;
            max_area = area;
        }
    }

    // Object detected
    if (contour_index >= 0) {
        rect = cv::boundingRect(contours[contour_index]);
    }

    return rect;
}

// --------------------------------------------------------------------------
// main(Number of arguments, Argument values)
// Description  : This is the entry point of the program.
// Return value : SUCCESS:0  ERROR:-1
// --------------------------------------------------------------------------
int main(int argc, char *argv[])
{
    // AR.Drone class
    ARDrone ardrone;

    // Initialize
    if (!ardrone.open()) {
        std::cout << "Failed to initialize." << std::endl;
        return -1;
    }

    // XML save data
    std::string filename("thresholds.xml");
    cv::FileStorage fs(filename, cv::FileStorage::READ);

    // If there is a save file then read it
    Thresholds thblue, thGreen, thBlue, thBlack;
    if (fs.isOpened()) {
        thRed.maxH   = fs["H_MAX_RED"];
        thRed.minH   = fs["H_MIN_RED"];
        thRed.maxS   = fs["S_MAX_RED"];
        thRed.minS   = fs["S_MIN_RED"];
        thRed.maxV   = fs["V_MAX_RED"];
        thRed.minV   = fs["V_MIN_RED"];
        thGreen.maxH = fs["H_MAX_GREEN"];
        thGreen.minH = fs["H_MIN_GREEN"];
        thGreen.maxS = fs["S_MAX_GREEN"];
        thGreen.minS = fs["S_MIN_GREEN"];
        thGreen.maxV = fs["V_MAX_GREEN"];
        thGreen.minV = fs["V_MIN_GREEN"];
        thBlue.maxH   = fs["H_MAX_BLUE"];
        thBlue.minH   = fs["H_MIN_BLUE"];
        thBlue.maxS   = fs["S_MAX_BLUE"];
        thBlue.minS   = fs["S_MIN_BLUE"];
        thBlue.maxV   = fs["V_MAX_BLUE"];
        thBlue.minV   = fs["V_MIN_BLUE"];
        thBlack.maxH  = fs["H_MAX_BLACK"];
        thBlack.minH  = fs["H_MIN_BLACK"];
        thBlack.maxS  = fs["S_MAX_BLACK"];
        thBlack.minS  = fs["S_MIN_BLACK"];
        thBlack.maxV  = fs["V_MAX_BLACK"];
        thBlack.minV  = fs["V_MIN_BLACK"];
        fs.release();
    }

    // Create a window
    cv::namedWindow("red");
    cv::createTrackbar("H max", "red", &thRed.maxH, 255);
    cv::createTrackbar("H min", "red", &thRed.minH, 255);
    cv::createTrackbar("S max", "red", &thRed.maxS, 255);
    cv::createTrackbar("S min", "red", &thRed.minS, 255);
    cv::createTrackbar("V max", "red", &thRed.maxV, 255);
    cv::createTrackbar("V min", "red", &thRed.minV, 255);
    cv::resizeWindow("red", 0, 0);
    cv::namedWindow("green");
    cv::createTrackbar("H max", "green", &thGreen.maxH, 255);
    cv::createTrackbar("H min", "green", &thGreen.minH, 255);
    cv::createTrackbar("S max", "green", &thGreen.maxS, 255);
    cv::createTrackbar("S min", "green", &thGreen.minS, 255);
    cv::createTrackbar("V max", "green", &thGreen.maxV, 255);
    cv::createTrackbar("V min", "green", &thGreen.minV, 255);
    cv::resizeWindow("green", 0, 0);
    cv::namedWindow("blue");
    cv::createTrackbar("H max", "blue", &thBlue.maxH, 255);
    cv::createTrackbar("H min", "blue", &thBlue.minH, 255);
    cv::createTrackbar("S max", "blue", &thBlue.maxS, 255);
    cv::createTrackbar("S min", "blue", &thBlue.minS, 255);
    cv::createTrackbar("V max", "blue", &thBlue.maxV, 255);
    cv::createTrackbar("V min", "blue", &thBlue.minV, 255);
    cv::resizeWindow("blue", 0, 0);
    cv::namedWindow("black");
    cv::createTrackbar("H max", "black", &thBlack.maxH, 255);
    cv::createTrackbar("H min", "black", &thBlack.minH, 255);
    cv::createTrackbar("S max", "black", &thBlack.maxS, 255);
    cv::createTrackbar("S min", "black", &thBlack.minS, 255);
    cv::createTrackbar("V max", "black", &thBlack.maxV, 255);
    cv::createTrackbar("V min", "black", &thBlack.minV, 255);
    cv::resizeWindow("black", 0, 0);

    // Main loop
    while (1) {
        // Key input
        int key = cv::waitKey(33);
        if (key == 0x1b) break;

        // Get an image
        cv::Mat image = ardrone.getImage();

        // HSV image
        cv::Mat hsv;
        cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV_FULL);

        // Binalize
        cv::Mat red, green, blue, black;
        cv::inRange(hsv, cv::Scalar(thRed.minH, thRed.minS, thRed.minV),       cv::Scalar(thRed.maxH, thRed.maxS, thRed.maxV),       red);
        cv::inRange(hsv, cv::Scalar(thGreen.minH, thGreen.minS, thGreen.minV), cv::Scalar(thGreen.maxH, thGreen.maxS, thGreen.maxV), green);
        cv::inRange(hsv, cv::Scalar(thBlue.minH, thBlue.minS, thBlue.minV),    cv::Scalar(thBlue.maxH, thBlue.maxS, thBlue.maxV),    blue);
        cv::inRange(hsv, cv::Scalar(thBlack.minH, thBlack.minS, thBlack.minV), cv::Scalar(thBlack.maxH, thBlack.maxS, thBlack.maxV), black);

        // Show results
        cv::imshow("red", red);
        cv::imshow("green", green);
        cv::imshow("blue", blue);
        cv::imshow("black", black);
        cv::rectangle(image, findLargestBoundingRect(red),   cv::Scalar(255,0,0));
        cv::rectangle(image, findLargestBoundingRect(green), cv::Scalar(0,255,0));
        cv::rectangle(image, findLargestBoundingRect(blue),  cv::Scalar(0,0,255));
        cv::rectangle(image, findLargestBoundingRect(black), cv::Scalar(0,0,0));

        // Display the image
        cv::imshow("camera", image);
    }

    // Save thresholds
    fs.open(filename, cv::FileStorage::WRITE);
    if (fs.isOpened()) {
        cv::write(fs, "H_MAX_RED",   thRed.maxH);
        cv::write(fs, "H_MIN_RED",   thRed.minH);
        cv::write(fs, "S_MAX_RED",   thRed.maxS);
        cv::write(fs, "S_MIN_RED",   thRed.minS);
        cv::write(fs, "V_MAX_RED",   thRed.maxV);
        cv::write(fs, "V_MIN_RED",   thRed.minV);
        cv::write(fs, "H_MAX_GREEN", thGreen.maxH);
        cv::write(fs, "H_MIN_GREEN", thGreen.minH);
        cv::write(fs, "S_MAX_GREEN", thGreen.maxS);
        cv::write(fs, "S_MIN_GREEN", thGreen.minS);
        cv::write(fs, "V_MAX_GREEN", thGreen.maxV);
        cv::write(fs, "V_MIN_GREEN", thGreen.minV);
        cv::write(fs, "H_MAX_BLUE",  thBlue.maxH);
        cv::write(fs, "H_MIN_BLUE",  thBlue.minH);
        cv::write(fs, "S_MAX_BLUE",  thBlue.maxS);
        cv::write(fs, "S_MIN_BLUE",  thBlue.minS);
        cv::write(fs, "V_MAX_BLUE",  thBlue.maxV);
        cv::write(fs, "V_MIN_BLUE",  thBlue.minV);
        cv::write(fs, "H_MAX_BLACK", thBlack.maxH);
        cv::write(fs, "H_MIN_BLACK", thBlack.minH);
        cv::write(fs, "S_MAX_BLACK", thBlack.maxS);
        cv::write(fs, "S_MIN_BLACK", thBlack.minS);
        cv::write(fs, "V_MAX_BLACK", thBlack.maxV);
        cv::write(fs, "V_MIN_BLACK", thBlack.minV);
        fs.release();
    }

    // See you
    ardrone.close();

    return 0;
}
rezaprasetyo commented 8 years ago

thank you very much for the program, and now, can you tell me how to get the sensor data from the quadrotor?

thanks!

On Tue, Jan 26, 2016 at 8:45 PM, puku0x notifications@github.com wrote:

This is it !

include "ardrone/ardrone.h"

// Thresholdsclass Thresholds {public: Thresholds() { minH = minS = minV = 0; maxH = maxS = maxV = 255; } int minH, maxH; int minS, maxS; int minV, maxV; }; // Find the largest object in a binalized image cv::Rect findLargestBoundingRect(cv::Mat img) { cv::Rect rect; cv::Mat tmp = img.clone();

// De-noising
cv::Mat kernel = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
cv::morphologyEx(tmp, tmp, cv::MORPH_CLOSE, kernel);

// Detect contours
std::vector< std::vector<cv::Point> > contours;
cv::findContours(tmp, contoursRed, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE);

// Find largest contour
int contour_index = -1;
double max_area = 0.0;
for (size_t i = 0; i < contours.size(); i++) {
    double area = fabs(cv::contourArea(contours[i]));
    if (area > max_area) {
        contour_index = i;
        max_area = area;
    }
}

// Object detected
if (contour_index >= 0) {
    rect = cv::boundingRect(contours[contour_index]);
}

return rect;

} // --------------------------------------------------------------------------// main(Number of arguments, Argument values)// Description : This is the entry point of the program.// Return value : SUCCESS:0 ERROR:-1// --------------------------------------------------------------------------int main(int argc, char *argv[]) { // AR.Drone class ARDrone ardrone;

// Initialize
if (!ardrone.open()) {
    std::cout << "Failed to initialize." << std::endl;
    return -1;
}

// XML save data
std::string filename("thresholds.xml");
cv::FileStorage fs(filename, cv::FileStorage::READ);

// If there is a save file then read it
Thresholds thblue, thGreen, thBlue, thBlack;
if (fs.isOpened()) {
    thRed.maxH   = fs["H_MAX_RED"];
    thRed.minH   = fs["H_MIN_RED"];
    thRed.maxS   = fs["S_MAX_RED"];
    thRed.minS   = fs["S_MIN_RED"];
    thRed.maxV   = fs["V_MAX_RED"];
    thRed.minV   = fs["V_MIN_RED"];
    thGreen.maxH = fs["H_MAX_GREEN"];
    thGreen.minH = fs["H_MIN_GREEN"];
    thGreen.maxS = fs["S_MAX_GREEN"];
    thGreen.minS = fs["S_MIN_GREEN"];
    thGreen.maxV = fs["V_MAX_GREEN"];
    thGreen.minV = fs["V_MIN_GREEN"];
    thBlue.maxH   = fs["H_MAX_BLUE"];
    thBlue.minH   = fs["H_MIN_BLUE"];
    thBlue.maxS   = fs["S_MAX_BLUE"];
    thBlue.minS   = fs["S_MIN_BLUE"];
    thBlue.maxV   = fs["V_MAX_BLUE"];
    thBlue.minV   = fs["V_MIN_BLUE"];
    thBlack.maxH  = fs["H_MAX_BLACK"];
    thBlack.minH  = fs["H_MIN_BLACK"];
    thBlack.maxS  = fs["S_MAX_BLACK"];
    thBlack.minS  = fs["S_MIN_BLACK"];
    thBlack.maxV  = fs["V_MAX_BLACK"];
    thBlack.minV  = fs["V_MIN_BLACK"];
    fs.release();
}

// Create a window
cv::namedWindow("red");
cv::createTrackbar("H max", "red", &thRed.maxH, 255);
cv::createTrackbar("H min", "red", &thRed.minH, 255);
cv::createTrackbar("S max", "red", &thRed.maxS, 255);
cv::createTrackbar("S min", "red", &thRed.minS, 255);
cv::createTrackbar("V max", "red", &thRed.maxV, 255);
cv::createTrackbar("V min", "red", &thRed.minV, 255);
cv::resizeWindow("red", 0, 0);
cv::namedWindow("green");
cv::createTrackbar("H max", "green", &thGreen.maxH, 255);
cv::createTrackbar("H min", "green", &thGreen.minH, 255);
cv::createTrackbar("S max", "green", &thGreen.maxS, 255);
cv::createTrackbar("S min", "green", &thGreen.minS, 255);
cv::createTrackbar("V max", "green", &thGreen.maxV, 255);
cv::createTrackbar("V min", "green", &thGreen.minV, 255);
cv::resizeWindow("green", 0, 0);
cv::namedWindow("blue");
cv::createTrackbar("H max", "blue", &thBlue.maxH, 255);
cv::createTrackbar("H min", "blue", &thBlue.minH, 255);
cv::createTrackbar("S max", "blue", &thBlue.maxS, 255);
cv::createTrackbar("S min", "blue", &thBlue.minS, 255);
cv::createTrackbar("V max", "blue", &thBlue.maxV, 255);
cv::createTrackbar("V min", "blue", &thBlue.minV, 255);
cv::resizeWindow("blue", 0, 0);
cv::namedWindow("black");
cv::createTrackbar("H max", "black", &thBlack.maxH, 255);
cv::createTrackbar("H min", "black", &thBlack.minH, 255);
cv::createTrackbar("S max", "black", &thBlack.maxS, 255);
cv::createTrackbar("S min", "black", &thBlack.minS, 255);
cv::createTrackbar("V max", "black", &thBlack.maxV, 255);
cv::createTrackbar("V min", "black", &thBlack.minV, 255);
cv::resizeWindow("black", 0, 0);

// Main loop
while (1) {
    // Key input
    int key = cv::waitKey(33);
    if (key == 0x1b) break;

    // Get an image
    cv::Mat image = ardrone.getImage();

    // HSV image
    cv::Mat hsv;
    cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV_FULL);

    // Binalize
    cv::Mat red, green, blue, black;
    cv::inRange(hsv, cv::Scalar(thRed.minH, thRed.minS, thRed.minV),       cv::Scalar(thRed.maxH, thRed.maxS, thRed.maxV),       red);
    cv::inRange(hsv, cv::Scalar(thGreen.minH, thGreen.minS, thGreen.minV), cv::Scalar(thGreen.maxH, thGreen.maxS, thGreen.maxV), green);
    cv::inRange(hsv, cv::Scalar(thBlue.minH, thBlue.minS, thBlue.minV),    cv::Scalar(thBlue.maxH, thBlue.maxS, thBlue.maxV),    blue);
    cv::inRange(hsv, cv::Scalar(thBlack.minH, thBlack.minS, thBlack.minV), cv::Scalar(thBlack.maxH, thBlack.maxS, thBlack.maxV), black);

    // Show results
    cv::imshow("red", red);
    cv::imshow("green", green);
    cv::imshow("blue", blue);
    cv::imshow("black", black);
    cv::rectangle(image, findLargestBoundingRect(red),   cv::Scalar(255,0,0));
    cv::rectangle(image, findLargestBoundingRect(green), cv::Scalar(0,255,0));
    cv::rectangle(image, findLargestBoundingRect(blue),  cv::Scalar(0,0,255));
    cv::rectangle(image, findLargestBoundingRect(black), cv::Scalar(0,0,0));

    // Display the image
    cv::imshow("camera", image);
}

// Save thresholds
fs.open(filename, cv::FileStorage::WRITE);
if (fs.isOpened()) {
    cv::write(fs, "H_MAX_RED",   thRed.maxH);
    cv::write(fs, "H_MIN_RED",   thRed.minH);
    cv::write(fs, "S_MAX_RED",   thRed.maxS);
    cv::write(fs, "S_MIN_RED",   thRed.minS);
    cv::write(fs, "V_MAX_RED",   thRed.maxV);
    cv::write(fs, "V_MIN_RED",   thRed.minV);
    cv::write(fs, "H_MAX_GREEN", thGreen.maxH);
    cv::write(fs, "H_MIN_GREEN", thGreen.minH);
    cv::write(fs, "S_MAX_GREEN", thGreen.maxS);
    cv::write(fs, "S_MIN_GREEN", thGreen.minS);
    cv::write(fs, "V_MAX_GREEN", thGreen.maxV);
    cv::write(fs, "V_MIN_GREEN", thGreen.minV);
    cv::write(fs, "H_MAX_BLUE",  thBlue.maxH);
    cv::write(fs, "H_MIN_BLUE",  thBlue.minH);
    cv::write(fs, "S_MAX_BLUE",  thBlue.maxS);
    cv::write(fs, "S_MIN_BLUE",  thBlue.minS);
    cv::write(fs, "V_MAX_BLUE",  thBlue.maxV);
    cv::write(fs, "V_MIN_BLUE",  thBlue.minV);
    cv::write(fs, "H_MAX_BLACK", thBlack.maxH);
    cv::write(fs, "H_MIN_BLACK", thBlack.minH);
    cv::write(fs, "S_MAX_BLACK", thBlack.maxS);
    cv::write(fs, "S_MIN_BLACK", thBlack.minS);
    cv::write(fs, "V_MAX_BLACK", thBlack.maxV);
    cv::write(fs, "V_MIN_BLACK", thBlack.minV);
    fs.release();
}

// See you
ardrone.close();

return 0;

}

— Reply to this email directly or view it on GitHub https://github.com/puku0x/cvdrone/issues/37#issuecomment-175019734.

Reza Prasetyo

Engineering Physics

Institut Teknologi Bandung

puku0x commented 8 years ago

Here is a sample code which gets sensor values from AR.Drone. https://github.com/puku0x/cvdrone/blob/master/samples/sample_navdata.cpp

More API references are in https://github.com/puku0x/cvdrone/wiki/API-reference

Regards, puku0x

rezaprasetyo commented 8 years ago

anyway, the multi color tracking isnt working. help please

rezaprasetyo commented 8 years ago

anyway, the multi color tracking isnt working. help please

On Tue, Feb 2, 2016 at 11:23 AM, puku0x notifications@github.com wrote:

Here is a sample code which gets sensor values from AR.Drone. https://github.com/puku0x/cvdrone/blob/master/samples/sample_navdata.cpp

More API references are in https://github.com/puku0x/cvdrone/wiki/API-reference

Regards, puku0x

— Reply to this email directly or view it on GitHub https://github.com/puku0x/cvdrone/issues/37#issuecomment-178364438.

Reza Prasetyo

Engineering Physics

Institut Teknologi Bandung

rezaprasetyo commented 8 years ago

visual studio said "thresholds is undefined" help me thanks

On Tue, Feb 2, 2016 at 11:48 AM, Reza Prasetyo rezaprasetyo15@gmail.com wrote:

anyway, the multi color tracking isnt working. help please

On Tue, Feb 2, 2016 at 11:23 AM, puku0x notifications@github.com wrote:

Here is a sample code which gets sensor values from AR.Drone. https://github.com/puku0x/cvdrone/blob/master/samples/sample_navdata.cpp

More API references are in https://github.com/puku0x/cvdrone/wiki/API-reference

Regards, puku0x

— Reply to this email directly or view it on GitHub https://github.com/puku0x/cvdrone/issues/37#issuecomment-178364438.

Reza Prasetyo

Engineering Physics

Institut Teknologi Bandung

Reza Prasetyo

Engineering Physics

Institut Teknologi Bandung

puku0x commented 8 years ago

Did you add Thresholds class ?

// Thresholds
class Thresholds {
public:
    Thresholds() {
        minH = minS = minV = 0;
        maxH = maxS = maxV = 255;
    }
    int minH, maxH;
    int minS, maxS;
    int minV, maxV;
};
abraxas4 commented 8 years ago

hello guys, I'm new here, but I was trying the code puku0x wrote above (Thank you very much) and it looks like the argument order is reversed when using cv::Scalar(...).

        cv::rectangle(image, findLargestBoundingRect(red),   cv::Scalar(255,0,0));
        cv::rectangle(image, findLargestBoundingRect(green), cv::Scalar(0,255,0));
        cv::rectangle(image, findLargestBoundingRect(blue),  cv::Scalar(0,0,255));

->

        cv::rectangle(image, findLargestBoundingRect(red),   cv::Scalar(0,0,255));
        cv::rectangle(image, findLargestBoundingRect(green), cv::Scalar(0,255,0));
        cv::rectangle(image, findLargestBoundingRect(blue),  cv::Scalar(255,0,0));

If this is not right, just ignore it. Thanks :)

nnguyen16 commented 7 years ago

hello guys, I use the same code and it said "'contoursRed': undeclared identifier" how do i fix this?

Thanks