Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I extract only the middle bone in this image using only erosion, dilation, and, xor and thresholding?

I am using opencv to extract the middle big bone from this image and I can’t seem to workout how to do itInput Image

Where I am right now

As you see, all 3 bones are showing but I only want the middle bone
Here is the code

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

b =  cv.imread('content/B.tif', cv.IMREAD_GRAYSCALE)

plt.figure(figsize=(5,5))
plt.imshow(b, cmap='gray')
plt.axis('off')
plt.show()

_, binary_b = cv.threshold(b, 200, 255, cv.THRESH_BINARY)
b_e = cv.erode(binary_b, np.ones((1,1), dtype=np.uint8))
b_d = cv.dilate(b_e, np.ones((5,5), dtype=np.uint8),iterations = 3)

xor = cv.bitwise_and(b_d,b)

plt.figure(figsize=(5,5))
plt.imshow(xor, cmap='gray')
plt.axis('off')
plt.show()

Can someone help please?

>Solution :

I tried to find the center bone as it’s largest using contour. Please see code below with explanation in comments. Hope this helps.

import cv2
import numpy as np

#Read image and convert to gray scale
image = cv2.imread("bone.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, thresholded_image = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)

#Dilate image to close gaps
#Erode image to remove additional edges created using dilation
#number of iteration found by trial and error
kernel = np.ones((5,5),np.uint8)
thresholded_image = cv2.dilate(thresholded_image, kernel,iterations=5)
thresholded_image = cv2.erode(thresholded_image, kernel,iterations=5)

#get the contour of dilate eroded image
contours, hierarchy = cv2.findContours(thresholded_image, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

#Since center bone is largest
#Find contour with max length
max_length=0
max_length_ctr=None
for ctr in contours:
    x,y,w,h = cv2.boundingRect(ctr)
    if h > max_length:
        max_length = h
        max_length_ctr = ctr

#Use the found contour to create mask and get the bone
if max_length_ctr is not None:
    big_bone_mask = np.zeros_like(thresholded_image)
    cv2.drawContours(big_bone_mask, [max_length_ctr], -1, (255, 255, 255), -1)
    cv2.imwrite("big_bone_mask.png",big_bone_mask)

    # Get the graph from original image from the mask
    bone_image = cv2.bitwise_and(image, image, mask=big_bone_mask)
    cv2.imwrite("bone_image.png", bone_image)

Output
enter image description here

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading