Revision history [back]

You should take a look at the documentation and tutorials. They contain almost everything you need to know. Unfortunately, this isn't quite a standard function. You can find the functions I'm talking about here in the documentation to see what they do and what the parameters mean.

So, there are lots of ways to do this, but I'm going to suggest an unusual one.

First, make sure all your pixels are 1 or 0, and the image is NOT of type float.

[cv::normalize](http://docs.opencv.org/3.1.0/d2/de8/group__core__array.html#ga87eef7ee3970f86906d69a92cbf064bd)(BnW, zeroOne, 1, 0, cv::NORM_MINMAX, CV_8U);


Then create an image of a circle of radius 5. There's a function that does that already.

cv::Mat circ;
circ = [cv::getStructuringElement](http://docs.opencv.org/3.1.0/d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc)(cv::MORPH_ELLIPSE, cv::Size(9,9));


Next, convolve the image with the circle.

[cv::filter2d](http://docs.opencv.org/3.1.0/d4/d86/group__imgproc__filter.html#ga27c049795ce870216ddfb366086b5a04)(zeroOne, zeroOne, CV_32F, circ, cv::Point(-1,-1), 0, cv::BORDER_CONSTANT);


Now each pixel contains the count of the number of pixels that were 1 in the circle centered on it. So the first circle you wanted was centered at (5,5), touching the top and left borders. So access that pixel like this: zeroOne.at<float>(cv::Point(5,5)); and it returns the number of 1s in that circle.

This should be significantly quicker than looping over the image, creating masks and using the cv::sum() function.

You should take a look at the documentation and tutorials. They contain almost everything you need to know. Unfortunately, this isn't quite a standard function. You can find the functions I'm talking about here in the documentation to see what they do and what the parameters mean.

So, there are lots of ways to do this, but I'm going to suggest an unusual one.

First, make sure all your pixels are 1 or 0, and the image is NOT of type float.

[cv::normalize](http://docs.opencv.org/3.1.0/d2/de8/group__core__array.html#ga87eef7ee3970f86906d69a92cbf064bd)(BnW, cv::normalize(BnW, zeroOne, 1, 0, cv::NORM_MINMAX, CV_8U);


cv::normalize documentation.

Then create an image of a circle of radius 5. There's a function that does that already.

cv::Mat circ;
circ = [cv::getStructuringElement](http://docs.opencv.org/3.1.0/d4/d86/group__imgproc__filter.html#gac342a1bb6eabf6f55c803b09268e36dc)(cv::MORPH_ELLIPSE, cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(9,9));


cv::getStructuringElement documentation.

Next, convolve the image with the circle.

[cv::filter2d](http://docs.opencv.org/3.1.0/d4/d86/group__imgproc__filter.html#ga27c049795ce870216ddfb366086b5a04)(zeroOne, cv::filter2D(zeroOne, zeroOne, CV_32F, circ, cv::Point(-1,-1), 0, cv::BORDER_CONSTANT);


cv::filter2d documentation

Now each pixel contains the count of the number of pixels that were 1 in the circle centered on it. So the first circle you wanted was centered at (5,5), touching the top and left borders. So access that pixel like this: zeroOne.at<float>(cv::Point(5,5)); and it returns the number of 1s in that circle.

This should be significantly quicker than looping over the image, creating masks and using the cv::sum() function.

You should take a look at the documentation and tutorials. They contain almost everything you need to know. Unfortunately, this isn't quite a standard function. You can find the functions I'm talking about here in the documentation to see what they do and what the parameters mean.

So, there are lots of ways to do this, but I'm going to suggest an unusual one.

First, make sure all your pixels are 1 or 0, and the image is NOT of type float.

cv::normalize(BnW, zeroOne, 1, 0, cv::NORM_MINMAX, CV_8U);


cv::normalize documentation.

Then create an image of a circle of radius 5. There's a function that does that already.

cv::Mat circ;
circ = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(9,9));


cv::getStructuringElement documentation.

Next, convolve the image with the circle.

cv::filter2D(zeroOne, zeroOne, CV_32F, circ, cv::Point(-1,-1), 0, cv::BORDER_CONSTANT);


cv::filter2d documentation

Now each pixel contains the count of the number of pixels that were 1 in the circle centered on it. So the first circle you wanted was centered at (5,5), touching the top and left borders. So access that pixel like this: zeroOne.at<float>(cv::Point(5,5)); and it returns the number of 1s in that circle.

This should be significantly quicker than looping over the image, creating masks and using the cv::sum() function.

EDIT:

So you don't want to divide the image into a grid of radius 5 circles, you want to slowly increase the size of the circle until the whole image is included? That's a very different problem.

Tell you what, you check out THIS tutorial and PAGE1, PAGE2, PAGE3 and PAGE4. If you read the tutorial and the first page you'll know how to find the center. The rest will help you create the sum of the points in a circle.

Once you've figured out how to do it for one circle (which is pretty simple), come back here and I can try to help you do it for all circles without repeating too much work.

Why are you trying to do this as image processing though? I would think that just finding each non-zero pixel, calculating the distance from the center, adding it to a list, and sorting would solve your problem much much quicker.