# Manipulate Image

I have a B&W image of size 200 X 200. I want to divide this image into circles of pixel width say 5 pixels and want to count the number of white pixels in the cropped circle. So the radius should be of 5 pixels. How can I get the centre of image ? After the first crop of radius 5 pixels, i want to again crop starting from 6th pixel with radius length 5 pixels and do the same till the whole image is divided into circles.

Can anyone help me in understanding the OpenCV library function which are there to perform this task ? I want to know which functions are there and how parameters are passed to achieve this.

The input image supposed to look like this C:\fakepath\Untitled drawing.png I want to divide the image in such circles denoted by different colours and then measure the no. of white pixels in each region.

Newb to OpenCV. Any help is appreciated. Thanks in advance

edit retag close merge delete

Sort by » oldest newest most voted

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.

more

Thank you so much for the answer @Tetragramm . I also wanted to know how I will calculate the centre of the image and then start cutting the image into circle of radius 5 ? Like how will I refer to the centre of location with co-ordinates (0,0) ?

( 2016-09-13 01:16:57 -0500 )edit

I don't understand the question.

( 2016-09-13 07:32:54 -0500 )edit

Changed the main question a bit (changes are formatted in bold and italic in the main question) as there was no option to add attachment while replying to your comment. May be that part will help you in understanding my problem better.

( 2016-09-13 11:52:54 -0500 )edit

Again thank you so much for the reply and help @Tetragramm, really appreciate it. I will definitely write some code first now and will come back again in case if I am stuck somewhere. One small thing I wanted you to know is that I will be measuring the no. of white pixels in the circle with width denoted by specific colour, so I will not be increasing the size (or radius) of the circle from centre of the image by 5 pixels for each iteration. I am doing this for character recognition using "Ring Features", have a look at this Reference Paper

( 2016-09-13 13:16:54 -0500 )edit

So you just want the count in the next 5 pixels out from the previous one? That's still really a job for a sorted list of distances rather than image processing.

( 2016-09-13 18:08:36 -0500 )edit

I am open to suggestion if you think other method would work just fine for this. The Reference Paper which I have mentioned demands this, this is a technique used for character recognition called as "Ring Features" .

( 2016-09-14 06:28:42 -0500 )edit

Take a look at the first tutorial I linked and the PAGE1 link. Those teach you how to access individual pixels.

Create a vector of doubles, and create a loop that looks through every pixel in the image. If it's greater than zero, calculate the distance to the center and push that onto the vector. Sort the vector, and you get all the ring features at once. Count all the distance values less than 5, then between 5 and 6, and so forth.

( 2016-09-14 17:44:20 -0500 )edit

So doing the image processing thing will be a computational overhead as compared to the method you have suggested ?

( 2016-09-15 00:36:07 -0500 )edit

Very much so. You would have to search through the image several times for every circle, as opposed to once total for the list.

( 2016-09-15 07:44:18 -0500 )edit

The option you have suggested won't require OpenCV ?

( 2016-09-19 09:44:49 -0500 )edit

Official site

GitHub

Wiki

Documentation