Get perimeter of pixels around centre pixel
I am attempting to get a circle of pixels around a centre pixel. Ie, just like how FAST keypoint detector works, I want to get the perimeter pixels around it given a radius. However the math escapes me, I know theoretically how I could obtain it using trigonometry. Ie, I could use a for loop and iterate at 15 degrees. I know the triangle hypotenuse length is the radius, I know the angle.
Any advice how I could obtain a perimeter of pixels around a given pixel?
python opencv trigonometry
add a comment |
I am attempting to get a circle of pixels around a centre pixel. Ie, just like how FAST keypoint detector works, I want to get the perimeter pixels around it given a radius. However the math escapes me, I know theoretically how I could obtain it using trigonometry. Ie, I could use a for loop and iterate at 15 degrees. I know the triangle hypotenuse length is the radius, I know the angle.
Any advice how I could obtain a perimeter of pixels around a given pixel?
python opencv trigonometry
add a comment |
I am attempting to get a circle of pixels around a centre pixel. Ie, just like how FAST keypoint detector works, I want to get the perimeter pixels around it given a radius. However the math escapes me, I know theoretically how I could obtain it using trigonometry. Ie, I could use a for loop and iterate at 15 degrees. I know the triangle hypotenuse length is the radius, I know the angle.
Any advice how I could obtain a perimeter of pixels around a given pixel?
python opencv trigonometry
I am attempting to get a circle of pixels around a centre pixel. Ie, just like how FAST keypoint detector works, I want to get the perimeter pixels around it given a radius. However the math escapes me, I know theoretically how I could obtain it using trigonometry. Ie, I could use a for loop and iterate at 15 degrees. I know the triangle hypotenuse length is the radius, I know the angle.
Any advice how I could obtain a perimeter of pixels around a given pixel?
python opencv trigonometry
python opencv trigonometry
asked Nov 16 '18 at 9:14
Jake MJake M
7,61644135253
7,61644135253
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
The formula is:
(x-cx)**2 + (y-cy)**2 = r**2
where cx and cy is the center of the circle and x and y are the coordinates you want to test... Now we can iterate over x and get the y with the formula like this:
y = sqrt(r**2 - (x-cx)**2) + cy
The other way will be to iterate the 360 degrees and calculate the x and y and add the offset (center) like this:
x = cos(radians) * radius + cx
y = sin(radians) * radius + cy
The second version gave me a more complete circle in my tests. Here is my test script in python:
import numpy as np
import cv2
import math
img = np.zeros((480, 640, 1), dtype="uint8")
img2 = np.zeros((480, 640, 1), dtype="uint8")
center = (200, 200)
radius = 100
x = np.arange(center[0] - radius, center[0]+radius+1)
y_off = np.sqrt(radius**2 - (x - center[0]) **2)
y1 = np.int32(np.round(center[1] + y_off))
y2 = np.int32(np.round(center[1] - y_off))
img[y1, x] = 255
img[y2, x] = 255
degrees = np.arange(360)
x = np.int32(np.round(np.cos(degrees) * radius)) + center[0]
y = np.int32(np.round(np.sin(degrees) * radius)) + center[1]
img2[y,x] = 255
cv2.imshow("First method", img)
cv2.imshow("Second method", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
and the results are these:
Method 1
Method 2
There is a third method... You take a box around the circle of size radius x radius and evaluate each point with the circle formula given above, if it is true then it is a circle point... however that is good to draw the whole circle, since you have integers and highly probable not many point will be equal...
UPDATE:
Just a small reminder, make sure your points are in the image, in the example above, if you put the center in 0,0 it will draw 1/4 of a circle in every corner, because it considers the negative values to start from the end of the array.
To remove duplicates you can try the following code:
c = np.unique(np.array(list(zip(y,x))), axis=0 )
img2[c[:,0], c[:,1]] = 255
1
Both functions could be vectorized pretty easily. The second one in particular---just replace themath
functions withnumpy
functions and use an array ford
. You can directly index the image with the two pairs of corresponding arrays for the x and y coordinates (after rounding and explicitly casting to an int).
– Alexander Reynolds
Nov 16 '18 at 10:28
@AlexanderReynolds true, I will edit them in a moment
– api55
Nov 16 '18 at 10:34
@api55 Thanks, your second solution works great. It does however always spit out 360 points even if the number of points around the centre is less than 360. For example a radius of 1, it produces 360 points instead of 4 or 8. Do you know how I could determine the angle step size? Ie, if the radius is 1 the step size would be 45 or 90.
– Jake M
Nov 16 '18 at 10:35
@api55 maybe the following is correct? Instead offor d in range(360):
it would befor d in range(0, 360, math.floor(360 / (radius * 4))):
replace4
for8
depending.
– Jake M
Nov 16 '18 at 10:41
@JakeM the thing is that a lot of the points will be the same... you can always filter duplicates. But maybe you can do something like to divide by the radius * 4, but put a mask to it
– api55
Nov 16 '18 at 10:42
|
show 3 more comments
Just draw the circle onto a mask:
In [27]: mask = np.zeros((9, 9), dtype=np.uint8)
In [28]: cv2.circle(mask, center=(4, 4), radius=4, color=255, thickness=1)
Out[28]:
array([[ 0, 0, 0, 0, 255, 0, 0, 0, 0],
[ 0, 0, 255, 255, 0, 255, 255, 0, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[255, 0, 0, 0, 0, 0, 0, 0, 255],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 0, 255, 255, 0, 255, 255, 0, 0],
[ 0, 0, 0, 0, 255, 0, 0, 0, 0]], dtype=uint8)
And now you can use it to index your image as you like. E.g., here's a random image:
In [33]: img
Out[33]:
array([[ 88, 239, 212, 160, 89, 85, 249, 242, 88],
[ 47, 230, 206, 206, 63, 143, 152, 67, 58],
[162, 212, 0, 213, 208, 169, 228, 14, 229],
[230, 45, 103, 201, 188, 231, 80, 122, 131],
[159, 31, 148, 158, 73, 215, 152, 158, 235],
[213, 177, 148, 237, 92, 115, 152, 188, 223],
[234, 67, 141, 173, 14, 18, 242, 208, 147],
[ 53, 194, 229, 141, 37, 215, 230, 167, 82],
[ 72, 78, 152, 76, 230, 128, 137, 25, 168]], dtype=uint8)
Here's the values on the perimeter:
In [34]: img[np.nonzero(mask)]
Out[34]:
array([ 89, 206, 206, 143, 152, 212, 14, 45, 122, 159, 235, 177, 188,
67, 208, 229, 141, 215, 230, 230], dtype=uint8)
Setting the value of the image at the perimeter of the circle to 0:
In [35]: img[np.nonzero(mask)] = 0
In [36]: img
Out[36]:
array([[ 88, 239, 212, 160, 0, 85, 249, 242, 88],
[ 47, 230, 0, 0, 63, 0, 0, 67, 58],
[162, 0, 0, 213, 208, 169, 228, 0, 229],
[230, 0, 103, 201, 188, 231, 80, 0, 131],
[ 0, 31, 148, 158, 73, 215, 152, 158, 0],
[213, 0, 148, 237, 92, 115, 152, 0, 223],
[234, 0, 141, 173, 14, 18, 242, 0, 147],
[ 53, 194, 0, 0, 37, 0, 0, 167, 82],
[ 72, 78, 152, 76, 0, 128, 137, 25, 168]], dtype=uint8)
You can easily get the coordinates as well:
In [56]: np.where(mask)
Out[56]:
(array([0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8]),
array([4, 2, 3, 5, 6, 1, 7, 1, 7, 0, 8, 1, 7, 1, 7, 2, 3, 5, 6, 4]))
Thumbs up for the pragmatic approach. :)
– Dan Mašek
Nov 16 '18 at 13:22
add a comment |
Assume img
is your image, radius
is the radius of the circle and x, y
are the coordinates of the center around which you want to focus.
The the focus_img
can be obtained using
offset = math.ceil(radius * math.sqrt(2))
focus_img = img[y-offset:y+offset, x-offset:x+offset]
OP is asking for the perimeter pixels on the edge of the circle, not an ROI centered around the circle.
– Alexander Reynolds
Nov 16 '18 at 9:47
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53334694%2fget-perimeter-of-pixels-around-centre-pixel%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
The formula is:
(x-cx)**2 + (y-cy)**2 = r**2
where cx and cy is the center of the circle and x and y are the coordinates you want to test... Now we can iterate over x and get the y with the formula like this:
y = sqrt(r**2 - (x-cx)**2) + cy
The other way will be to iterate the 360 degrees and calculate the x and y and add the offset (center) like this:
x = cos(radians) * radius + cx
y = sin(radians) * radius + cy
The second version gave me a more complete circle in my tests. Here is my test script in python:
import numpy as np
import cv2
import math
img = np.zeros((480, 640, 1), dtype="uint8")
img2 = np.zeros((480, 640, 1), dtype="uint8")
center = (200, 200)
radius = 100
x = np.arange(center[0] - radius, center[0]+radius+1)
y_off = np.sqrt(radius**2 - (x - center[0]) **2)
y1 = np.int32(np.round(center[1] + y_off))
y2 = np.int32(np.round(center[1] - y_off))
img[y1, x] = 255
img[y2, x] = 255
degrees = np.arange(360)
x = np.int32(np.round(np.cos(degrees) * radius)) + center[0]
y = np.int32(np.round(np.sin(degrees) * radius)) + center[1]
img2[y,x] = 255
cv2.imshow("First method", img)
cv2.imshow("Second method", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
and the results are these:
Method 1
Method 2
There is a third method... You take a box around the circle of size radius x radius and evaluate each point with the circle formula given above, if it is true then it is a circle point... however that is good to draw the whole circle, since you have integers and highly probable not many point will be equal...
UPDATE:
Just a small reminder, make sure your points are in the image, in the example above, if you put the center in 0,0 it will draw 1/4 of a circle in every corner, because it considers the negative values to start from the end of the array.
To remove duplicates you can try the following code:
c = np.unique(np.array(list(zip(y,x))), axis=0 )
img2[c[:,0], c[:,1]] = 255
1
Both functions could be vectorized pretty easily. The second one in particular---just replace themath
functions withnumpy
functions and use an array ford
. You can directly index the image with the two pairs of corresponding arrays for the x and y coordinates (after rounding and explicitly casting to an int).
– Alexander Reynolds
Nov 16 '18 at 10:28
@AlexanderReynolds true, I will edit them in a moment
– api55
Nov 16 '18 at 10:34
@api55 Thanks, your second solution works great. It does however always spit out 360 points even if the number of points around the centre is less than 360. For example a radius of 1, it produces 360 points instead of 4 or 8. Do you know how I could determine the angle step size? Ie, if the radius is 1 the step size would be 45 or 90.
– Jake M
Nov 16 '18 at 10:35
@api55 maybe the following is correct? Instead offor d in range(360):
it would befor d in range(0, 360, math.floor(360 / (radius * 4))):
replace4
for8
depending.
– Jake M
Nov 16 '18 at 10:41
@JakeM the thing is that a lot of the points will be the same... you can always filter duplicates. But maybe you can do something like to divide by the radius * 4, but put a mask to it
– api55
Nov 16 '18 at 10:42
|
show 3 more comments
The formula is:
(x-cx)**2 + (y-cy)**2 = r**2
where cx and cy is the center of the circle and x and y are the coordinates you want to test... Now we can iterate over x and get the y with the formula like this:
y = sqrt(r**2 - (x-cx)**2) + cy
The other way will be to iterate the 360 degrees and calculate the x and y and add the offset (center) like this:
x = cos(radians) * radius + cx
y = sin(radians) * radius + cy
The second version gave me a more complete circle in my tests. Here is my test script in python:
import numpy as np
import cv2
import math
img = np.zeros((480, 640, 1), dtype="uint8")
img2 = np.zeros((480, 640, 1), dtype="uint8")
center = (200, 200)
radius = 100
x = np.arange(center[0] - radius, center[0]+radius+1)
y_off = np.sqrt(radius**2 - (x - center[0]) **2)
y1 = np.int32(np.round(center[1] + y_off))
y2 = np.int32(np.round(center[1] - y_off))
img[y1, x] = 255
img[y2, x] = 255
degrees = np.arange(360)
x = np.int32(np.round(np.cos(degrees) * radius)) + center[0]
y = np.int32(np.round(np.sin(degrees) * radius)) + center[1]
img2[y,x] = 255
cv2.imshow("First method", img)
cv2.imshow("Second method", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
and the results are these:
Method 1
Method 2
There is a third method... You take a box around the circle of size radius x radius and evaluate each point with the circle formula given above, if it is true then it is a circle point... however that is good to draw the whole circle, since you have integers and highly probable not many point will be equal...
UPDATE:
Just a small reminder, make sure your points are in the image, in the example above, if you put the center in 0,0 it will draw 1/4 of a circle in every corner, because it considers the negative values to start from the end of the array.
To remove duplicates you can try the following code:
c = np.unique(np.array(list(zip(y,x))), axis=0 )
img2[c[:,0], c[:,1]] = 255
1
Both functions could be vectorized pretty easily. The second one in particular---just replace themath
functions withnumpy
functions and use an array ford
. You can directly index the image with the two pairs of corresponding arrays for the x and y coordinates (after rounding and explicitly casting to an int).
– Alexander Reynolds
Nov 16 '18 at 10:28
@AlexanderReynolds true, I will edit them in a moment
– api55
Nov 16 '18 at 10:34
@api55 Thanks, your second solution works great. It does however always spit out 360 points even if the number of points around the centre is less than 360. For example a radius of 1, it produces 360 points instead of 4 or 8. Do you know how I could determine the angle step size? Ie, if the radius is 1 the step size would be 45 or 90.
– Jake M
Nov 16 '18 at 10:35
@api55 maybe the following is correct? Instead offor d in range(360):
it would befor d in range(0, 360, math.floor(360 / (radius * 4))):
replace4
for8
depending.
– Jake M
Nov 16 '18 at 10:41
@JakeM the thing is that a lot of the points will be the same... you can always filter duplicates. But maybe you can do something like to divide by the radius * 4, but put a mask to it
– api55
Nov 16 '18 at 10:42
|
show 3 more comments
The formula is:
(x-cx)**2 + (y-cy)**2 = r**2
where cx and cy is the center of the circle and x and y are the coordinates you want to test... Now we can iterate over x and get the y with the formula like this:
y = sqrt(r**2 - (x-cx)**2) + cy
The other way will be to iterate the 360 degrees and calculate the x and y and add the offset (center) like this:
x = cos(radians) * radius + cx
y = sin(radians) * radius + cy
The second version gave me a more complete circle in my tests. Here is my test script in python:
import numpy as np
import cv2
import math
img = np.zeros((480, 640, 1), dtype="uint8")
img2 = np.zeros((480, 640, 1), dtype="uint8")
center = (200, 200)
radius = 100
x = np.arange(center[0] - radius, center[0]+radius+1)
y_off = np.sqrt(radius**2 - (x - center[0]) **2)
y1 = np.int32(np.round(center[1] + y_off))
y2 = np.int32(np.round(center[1] - y_off))
img[y1, x] = 255
img[y2, x] = 255
degrees = np.arange(360)
x = np.int32(np.round(np.cos(degrees) * radius)) + center[0]
y = np.int32(np.round(np.sin(degrees) * radius)) + center[1]
img2[y,x] = 255
cv2.imshow("First method", img)
cv2.imshow("Second method", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
and the results are these:
Method 1
Method 2
There is a third method... You take a box around the circle of size radius x radius and evaluate each point with the circle formula given above, if it is true then it is a circle point... however that is good to draw the whole circle, since you have integers and highly probable not many point will be equal...
UPDATE:
Just a small reminder, make sure your points are in the image, in the example above, if you put the center in 0,0 it will draw 1/4 of a circle in every corner, because it considers the negative values to start from the end of the array.
To remove duplicates you can try the following code:
c = np.unique(np.array(list(zip(y,x))), axis=0 )
img2[c[:,0], c[:,1]] = 255
The formula is:
(x-cx)**2 + (y-cy)**2 = r**2
where cx and cy is the center of the circle and x and y are the coordinates you want to test... Now we can iterate over x and get the y with the formula like this:
y = sqrt(r**2 - (x-cx)**2) + cy
The other way will be to iterate the 360 degrees and calculate the x and y and add the offset (center) like this:
x = cos(radians) * radius + cx
y = sin(radians) * radius + cy
The second version gave me a more complete circle in my tests. Here is my test script in python:
import numpy as np
import cv2
import math
img = np.zeros((480, 640, 1), dtype="uint8")
img2 = np.zeros((480, 640, 1), dtype="uint8")
center = (200, 200)
radius = 100
x = np.arange(center[0] - radius, center[0]+radius+1)
y_off = np.sqrt(radius**2 - (x - center[0]) **2)
y1 = np.int32(np.round(center[1] + y_off))
y2 = np.int32(np.round(center[1] - y_off))
img[y1, x] = 255
img[y2, x] = 255
degrees = np.arange(360)
x = np.int32(np.round(np.cos(degrees) * radius)) + center[0]
y = np.int32(np.round(np.sin(degrees) * radius)) + center[1]
img2[y,x] = 255
cv2.imshow("First method", img)
cv2.imshow("Second method", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
and the results are these:
Method 1
Method 2
There is a third method... You take a box around the circle of size radius x radius and evaluate each point with the circle formula given above, if it is true then it is a circle point... however that is good to draw the whole circle, since you have integers and highly probable not many point will be equal...
UPDATE:
Just a small reminder, make sure your points are in the image, in the example above, if you put the center in 0,0 it will draw 1/4 of a circle in every corner, because it considers the negative values to start from the end of the array.
To remove duplicates you can try the following code:
c = np.unique(np.array(list(zip(y,x))), axis=0 )
img2[c[:,0], c[:,1]] = 255
edited Nov 16 '18 at 11:59
answered Nov 16 '18 at 9:59
api55api55
7,15042546
7,15042546
1
Both functions could be vectorized pretty easily. The second one in particular---just replace themath
functions withnumpy
functions and use an array ford
. You can directly index the image with the two pairs of corresponding arrays for the x and y coordinates (after rounding and explicitly casting to an int).
– Alexander Reynolds
Nov 16 '18 at 10:28
@AlexanderReynolds true, I will edit them in a moment
– api55
Nov 16 '18 at 10:34
@api55 Thanks, your second solution works great. It does however always spit out 360 points even if the number of points around the centre is less than 360. For example a radius of 1, it produces 360 points instead of 4 or 8. Do you know how I could determine the angle step size? Ie, if the radius is 1 the step size would be 45 or 90.
– Jake M
Nov 16 '18 at 10:35
@api55 maybe the following is correct? Instead offor d in range(360):
it would befor d in range(0, 360, math.floor(360 / (radius * 4))):
replace4
for8
depending.
– Jake M
Nov 16 '18 at 10:41
@JakeM the thing is that a lot of the points will be the same... you can always filter duplicates. But maybe you can do something like to divide by the radius * 4, but put a mask to it
– api55
Nov 16 '18 at 10:42
|
show 3 more comments
1
Both functions could be vectorized pretty easily. The second one in particular---just replace themath
functions withnumpy
functions and use an array ford
. You can directly index the image with the two pairs of corresponding arrays for the x and y coordinates (after rounding and explicitly casting to an int).
– Alexander Reynolds
Nov 16 '18 at 10:28
@AlexanderReynolds true, I will edit them in a moment
– api55
Nov 16 '18 at 10:34
@api55 Thanks, your second solution works great. It does however always spit out 360 points even if the number of points around the centre is less than 360. For example a radius of 1, it produces 360 points instead of 4 or 8. Do you know how I could determine the angle step size? Ie, if the radius is 1 the step size would be 45 or 90.
– Jake M
Nov 16 '18 at 10:35
@api55 maybe the following is correct? Instead offor d in range(360):
it would befor d in range(0, 360, math.floor(360 / (radius * 4))):
replace4
for8
depending.
– Jake M
Nov 16 '18 at 10:41
@JakeM the thing is that a lot of the points will be the same... you can always filter duplicates. But maybe you can do something like to divide by the radius * 4, but put a mask to it
– api55
Nov 16 '18 at 10:42
1
1
Both functions could be vectorized pretty easily. The second one in particular---just replace the
math
functions with numpy
functions and use an array for d
. You can directly index the image with the two pairs of corresponding arrays for the x and y coordinates (after rounding and explicitly casting to an int).– Alexander Reynolds
Nov 16 '18 at 10:28
Both functions could be vectorized pretty easily. The second one in particular---just replace the
math
functions with numpy
functions and use an array for d
. You can directly index the image with the two pairs of corresponding arrays for the x and y coordinates (after rounding and explicitly casting to an int).– Alexander Reynolds
Nov 16 '18 at 10:28
@AlexanderReynolds true, I will edit them in a moment
– api55
Nov 16 '18 at 10:34
@AlexanderReynolds true, I will edit them in a moment
– api55
Nov 16 '18 at 10:34
@api55 Thanks, your second solution works great. It does however always spit out 360 points even if the number of points around the centre is less than 360. For example a radius of 1, it produces 360 points instead of 4 or 8. Do you know how I could determine the angle step size? Ie, if the radius is 1 the step size would be 45 or 90.
– Jake M
Nov 16 '18 at 10:35
@api55 Thanks, your second solution works great. It does however always spit out 360 points even if the number of points around the centre is less than 360. For example a radius of 1, it produces 360 points instead of 4 or 8. Do you know how I could determine the angle step size? Ie, if the radius is 1 the step size would be 45 or 90.
– Jake M
Nov 16 '18 at 10:35
@api55 maybe the following is correct? Instead of
for d in range(360):
it would be for d in range(0, 360, math.floor(360 / (radius * 4))):
replace 4
for 8
depending.– Jake M
Nov 16 '18 at 10:41
@api55 maybe the following is correct? Instead of
for d in range(360):
it would be for d in range(0, 360, math.floor(360 / (radius * 4))):
replace 4
for 8
depending.– Jake M
Nov 16 '18 at 10:41
@JakeM the thing is that a lot of the points will be the same... you can always filter duplicates. But maybe you can do something like to divide by the radius * 4, but put a mask to it
– api55
Nov 16 '18 at 10:42
@JakeM the thing is that a lot of the points will be the same... you can always filter duplicates. But maybe you can do something like to divide by the radius * 4, but put a mask to it
– api55
Nov 16 '18 at 10:42
|
show 3 more comments
Just draw the circle onto a mask:
In [27]: mask = np.zeros((9, 9), dtype=np.uint8)
In [28]: cv2.circle(mask, center=(4, 4), radius=4, color=255, thickness=1)
Out[28]:
array([[ 0, 0, 0, 0, 255, 0, 0, 0, 0],
[ 0, 0, 255, 255, 0, 255, 255, 0, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[255, 0, 0, 0, 0, 0, 0, 0, 255],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 0, 255, 255, 0, 255, 255, 0, 0],
[ 0, 0, 0, 0, 255, 0, 0, 0, 0]], dtype=uint8)
And now you can use it to index your image as you like. E.g., here's a random image:
In [33]: img
Out[33]:
array([[ 88, 239, 212, 160, 89, 85, 249, 242, 88],
[ 47, 230, 206, 206, 63, 143, 152, 67, 58],
[162, 212, 0, 213, 208, 169, 228, 14, 229],
[230, 45, 103, 201, 188, 231, 80, 122, 131],
[159, 31, 148, 158, 73, 215, 152, 158, 235],
[213, 177, 148, 237, 92, 115, 152, 188, 223],
[234, 67, 141, 173, 14, 18, 242, 208, 147],
[ 53, 194, 229, 141, 37, 215, 230, 167, 82],
[ 72, 78, 152, 76, 230, 128, 137, 25, 168]], dtype=uint8)
Here's the values on the perimeter:
In [34]: img[np.nonzero(mask)]
Out[34]:
array([ 89, 206, 206, 143, 152, 212, 14, 45, 122, 159, 235, 177, 188,
67, 208, 229, 141, 215, 230, 230], dtype=uint8)
Setting the value of the image at the perimeter of the circle to 0:
In [35]: img[np.nonzero(mask)] = 0
In [36]: img
Out[36]:
array([[ 88, 239, 212, 160, 0, 85, 249, 242, 88],
[ 47, 230, 0, 0, 63, 0, 0, 67, 58],
[162, 0, 0, 213, 208, 169, 228, 0, 229],
[230, 0, 103, 201, 188, 231, 80, 0, 131],
[ 0, 31, 148, 158, 73, 215, 152, 158, 0],
[213, 0, 148, 237, 92, 115, 152, 0, 223],
[234, 0, 141, 173, 14, 18, 242, 0, 147],
[ 53, 194, 0, 0, 37, 0, 0, 167, 82],
[ 72, 78, 152, 76, 0, 128, 137, 25, 168]], dtype=uint8)
You can easily get the coordinates as well:
In [56]: np.where(mask)
Out[56]:
(array([0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8]),
array([4, 2, 3, 5, 6, 1, 7, 1, 7, 0, 8, 1, 7, 1, 7, 2, 3, 5, 6, 4]))
Thumbs up for the pragmatic approach. :)
– Dan Mašek
Nov 16 '18 at 13:22
add a comment |
Just draw the circle onto a mask:
In [27]: mask = np.zeros((9, 9), dtype=np.uint8)
In [28]: cv2.circle(mask, center=(4, 4), radius=4, color=255, thickness=1)
Out[28]:
array([[ 0, 0, 0, 0, 255, 0, 0, 0, 0],
[ 0, 0, 255, 255, 0, 255, 255, 0, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[255, 0, 0, 0, 0, 0, 0, 0, 255],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 0, 255, 255, 0, 255, 255, 0, 0],
[ 0, 0, 0, 0, 255, 0, 0, 0, 0]], dtype=uint8)
And now you can use it to index your image as you like. E.g., here's a random image:
In [33]: img
Out[33]:
array([[ 88, 239, 212, 160, 89, 85, 249, 242, 88],
[ 47, 230, 206, 206, 63, 143, 152, 67, 58],
[162, 212, 0, 213, 208, 169, 228, 14, 229],
[230, 45, 103, 201, 188, 231, 80, 122, 131],
[159, 31, 148, 158, 73, 215, 152, 158, 235],
[213, 177, 148, 237, 92, 115, 152, 188, 223],
[234, 67, 141, 173, 14, 18, 242, 208, 147],
[ 53, 194, 229, 141, 37, 215, 230, 167, 82],
[ 72, 78, 152, 76, 230, 128, 137, 25, 168]], dtype=uint8)
Here's the values on the perimeter:
In [34]: img[np.nonzero(mask)]
Out[34]:
array([ 89, 206, 206, 143, 152, 212, 14, 45, 122, 159, 235, 177, 188,
67, 208, 229, 141, 215, 230, 230], dtype=uint8)
Setting the value of the image at the perimeter of the circle to 0:
In [35]: img[np.nonzero(mask)] = 0
In [36]: img
Out[36]:
array([[ 88, 239, 212, 160, 0, 85, 249, 242, 88],
[ 47, 230, 0, 0, 63, 0, 0, 67, 58],
[162, 0, 0, 213, 208, 169, 228, 0, 229],
[230, 0, 103, 201, 188, 231, 80, 0, 131],
[ 0, 31, 148, 158, 73, 215, 152, 158, 0],
[213, 0, 148, 237, 92, 115, 152, 0, 223],
[234, 0, 141, 173, 14, 18, 242, 0, 147],
[ 53, 194, 0, 0, 37, 0, 0, 167, 82],
[ 72, 78, 152, 76, 0, 128, 137, 25, 168]], dtype=uint8)
You can easily get the coordinates as well:
In [56]: np.where(mask)
Out[56]:
(array([0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8]),
array([4, 2, 3, 5, 6, 1, 7, 1, 7, 0, 8, 1, 7, 1, 7, 2, 3, 5, 6, 4]))
Thumbs up for the pragmatic approach. :)
– Dan Mašek
Nov 16 '18 at 13:22
add a comment |
Just draw the circle onto a mask:
In [27]: mask = np.zeros((9, 9), dtype=np.uint8)
In [28]: cv2.circle(mask, center=(4, 4), radius=4, color=255, thickness=1)
Out[28]:
array([[ 0, 0, 0, 0, 255, 0, 0, 0, 0],
[ 0, 0, 255, 255, 0, 255, 255, 0, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[255, 0, 0, 0, 0, 0, 0, 0, 255],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 0, 255, 255, 0, 255, 255, 0, 0],
[ 0, 0, 0, 0, 255, 0, 0, 0, 0]], dtype=uint8)
And now you can use it to index your image as you like. E.g., here's a random image:
In [33]: img
Out[33]:
array([[ 88, 239, 212, 160, 89, 85, 249, 242, 88],
[ 47, 230, 206, 206, 63, 143, 152, 67, 58],
[162, 212, 0, 213, 208, 169, 228, 14, 229],
[230, 45, 103, 201, 188, 231, 80, 122, 131],
[159, 31, 148, 158, 73, 215, 152, 158, 235],
[213, 177, 148, 237, 92, 115, 152, 188, 223],
[234, 67, 141, 173, 14, 18, 242, 208, 147],
[ 53, 194, 229, 141, 37, 215, 230, 167, 82],
[ 72, 78, 152, 76, 230, 128, 137, 25, 168]], dtype=uint8)
Here's the values on the perimeter:
In [34]: img[np.nonzero(mask)]
Out[34]:
array([ 89, 206, 206, 143, 152, 212, 14, 45, 122, 159, 235, 177, 188,
67, 208, 229, 141, 215, 230, 230], dtype=uint8)
Setting the value of the image at the perimeter of the circle to 0:
In [35]: img[np.nonzero(mask)] = 0
In [36]: img
Out[36]:
array([[ 88, 239, 212, 160, 0, 85, 249, 242, 88],
[ 47, 230, 0, 0, 63, 0, 0, 67, 58],
[162, 0, 0, 213, 208, 169, 228, 0, 229],
[230, 0, 103, 201, 188, 231, 80, 0, 131],
[ 0, 31, 148, 158, 73, 215, 152, 158, 0],
[213, 0, 148, 237, 92, 115, 152, 0, 223],
[234, 0, 141, 173, 14, 18, 242, 0, 147],
[ 53, 194, 0, 0, 37, 0, 0, 167, 82],
[ 72, 78, 152, 76, 0, 128, 137, 25, 168]], dtype=uint8)
You can easily get the coordinates as well:
In [56]: np.where(mask)
Out[56]:
(array([0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8]),
array([4, 2, 3, 5, 6, 1, 7, 1, 7, 0, 8, 1, 7, 1, 7, 2, 3, 5, 6, 4]))
Just draw the circle onto a mask:
In [27]: mask = np.zeros((9, 9), dtype=np.uint8)
In [28]: cv2.circle(mask, center=(4, 4), radius=4, color=255, thickness=1)
Out[28]:
array([[ 0, 0, 0, 0, 255, 0, 0, 0, 0],
[ 0, 0, 255, 255, 0, 255, 255, 0, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[255, 0, 0, 0, 0, 0, 0, 0, 255],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 0, 255, 255, 0, 255, 255, 0, 0],
[ 0, 0, 0, 0, 255, 0, 0, 0, 0]], dtype=uint8)
And now you can use it to index your image as you like. E.g., here's a random image:
In [33]: img
Out[33]:
array([[ 88, 239, 212, 160, 89, 85, 249, 242, 88],
[ 47, 230, 206, 206, 63, 143, 152, 67, 58],
[162, 212, 0, 213, 208, 169, 228, 14, 229],
[230, 45, 103, 201, 188, 231, 80, 122, 131],
[159, 31, 148, 158, 73, 215, 152, 158, 235],
[213, 177, 148, 237, 92, 115, 152, 188, 223],
[234, 67, 141, 173, 14, 18, 242, 208, 147],
[ 53, 194, 229, 141, 37, 215, 230, 167, 82],
[ 72, 78, 152, 76, 230, 128, 137, 25, 168]], dtype=uint8)
Here's the values on the perimeter:
In [34]: img[np.nonzero(mask)]
Out[34]:
array([ 89, 206, 206, 143, 152, 212, 14, 45, 122, 159, 235, 177, 188,
67, 208, 229, 141, 215, 230, 230], dtype=uint8)
Setting the value of the image at the perimeter of the circle to 0:
In [35]: img[np.nonzero(mask)] = 0
In [36]: img
Out[36]:
array([[ 88, 239, 212, 160, 0, 85, 249, 242, 88],
[ 47, 230, 0, 0, 63, 0, 0, 67, 58],
[162, 0, 0, 213, 208, 169, 228, 0, 229],
[230, 0, 103, 201, 188, 231, 80, 0, 131],
[ 0, 31, 148, 158, 73, 215, 152, 158, 0],
[213, 0, 148, 237, 92, 115, 152, 0, 223],
[234, 0, 141, 173, 14, 18, 242, 0, 147],
[ 53, 194, 0, 0, 37, 0, 0, 167, 82],
[ 72, 78, 152, 76, 0, 128, 137, 25, 168]], dtype=uint8)
You can easily get the coordinates as well:
In [56]: np.where(mask)
Out[56]:
(array([0, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7, 7, 8]),
array([4, 2, 3, 5, 6, 1, 7, 1, 7, 0, 8, 1, 7, 1, 7, 2, 3, 5, 6, 4]))
edited Nov 16 '18 at 10:41
answered Nov 16 '18 at 10:14
Alexander ReynoldsAlexander Reynolds
10.3k12344
10.3k12344
Thumbs up for the pragmatic approach. :)
– Dan Mašek
Nov 16 '18 at 13:22
add a comment |
Thumbs up for the pragmatic approach. :)
– Dan Mašek
Nov 16 '18 at 13:22
Thumbs up for the pragmatic approach. :)
– Dan Mašek
Nov 16 '18 at 13:22
Thumbs up for the pragmatic approach. :)
– Dan Mašek
Nov 16 '18 at 13:22
add a comment |
Assume img
is your image, radius
is the radius of the circle and x, y
are the coordinates of the center around which you want to focus.
The the focus_img
can be obtained using
offset = math.ceil(radius * math.sqrt(2))
focus_img = img[y-offset:y+offset, x-offset:x+offset]
OP is asking for the perimeter pixels on the edge of the circle, not an ROI centered around the circle.
– Alexander Reynolds
Nov 16 '18 at 9:47
add a comment |
Assume img
is your image, radius
is the radius of the circle and x, y
are the coordinates of the center around which you want to focus.
The the focus_img
can be obtained using
offset = math.ceil(radius * math.sqrt(2))
focus_img = img[y-offset:y+offset, x-offset:x+offset]
OP is asking for the perimeter pixels on the edge of the circle, not an ROI centered around the circle.
– Alexander Reynolds
Nov 16 '18 at 9:47
add a comment |
Assume img
is your image, radius
is the radius of the circle and x, y
are the coordinates of the center around which you want to focus.
The the focus_img
can be obtained using
offset = math.ceil(radius * math.sqrt(2))
focus_img = img[y-offset:y+offset, x-offset:x+offset]
Assume img
is your image, radius
is the radius of the circle and x, y
are the coordinates of the center around which you want to focus.
The the focus_img
can be obtained using
offset = math.ceil(radius * math.sqrt(2))
focus_img = img[y-offset:y+offset, x-offset:x+offset]
answered Nov 16 '18 at 9:21
SilverSlashSilverSlash
670414
670414
OP is asking for the perimeter pixels on the edge of the circle, not an ROI centered around the circle.
– Alexander Reynolds
Nov 16 '18 at 9:47
add a comment |
OP is asking for the perimeter pixels on the edge of the circle, not an ROI centered around the circle.
– Alexander Reynolds
Nov 16 '18 at 9:47
OP is asking for the perimeter pixels on the edge of the circle, not an ROI centered around the circle.
– Alexander Reynolds
Nov 16 '18 at 9:47
OP is asking for the perimeter pixels on the edge of the circle, not an ROI centered around the circle.
– Alexander Reynolds
Nov 16 '18 at 9:47
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53334694%2fget-perimeter-of-pixels-around-centre-pixel%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown