Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

You just need to play with the findContours() and findNonZero()(at the moment there is not any documentation about this function) functions. Have a look, on the code below:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    // Load source image
    string filename = "cloud.png";
    Mat src = imread(filename);

    // Check if image is loaded fine
    if(!src.data)
        cerr << "Problem loading image!!!" << endl;

    // Show source image
    imshow("src", src);

    // Transform source image to gray if it is not
    Mat gray;

    if (src.channels() == 3)
    {
        cvtColor(src, gray, CV_BGR2GRAY);
    }
    else
    {
        gray = src;
    }

    // Show gray image
    imshow("gray", gray);

    // Transform it to binary and invert it. White on black is needed.
    Mat bw;
    threshold(gray, bw, 40, 255, CV_THRESH_BINARY_INV | CV_THRESH_OTSU);

    vector<Point> black_pixels;   // output, locations of non-zero pixels
    cv::findNonZero(bw, black_pixels);

    cout << "Cloud all black pixels: " << black_pixels.size() << endl; // amount of black pixels is returned from the size

    // Show binary image
    imshow("binary", bw);

    vector<Vec4i> hierarchy;
    vector<vector<Point> > contours;
    // extract only the external blob
    findContours(bw, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    Mat mask = Mat::zeros(bw.size(), CV_8UC1);

    // draw the contours as a solid blob, and create a mask of the cloud
    for(size_t i = 0; i < contours.size(); i++)
        drawContours(mask, contours, i, Scalar(255, 255, 255), CV_FILLED, 8, hierarchy, 0, Point());

    imshow("mask", mask);

    vector<Point> all_pixels;   // output, locations of non-zero pixels
    cv::findNonZero(mask, all_pixels);

    cout << "Cloud all pixels: " << all_pixels.size() << endl; // amount of all pixels is returned from the size

    int white_pixels = all_pixels.size() - black_pixels.size(); // amount of white pixels is returned from the subtraction of all - black ;-)

    cout << "Cloud all white pixels: " << white_pixels << endl;

    waitKey(0);
    return 0;
}

You just need to play with the findContours() and findNonZero()(at the moment there is not any documentation about this function) functions. Have a look, on the code below:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    // Load source image
    string filename = "cloud.png";
    Mat src = imread(filename);

    // Check if image is loaded fine
    if(!src.data)
        cerr << "Problem loading image!!!" << endl;

    // Show source image
    imshow("src", src);

    // Transform source image to gray if it is not
    Mat gray;

    if (src.channels() == 3)
    {
        cvtColor(src, gray, CV_BGR2GRAY);
    }
    else
    {
        gray = src;
    }

    // Show gray image
    imshow("gray", gray);

    // Transform it to binary and invert it. White on black is needed.
    Mat bw;
    threshold(gray, bw, 40, 255, CV_THRESH_BINARY_INV | CV_THRESH_OTSU);

    vector<Point> black_pixels;   // output, locations of non-zero pixels
    cv::findNonZero(bw, black_pixels);

    cout << "Cloud all black pixels: " << black_pixels.size() << endl; // amount of black pixels is returned from the size

    // Show binary image
    imshow("binary", bw);

    vector<Vec4i> hierarchy;
    vector<vector<Point> > contours;
    // extract only the external blob
    findContours(bw, findContours(bw.clone(), contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    Mat mask = Mat::zeros(bw.size(), CV_8UC1);

    // draw the contours as a solid blob, and create a mask of the cloud
    for(size_t i = 0; i < contours.size(); i++)
        drawContours(mask, contours, i, Scalar(255, 255, 255), CV_FILLED, 8, hierarchy, 0, Point());

    imshow("mask", mask);

    vector<Point> all_pixels;   // output, locations of non-zero pixels
    cv::findNonZero(mask, all_pixels);

    cout << "Cloud all pixels: " << all_pixels.size() << endl; // amount of all pixels is returned from the size

    int white_pixels = all_pixels.size() - black_pixels.size(); // amount of white pixels is returned from the subtraction of all - black ;-)

    cout << "Cloud all white pixels: " << white_pixels << endl;

    waitKey(0);
    return 0;
}

You just need to play with the findContours() and findNonZero()(at the moment there is not any documentation about this function) findNonZero() functions. Have a look, on the code below:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    // Load source image
    string filename = "cloud.png";
    Mat src = imread(filename);

    // Check if image is loaded fine
    if(!src.data)
        cerr << "Problem loading image!!!" << endl;

    // Show source image
    imshow("src", src);

    // Transform source image to gray if it is not
    Mat gray;

    if (src.channels() == 3)
    {
        cvtColor(src, gray, CV_BGR2GRAY);
    }
    else
    {
        gray = src;
    }

    // Show gray image
    imshow("gray", gray);

    // Transform it to binary and invert it. White on black is needed.
    Mat bw;
    threshold(gray, bw, 40, 255, CV_THRESH_BINARY_INV | CV_THRESH_OTSU);

    vector<Point> black_pixels;   // output, locations of non-zero pixels
    cv::findNonZero(bw, black_pixels);

    cout << "Cloud all black pixels: " << black_pixels.size() << endl; // amount of black pixels is returned from the size

    // Show binary image
    imshow("binary", bw);

    vector<Vec4i> hierarchy;
    vector<vector<Point> > contours;
    // extract only the external blob
    findContours(bw.clone(), contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    Mat mask = Mat::zeros(bw.size(), CV_8UC1);

    // draw the contours as a solid blob, and create a mask of the cloud
    for(size_t i = 0; i < contours.size(); i++)
        drawContours(mask, contours, i, Scalar(255, 255, 255), CV_FILLED, 8, hierarchy, 0, Point());

    imshow("mask", mask);

    vector<Point> all_pixels;   // output, locations of non-zero pixels
    cv::findNonZero(mask, all_pixels);

    cout << "Cloud all pixels: " << all_pixels.size() << endl; // amount of all pixels is returned from the size

    int white_pixels = all_pixels.size() - black_pixels.size(); // amount of white pixels is returned from the subtraction of all - black ;-)

    cout << "Cloud all white pixels: " << white_pixels << endl;

    waitKey(0);
    return 0;
}

You just need to play with the findContours() and findNonZero() functions. functions.

Have a look, on the code below:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    // Load source image
    string filename = "cloud.png";
    Mat src = imread(filename);

    // Check if image is loaded fine
    if(!src.data)
        cerr << "Problem loading image!!!" << endl;

    // Show source image
    imshow("src", src);

    // Transform source image to gray if it is not
    Mat gray;

    if (src.channels() == 3)
    {
        cvtColor(src, gray, CV_BGR2GRAY);
    }
    else
    {
        gray = src;
    }

    // Show gray image
    imshow("gray", gray);

    // Transform it to binary and invert it. White on black is needed.
    Mat bw;
    threshold(gray, bw, 40, 255, CV_THRESH_BINARY_INV | CV_THRESH_OTSU);

    vector<Point> black_pixels;   // output, locations of non-zero pixels
    cv::findNonZero(bw, black_pixels);

    cout << "Cloud all black pixels: " << black_pixels.size() << endl; // amount of black pixels is returned from the size

    // Show binary image
    imshow("binary", bw);

    vector<Vec4i> hierarchy;
    vector<vector<Point> > contours;
    // extract only the external blob
    findContours(bw.clone(), contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    Mat mask = Mat::zeros(bw.size(), CV_8UC1);

    // draw the contours as a solid blob, and create a mask of the cloud
    for(size_t i = 0; i < contours.size(); i++)
        drawContours(mask, contours, i, Scalar(255, 255, 255), CV_FILLED, 8, hierarchy, 0, Point());

    imshow("mask", mask);

    vector<Point> all_pixels;   // output, locations of non-zero pixels
    cv::findNonZero(mask, all_pixels);

    cout << "Cloud all pixels: " << all_pixels.size() << endl; // amount of all pixels is returned from the size

    int white_pixels = all_pixels.size() - black_pixels.size(); // amount of white pixels is returned from the subtraction of all - black ;-)

    cout << "Cloud all white pixels: " << white_pixels << endl;

    waitKey(0);
    return 0;
}