Get perimeter of pixels around centre pixel












0















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?



image description










share|improve this question



























    0















    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?



    image description










    share|improve this question

























      0












      0








      0








      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?



      image description










      share|improve this question














      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?



      image description







      python opencv trigonometry






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 16 '18 at 9:14









      Jake MJake M

      7,61644135253




      7,61644135253
























          3 Answers
          3






          active

          oldest

          votes


















          2














          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



          enter image description here



          Method 2



          enter image description here



          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





          share|improve this answer





















          • 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











          • @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 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



















          2














          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]))





          share|improve this answer


























          • Thumbs up for the pragmatic approach. :)

            – Dan Mašek
            Nov 16 '18 at 13:22



















          -1














          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]





          share|improve this answer
























          • 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












          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
          });


          }
          });














          draft saved

          draft discarded


















          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









          2














          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



          enter image description here



          Method 2



          enter image description here



          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





          share|improve this answer





















          • 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











          • @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 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
















          2














          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



          enter image description here



          Method 2



          enter image description here



          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





          share|improve this answer





















          • 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











          • @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 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














          2












          2








          2







          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



          enter image description here



          Method 2



          enter image description here



          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





          share|improve this answer















          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



          enter image description here



          Method 2



          enter image description here



          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






          share|improve this answer














          share|improve this answer



          share|improve this answer








          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 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











          • @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













          • @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





            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











          • @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













          • @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













          2














          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]))





          share|improve this answer


























          • Thumbs up for the pragmatic approach. :)

            – Dan Mašek
            Nov 16 '18 at 13:22
















          2














          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]))





          share|improve this answer


























          • Thumbs up for the pragmatic approach. :)

            – Dan Mašek
            Nov 16 '18 at 13:22














          2












          2








          2







          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]))





          share|improve this answer















          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]))






          share|improve this answer














          share|improve this answer



          share|improve this answer








          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



















          • 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











          -1














          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]





          share|improve this answer
























          • 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
















          -1














          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]





          share|improve this answer
























          • 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














          -1












          -1








          -1







          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]





          share|improve this answer













          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]






          share|improve this answer












          share|improve this answer



          share|improve this answer










          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



















          • 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


















          draft saved

          draft discarded




















































          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.




          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          Florida Star v. B. J. F.

          Danny Elfman

          Lugert, Oklahoma