Ask Your Question
1

How to get boundry and center information of a mask

asked 2018-11-27 08:31:28 -0600

Raki gravatar image

updated 2018-11-27 08:32:09 -0600

Hi,

I have the following mask:

mask

and I would like to get this mask's center position as well as its boundary positions. Since this is not a rigid geometric shape, I don't know how exactly one could get its center, hence my question.

As for the boundary information, do we need to use a contour detector? Is there a simpler way?

Thanks in advance.

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
3

answered 2018-11-27 10:07:47 -0600

This python code performs what you want.

# Import required packages:
import cv2

# Load the image and convert it to grayscale:
image = cv2.imread("test_image.png")
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Apply cv2.threshold() to get a binary image
ret, thresh = cv2.threshold(gray_image, 50, 255, cv2.THRESH_BINARY)

# Find contours:
im, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

# Draw contours:
cv2.drawContours(image, contours, 0, (0, 255, 0), 2)

# Calculate image moments of the detected contour
M = cv2.moments(contours[0])

# Print center (debugging):
print("center X : '{}'".format(round(M['m10'] / M['m00'])))
print("center Y : '{}'".format(round(M['m01'] / M['m00'])))

# Draw a circle based centered at centroid coordinates
cv2.circle(image, (round(M['m10'] / M['m00']), round(M['m01'] / M['m00'])), 5, (0, 255, 0), -1)

# Show image:
cv2.imshow("outline contour & centroid", image)

# Wait until a key is pressed:
cv2.waitKey(0)

# Destroy all created windows:
cv2.destroyAllWindows()

image description

edit flag offensive delete link more

Comments

Indeed it does perform it. Marvelous, Thanks!

Raki gravatar imageRaki ( 2018-11-27 10:11:02 -0600 )edit

Just a question: Is there a way to get the image coordinates of the moments? Like, given a contour, getting all the coordinates of the boundaries?

Raki gravatar imageRaki ( 2018-12-03 02:18:13 -0600 )edit
1

x_centroid = round(M['m10'] / M['m00'])

 y_centroid = round(M['m01'] / M['m00'])
albertofernandez gravatar imagealbertofernandez ( 2018-12-06 04:15:02 -0600 )edit
0

answered 2018-11-27 08:39:17 -0600

LBerger gravatar image

updated 2018-11-27 08:41:38 -0600

Use findContours and you can get geometry using moment

I think minEnclosingCircle or minAreaRect can help you for shape

edit flag offensive delete link more

Comments

Do these methods work with a binary image though? If not, is there a way to convert my mask to the format the contour function requires? TypeError: src data type = 0 is not supported

Raki gravatar imageRaki ( 2018-11-27 09:24:21 -0600 )edit

Doc : Source, an 8-bit single-channel image. Non-zero pixels are treated as 1's. Zero pixels remain 0's, so the image is treated as binary

LBerger gravatar imageLBerger ( 2018-11-27 09:28:18 -0600 )edit

I have a boolean array and it does not work with it. I converted it into integer array but then TypeError: Layout of the output array image is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels).

Raki gravatar imageRaki ( 2018-11-27 09:36:29 -0600 )edit
1

python -> myMat = mybool.astype(np.uint8)

LBerger gravatar imageLBerger ( 2018-11-27 09:41:18 -0600 )edit
LBerger gravatar imageLBerger ( 2018-11-27 10:39:54 -0600 )edit

This code worked for me as well but I have more than one blob. How can I do this for multiple blobs?

ayshine gravatar imageayshine ( 2020-12-22 03:09:27 -0600 )edit

@ayshine this forum can be closed at any moment. May be you should ask your question at https://forum.opencv.org/

LBerger gravatar imageLBerger ( 2020-12-22 03:14:14 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2018-11-27 08:31:28 -0600

Seen: 19,100 times

Last updated: Nov 27 '18