python - 乳房 X 光检查中最大轮廓的 OpenCV 分割

标签 python opencv image-processing image-segmentation

这可能是一个有点太“笼统”的问题,但是如何执行灰度图像分割并保持最大轮廓?我试图从乳房 X 光照片中消除背景噪音(即标签),但没有成功。这是原图:

enter image description here

首先,我应用了 AGCWD 算法(基于论文“Efficient Contrast Enhancement using Adaptive Gamma Correction With Weighting Distribution”)以获得更好的图像像素对比度,如下所示: enter image description here

之后,我尝试执行以下步骤:

使用 OpenCV 的 KMeans 聚类算法进行图像分割:

enhanced_image_cpy = enhanced_image.copy()
reshaped_image = np.float32(enhanced_image_cpy.reshape(-1, 1))

number_of_clusters = 10
stop_criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.1)

ret, labels, clusters = cv2.kmeans(reshaped_image, number_of_clusters, None, stop_criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
clusters = np.uint8(clusters)

Canny 边缘检测:

removed_cluster = 1

canny_image = np.copy(enhanced_image_cpy).reshape((-1, 1))
canny_image[labels.flatten() == removed_cluster] = [0]

canny_image = cv2.Canny(canny_image,100,200).reshape(enhanced_image_cpy.shape)
show_images([canny_image])

查找并绘制轮廓:

initial_contours_image = np.copy(canny_image)
initial_contours_image_bgr = cv2.cvtColor(initial_contours_image, cv2.COLOR_GRAY2BGR)
_, thresh = cv2.threshold(initial_contours_image, 50, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(initial_contours_image_bgr, contours, -1, (255,0,0), cv2.CHAIN_APPROX_SIMPLE)
show_images([initial_contours_image_bgr])

这是我绘制 44004 个轮廓后图像的外观:

enter image description here

我不知道如何才能得到一个大轮廓,而不是 44004 个小轮廓。任何如何解决我的方法的想法,或者可能有任何关于使用替代方法来摆脱右上角标签的想法。

提前致谢!

最佳答案

这是在 Python OpenCV 中执行此操作的一种方法

阅读图片

  • 阈值并反转,使边框为黑色
  • 按照如下方式去除图像的边框(以便后面更容易得到相关轮廓):
  • 计算每列中非零像素的数量,并找到计数大于 0 的第一列和最后一列
  • 计算每行中非零像素的数量,并找到计数大于 0 的第一行和最后一行
  • 裁剪图像以去除边框
  • 裁剪 thresh1 并反转以制作 thresh2
  • 从 thresh2 获取外部轮廓
  • 找到最大的轮廓并在黑色背景上绘制白色填充作为蒙版
  • 将裁剪图像中 mask 为黑色的所有像素设为黑色
  • 保存结果 -

输入:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread('xray3.png')

# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# threshold and invert
thresh1 = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)[1]
thresh1 = 255 - thresh1

# remove borders
# count number of white pixels in columns as new 1D array
count_cols = np.count_nonzero(thresh1, axis=0)

# get first and last x coordinate where black
first_x = np.where(count_cols>0)[0][0]
last_x = np.where(count_cols>0)[0][-1]
print(first_x,last_x)

# count number of white pixels in rows as new 1D array
count_rows = np.count_nonzero(thresh1, axis=1)

# get first and last y coordinate where black
first_y = np.where(count_rows>0)[0][0]
last_y = np.where(count_rows>0)[0][-1]
print(first_y,last_y)

# crop image
crop = img[first_y:last_y+1, first_x:last_x+1]

# crop thresh1 and invert
thresh2 = thresh1[first_y:last_y+1, first_x:last_x+1]
thresh2 = 255 - thresh2

# get external contours and keep largest one
contours = cv2.findContours(thresh2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)

# make mask from contour
mask = np.zeros_like(thresh2 , dtype=np.uint8)
cv2.drawContours(mask, [big_contour], 0, 255, -1)

# make crop black everywhere except where largest contour is white in mask
result = crop.copy()
result[mask==0] = (0,0,0)

# write result to disk
cv2.imwrite("xray3_thresh1.jpg", thresh1)
cv2.imwrite("xray3_crop.jpg", crop)
cv2.imwrite("xray3_thresh2.jpg", thresh2)
cv2.imwrite("xray3_mask.jpg", mask)
cv2.imwrite("xray3_result.png", result)

# display it
cv2.imshow("thresh1", thresh1)
cv2.imshow("crop", crop)
cv2.imshow("thresh2", thresh2)
cv2.imshow("mask", mask)
cv2.imshow("result", result)
cv2.waitKey(0)

阈值 1 图像:

enter image description here

裁剪后的图像:

enter image description here

阈值 2 图像:

enter image description here

蒙版图像:

enter image description here

结果:

enter image description here

关于python - 乳房 X 光检查中最大轮廓的 OpenCV 分割,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64850305/

相关文章:

python - 与 Python 2.7 中的 ModuleNotFoundError 类似的异常?

python - OpenCV 错误 : Assertion failed when using COLOR_BGR2GRAY function

c++ - 为什么霍夫变换检测到两条线而只有一条线

opencv - OpenCV-仅显示关键点而不使用SIFT显示图像

matlab - 使用DCT将图像分解为两个频率分量?

java - 使用 JasperReports 在每个页面上创建折叠机的 OMR 图像

python - 导入skimage导入数据报错,过滤器

python - 将队列转储到python中的列表/数组中

python - 按平均小时数分组

python - 你如何在 Python 中找到 2 个点以直角相交的点?