I want to straighten the hand in the image based on the middle finger. I have about 10000 of these hand X-ray images to preprocess. The preprocess I did so far:
- Apply Gaussian Blur and Threshold (Binary Otsu) on the image.
- Apply dilation to get a single object (in this case a hand).
- Used
cv2.findContours()
to draw outline along the edges around the hand. - Apply
cv2.convexHull()
and thencv2.convexityDefects()
to mark the points that are farthest away from the convex hull. To filter out the ones of interest between the fingers, I only considered those that are more than a certain distance from the convex hull.
The code below describes the above-mentioned:
import cv2
import numpy as np
from matplotlib import pyplot as plt
img_path = "sample_image.png"
# Getting the threshold of the image:
image = cv2.imread("sample_image.png")
original = image.copy()
blank = np.zeros(image.shape[:2], dtype = np.uint8)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (127,127), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY cv2.THRESH_OTSU)[1]
# Merge into a single contour
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
dilate = cv2.dilate(thresh, kernel, iterations = 2)
# Drawing the contours along the edges of the hand in X-ray:
contours, hierarchy = cv2.findContours(dilate, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours = max(contours, key = lambda x: cv2.contourArea(x))
cv2.drawContours(image, [contours], -1, (255,255,0), 2)
# To mark the points that are farthest away from the convex hull, one for each "convexity defect"
hull = cv2.convexHull(contours, returnPoints = False)
defects = cv2.convexityDefects(contours, hull)
for i in range(defects.shape[0]):
_, _, farthest_point_index, distance = defects[i, 0]
farthest_point = contours[farthest_point_index][0]
if distance > 50_000:
circle = cv2.circle(image, farthest_point, 20, [0,0,255], -1)