我正在尝试对胸部 X 光图像进行肺部分割
import cv2
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
def margin(img, margin_percent=10):
h, w = img.shape
margin_x = int(w * margin_percent / 100)
margin_y = int(h * margin_percent / 100)
cropped = img[margin_y:h-margin_y, margin_x:w-margin_x]
return cropped
def process(img):
flat_img = img.flatten().reshape(-1, 1)
kmeans = KMeans(n_clusters=2, n_init=10, random_state=0)
labels = kmeans.fit_predict(flat_img)
centers = kmeans.cluster_centers_
if np.mean(centers[1]) > np.mean(centers[0]):
labels = 1 - labels
clustered = np.reshape(labels, img.shape)
clustered_binary = np.uint8(clustered * 255)
return clustered_binary
def segment_and_filter(clustered_img):
ret, thresh = cv2.threshold(clustered_img, 0, 255, cv2.THRESH_BINARY)
if cv2.__version__[0] > '3':
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
else:
_, contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
max_area = 0
largest_contour = None
for contour in contours:
area = cv2.contourArea(contour)
if area > max_area:
max_area = area
largest_contour = contour
result = np.zeros_like(clustered_img)
cv2.drawContours(result, [largest_contour], -1, 255, thickness=cv2.FILLED)
return result, largest_contour
def process_image(image_path):
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
cropped_img = margin(img)
clustered_img = process(cropped_img)
filtered_result, largest_contour = segment_and_filter(clustered_img)
combined_image = np.hstack((filtered_result[:, :filtered_result.shape[1] // 2],
cv2.flip(filtered_result[:, :filtered_result.shape[1] // 2], 1)))
return combined_image
image_path = "/kaggle/input/chest-xray-pneumonia/chest_xray/test/NORMAL/IM-0105-0001.jpeg"
result_image = process_image(image_path)
plt.figure(figsize=(9, 3))
plt.imshow(result_image, cmap='gray')
plt.title('Combined Lungs')
plt.axis('on')
plt.show()
上面的代码给出了这个输出 到目前为止一切都很好
现在我想拟合一条覆盖两个肺部区域的抛物线 尝试了多次 但这没有用
你能帮我吗?
尝试过单肺得到这个,但对两个都不起作用
预计
希望这对您有帮助。
import cv2
import numpy as np
import matplotlib.pyplot as plt
def preprocess_image(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
equalized = cv2.equalizeHist(gray)
return equalized
def segment_lungs(image):
_, binary = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
binary = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel, iterations=2)
binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel, iterations=2)
return binary
image_path = "image.png"
image = cv2.imread(image_path)
preprocessed_image = preprocess_image(image)
lung_mask = segment_lungs(preprocessed_image)
if cv2.__version__[0] > '3':
contours, _ = cv2.findContours(lung_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
else:
_, contours, _ = cv2.findContours(lung_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
top_points = []
for contour in contours:
top_point = tuple(contour[contour[:, :, 1].argmin()][0])
top_points.append(top_point)
top_points = np.array(top_points)
sorted_top_points = top_points[np.argsort(top_points[:, 0])]
x = sorted_top_points[:, 0]
y = sorted_top_points[:, 1]
coefficients = np.polyfit(x, y, 2)
a, b, c = coefficients
x_values = np.linspace(min(x), max(x), 100)
y_values = a * x_values ** 2 + b * x_values + c
plt.imshow(image, cmap='gray')
for contour in contours:
plt.plot(contour[:, 0, 0], contour[:, 0, 1], 'r', linewidth=2)
plt.plot(x_values, y_values, 'b', linewidth=5)
plt.title('Lung Segmentation with Fitted Parabola')
plt.axis('off')
plt.show()