68 KiB
68 KiB
In [ ]:
import requests
import json
# Пример запроса к TCIA API, предполагающий JSON формат
url = "https://services.cancerimagingarchive.net/services/v3/TCIA/query/getSeries?Collection=TCGA-BRCA&format=json"
response = requests.get(url)
# Проверка ответа
if response.status_code == 200:
print("Данные получены успешно")
# Преобразование ответа в JSON
try:
data = response.json()
if data:
print(json.dumps(data, indent=4)) # Печать данных в формате JSON с отступами
# Обработка данных
for item in data:
series_instance_uid = item.get('SeriesInstanceUID', 'N/A')
modality = item.get('Modality', 'N/A')
protocol_name = item.get('ProtocolName', 'N/A')
body_part_examined = item.get('BodyPartExamined', 'N/A')
# Печать извлеченной информации
print(f"SeriesInstanceUID: {series_instance_uid}")
print(f"Modality: {modality}")
print(f"ProtocolName: {protocol_name}")
print(f"BodyPartExamined: {body_part_examined}")
print('-' * 30)
else:
print("Нет данных для отображения.")
except json.JSONDecodeError:
print("Ошибка преобразования ответа в JSON.")
else:
print(f"Ошибка получения данных. Статус код: {response.status_code}")
In [ ]:
import os
import requests
# Пример использования SeriesInstanceUID
series_instance_uid = "1.3.6.1.4.1.14519.5.2.1.6450.4002.265963154110062013582166845425" # Пример идентификатора
# URL для загрузки изображений
url = f"https://services.cancerimagingarchive.net/services/v3/TCIA/query/getImage?SeriesInstanceUID={series_instance_uid}"
response = requests.get(url, stream=True)
# Путь для сохранения ZIP-файла
output_path = "/content/images.zip"
# Создание необходимых папок, если их нет
folder_path = os.path.dirname(output_path)
os.makedirs(folder_path, exist_ok=True)
# Проверка ответа и сохранение изображения
if response.status_code == 200:
print(f"Сохранение файла в {output_path}")
with open(output_path, "wb") as file:
for chunk in response.iter_content(chunk_size=128):
file.write(chunk)
print(f"Изображения успешно загружены и сохранены как {output_path}")
else:
print("Ошибка при загрузке изображений")In [ ]:
import zipfile
# Распаковка загруженного ZIP-файла
with zipfile.ZipFile("images.zip", 'r') as zip_ref:
zip_ref.extractall("images") # Папка для распакованных изображений
print("Файлы успешно распакованы")In [ ]:
!pip install pydicomIn [ ]:
pip install scikit-imageIn [ ]:
import os
import random
import pydicom
import matplotlib.pyplot as plt
# Папка с распакованными изображениями
dicom_folder = "images"
# Сбор всех DICOM-файлов в папке
dicom_files = [os.path.join(dicom_folder, filename) for filename in os.listdir(dicom_folder) if filename.endswith(".dcm")]
# Проверка, что в папке достаточно файлов для выбора 20
num_files_to_show = min(20, len(dicom_files))
# Выбор случайных файлов из списка случайным образом
random_files = random.sample(dicom_files, num_files_to_show)
# Визуализация выбранных изображений
for dicom_path in random_files:
dicom_data = pydicom.dcmread(dicom_path)
# Получение массива пикселей изображения
image = dicom_data.pixel_array
# Визуализация изображения
filename = os.path.basename(dicom_path)
plt.imshow(image, cmap="gray")
plt.title(f"Файл: {filename}\nПациент ID: {dicom_data.PatientID}")
plt.axis("off")
plt.show()
In [ ]:
In [ ]:
import os
import random
import pydicom
import matplotlib.pyplot as plt
import cv2
import numpy as np
import skimage.restoration as restoration
# Папка с распакованными изображениями
dicom_folder = "images"
# Сбор всех DICOM-файлов в папке
dicom_files = [filename for filename in os.listdir(dicom_folder) if filename.endswith(".dcm")]
# Запрос у пользователя названий файлов для отображения
file_names = input("Введите названия файлов изображений через запятую: ").split(",")
file_names = [name.strip() for name in file_names]
# Поиск указанных файлов в папке
selected_files = []
for filename in file_names:
found_files = [os.path.join(dicom_folder, f) for f in dicom_files if filename in f]
selected_files.extend(found_files)
# Визуализация выбранных изображений
for dicom_path in selected_files:
if os.path.exists(dicom_path):
dicom_data = pydicom.dcmread(dicom_path)
# Получение массива пикселей изображения
image = dicom_data.pixel_array
# Визуализация изображения
filename = os.path.basename(dicom_path)
plt.imshow(image, cmap="gray")
plt.title(f"Файл: {filename}\nПациент ID: {dicom_data.PatientID}")
plt.axis("off")
plt.show()
# Применение адаптивного медианного фильтра для улучшения качества изображений перед сегментацией
for dicom_path in selected_files:
if os.path.exists(dicom_path):
dicom_data = pydicom.dcmread(dicom_path)
image = dicom_data.pixel_array
# Преобразование изображения в формат uint8, если это необходимо
if image.dtype != np.uint8:
image = cv2.normalize(image, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
# Применение адаптивного медианного фильтра для сглаживания шума
filtered_image = restoration.denoise_bilateral(image, sigma_color=0.01, sigma_spatial=11, channel_axis=None)
# Преобразование фильтрованного изображения обратно в формат uint8
filtered_image = (filtered_image * 255).astype(np.uint8)
# Визуализация фильтрованного изображения
filename = os.path.basename(dicom_path)
plt.imshow(filtered_image, cmap="gray")
plt.title(f"Фильтрованное изображение: {filename}")
plt.axis("off")
plt.show()In [ ]:
import os
import random
import pydicom
import matplotlib.pyplot as plt
import cv2
import numpy as np
import skimage.restoration as restoration
# Папка с распакованными изображениями
dicom_folder = "images"
# Сбор всех DICOM-файлов в папке
dicom_files = [filename for filename in os.listdir(dicom_folder) if filename.endswith(".dcm")]
# Запрос у пользователя названий файлов для отображения
file_names = input("Введите названия файлов изображений через запятую: ").split(",")
file_names = [name.strip() for name in file_names]
# Поиск указанных файлов в папке
selected_files = []
for filename in file_names:
found_files = [os.path.join(dicom_folder, f) for f in dicom_files if filename in f]
selected_files.extend(found_files)
# Визуализация выбранных изображений
for dicom_path in selected_files:
if os.path.exists(dicom_path):
dicom_data = pydicom.dcmread(dicom_path)
# Получение массива пикселей изображения
image = dicom_data.pixel_array
# Обрезка верхней 1/3 изображения
height = image.shape[0]
cropped_image = image[height // 3:, :]
# Применение адаптивного выравнивания гистограммы (CLAHE)
clahe = cv2.createCLAHE(clipLimit=0.5, tileGridSize=(3, 3))
cropped_image = clahe.apply(cropped_image.astype(np.uint8))
# Визуализация обрезанного изображения
filename = os.path.basename(dicom_path)
plt.imshow(cropped_image, cmap="gray")
plt.title(f"Обрезанное изображение: {filename}\nПациент ID: {dicom_data.PatientID}")
plt.axis("off")
plt.show()
# Применение адаптивного медианного фильтра для улучшения качества изображений перед сегментацией
for dicom_path in selected_files:
if os.path.exists(dicom_path):
dicom_data = pydicom.dcmread(dicom_path)
image = dicom_data.pixel_array
# Обрезка верхней 1/3 изображения
height = image.shape[0]
cropped_image = image[height // 3:, :]
# Преобразование изображения в формат uint8, если это необходимо
if cropped_image.dtype != np.uint8:
cropped_image = cv2.normalize(cropped_image, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
# Применение адаптивного медианного фильтра для сглаживания шума
filtered_image = restoration.denoise_bilateral(cropped_image, sigma_color=0.05, sigma_spatial=5, channel_axis=None)
# Преобразование фильтрованного изображения обратно в формат uint8
filtered_image = (filtered_image * 255).astype(np.uint8)
# Применение алгоритма водораздела для сегментации изображения
# Создание маски для водораздела
_, binary_image = cv2.threshold(filtered_image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
distance_transform = cv2.distanceTransform(binary_image, cv2.DIST_L2, 5)
_, sure_fg = cv2.threshold(distance_transform, 0.9 * distance_transform.max(), 255, 0)
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(binary_image, sure_fg)
# Маркировка объектов
num_markers, markers = cv2.connectedComponents(sure_fg)
markers = markers + 1
markers[unknown == 255] = 0
# Применение водораздела
markers = cv2.watershed(cv2.cvtColor(filtered_image, cv2.COLOR_GRAY2BGR), markers)
segmented_image = np.zeros_like(filtered_image)
segmented_image[markers == -1] = 255
# Наложение сегментированного изображения на исходное с зелеными границами
original_image_bgr = cv2.cvtColor(cropped_image, cv2.COLOR_GRAY2BGR)
original_image_bgr[markers == -1] = [0, 255, 0] # Установка зеленого цвета для границ
# Визуализация наложенного изображения
filename = os.path.basename(dicom_path)
plt.imshow(cv2.cvtColor(original_image_bgr, cv2.COLOR_BGR2RGB))
plt.title(f"Сегментированное изображение с наложением (водораздел): {filename}")
plt.axis("off")
plt.show()
In [ ]:
import os
import random
import pydicom
import matplotlib.pyplot as plt
import cv2
import numpy as np
# Папка с распакованными изображениями
dicom_folder = "images"
# Сбор всех DICOM-файлов в папке
dicom_files = [filename for filename in os.listdir(dicom_folder) if filename.endswith(".dcm")]
# Запрос у пользователя названий файлов для отображения
file_names = input("Введите названия файлов изображений через запятую: ").split(",")
file_names = [name.strip() for name in file_names]
# Поиск указанных файлов в папке
selected_files = []
for filename in file_names:
found_files = [os.path.join(dicom_folder, f) for f in dicom_files if filename in f]
selected_files.extend(found_files)
# Визуализация выбранных изображений
for dicom_path in selected_files:
if os.path.exists(dicom_path):
dicom_data = pydicom.dcmread(dicom_path)
# Получение массива пикселей изображения
image = dicom_data.pixel_array
# Визуализация изображения
filename = os.path.basename(dicom_path)
plt.imshow(image, cmap="gray")
plt.title(f"Файл: {filename}\nПациент ID: {dicom_data.PatientID}")
plt.axis("off")
plt.show()
# Применение обработки изображений перед сегментацией
for dicom_path in selected_files:
if os.path.exists(dicom_path):
dicom_data = pydicom.dcmread(dicom_path)
image = dicom_data.pixel_array
# Обрезка верхней трети изображения
height, width = image.shape
cropped_image = image[height // 3: , :]
# Преобразование изображения в формат uint8, если это необходимо
if cropped_image.dtype != np.uint8:
cropped_image = cv2.normalize(cropped_image, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
# Применение адаптивного выравнивания гистограммы для повышения контрастности
clahe = cv2.createCLAHE(clipLimit=1.5, tileGridSize=(8, 8))
enhanced_image = clahe.apply(cropped_image)
# Визуализация улучшенного изображения
filename = os.path.basename(dicom_path)
plt.imshow(enhanced_image, cmap="gray")
plt.title(f"Улучшенное изображение: {filename}")
plt.axis("off")
plt.show()
# Применение пороговой сегментации
threshold_value = 100 # Порог можно изменять в зависимости от задачи
_, thresholded_image = cv2.threshold(enhanced_image, threshold_value, 255, cv2.THRESH_BINARY)
# Визуализация пороговой сегментации
plt.imshow(thresholded_image, cmap="gray")
plt.title(f"Пороговая сегментация: {filename}")
plt.axis("off")
plt.show()
# Наложение сегментированного изображения на исходное с зеленой линией
contours, _ = cv2.findContours(thresholded_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
overlay_image = cv2.cvtColor(cropped_image, cv2.COLOR_GRAY2BGR)
cv2.drawContours(overlay_image, contours, -1, (0, 255, 0), 1)
# Визуализация наложенного изображения
plt.imshow(cv2.cvtColor(overlay_image, cv2.COLOR_BGR2RGB))
plt.title(f"Наложенное изображение: {filename}")
plt.axis("off")
plt.show()
In [ ]:
pip install fuzzy-c-meansIn [ ]:
pip install tabulate>=0.9.0In [ ]:
import cv2
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import expit
from fcmeans import FCM # Для Fuzzy C-means
# Загрузка изображения
image_path = "/content/8.png" # Укажите путь к вашему изображению
input_image = cv2.imread(image_path)
if input_image is None:
raise FileNotFoundError(f"Не удалось загрузить изображение по указанному пути: {image_path}")
# Функция для отображения изображения
def show_image(image, title):
plt.figure(figsize=(10, 10))
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title(title)
plt.axis('off')
plt.show()
# Функция для разложения изображения на базовый слой и детали
def multiscale_decomposition(image, kernel_size=5):
base_layer = cv2.GaussianBlur(image, (kernel_size, kernel_size), 0)
detail_layer_1 = cv2.subtract(image, base_layer)
detail_layer_2 = cv2.subtract(base_layer, cv2.GaussianBlur(base_layer, (kernel_size, kernel_size), 0))
return base_layer, detail_layer_1, detail_layer_2
# Функция для применения сигмоиды к каждому пикселю
def sigmoid(x, a=1):
return expit(a * x)
# Функция для применения тонового улучшения на основе трехуровневой декомпозиции
def multiscale_tone_enhancement(image, delta_0=1.1, delta_1=2.5, delta_2=2.2, alpha=0.5):
# Разложение изображения на базовый слой и два слоя детализации
base_layer, detail_layer_1, detail_layer_2 = multiscale_decomposition(image, kernel_size=5)
# Среднее значение яркости для каждого канала
mu = np.mean(base_layer, axis=(0, 1))
# Применение S-симгмоиды для управления усилением деталей
S = lambda x: sigmoid((x - mu) / 255.0, a=alpha)
# Усиление базового слоя и слоев детализации
enhanced_image = base_layer + delta_0 * (base_layer - mu) + \
0.9 * S(detail_layer_1) * (delta_1 * detail_layer_1) + \
0.9 * S(detail_layer_2) * (delta_2 * detail_layer_2)
# Клиппинг результата в допустимый диапазон [0, 255]
enhanced_image = np.clip(enhanced_image, 0, 255).astype(np.uint8)
return enhanced_image
# Применение тонового улучшения
enhanced_image = multiscale_tone_enhancement(input_image)
# Преобразование изображения в градации серого для FCM
gray_image = cv2.cvtColor(enhanced_image, cv2.COLOR_BGR2GRAY)
# Преобразование изображения в формат, подходящий для FCM
reshaped_image = gray_image.flatten().astype(np.float64) / 255.0
# Применение Fuzzy C-means
num_clusters = 5 # Задайте количество кластеров
fcm = FCM(n_clusters=num_clusters)
fcm.fit(reshaped_image.reshape(-1, 1))
cluster_labels = fcm.u.argmax(axis=1) # Метки кластеров
# Преобразование кластеров в форму изображения
segmented_image = cluster_labels.reshape(gray_image.shape)
# Отображение результатов
show_image(input_image, 'Original Image')
show_image(enhanced_image, 'Enhanced Image')
plt.figure(figsize=(10, 10))
plt.imshow(segmented_image, cmap="jet")
plt.title("Fuzzy C-means Segmentation")
plt.axis('off')
plt.show()
In [ ]:
pip install scipyIn [ ]:
import os
import matplotlib.pyplot as plt
import cv2
import numpy as np
from skimage.segmentation import active_contour
from scipy.spatial import distance
# Функция для применения адаптивного медианного фильтра
def adaptive_median_filter(image, max_kernel_size=5):
filtered_image = image.copy()
height, width = image.shape
for i in range(height):
for j in range(width):
kernel_size = 3 # Начальный размер ядра
while kernel_size <= max_kernel_size:
# Получаем область с заданным размером ядра
half_size = kernel_size // 2
x_start = max(j - half_size, 0)
x_end = min(j + half_size + 1, width)
y_start = max(i - half_size, 0)
y_end = min(i + half_size + 1, height)
region = image[y_start:y_end, x_start:x_end]
median_value = np.median(region)
# Если медианное значение близко к текущему пикселю, увеличиваем размер ядра
if abs(median_value - image[i, j]) < 10: # Порог можно настроить
break
kernel_size += 2 # Увеличиваем размер ядра, проверяя на большее
filtered_image[i, j] = median_value
return filtered_image
# Функция для объединения пересекающихся контуров
def merge_contours(contours, min_distance=10):
merged_contours = []
while contours:
contour = contours.pop(0)
merged = False
for i, existing_contour in enumerate(merged_contours):
# Проверяем, пересекаются ли контуры (минимальное расстояние между точками)
if any(distance.euclidean(point, existing_point) < min_distance for point in contour for existing_point in existing_contour):
# Если контуры пересекаются, объединяем их
merged_contours[i] = np.vstack((existing_contour, contour))
merged = True
break
if not merged:
merged_contours.append(contour)
return merged_contours
# Загрузка изображения (например, PNG)
image_path = "/content/9.png" # Укажите путь к вашему изображению
input_image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if input_image is None:
raise FileNotFoundError(f"Не удалось загрузить изображение по указанному пути: {image_path}")
# Обрезка верхней трети изображения (три восьмых сверху)
cropped_image = input_image
# Преобразование изображения в формат uint8, если это необходимо
if cropped_image.dtype != np.uint8:
cropped_image = cv2.normalize(cropped_image, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
# Применение адаптивного медианного фильтра
adaptive_filtered = adaptive_median_filter(cropped_image)
# Визуализация результата CLAHE
plt.figure(figsize=(6, 6))
plt.imshow(adaptive_filtered, cmap="gray")
plt.axis("off")
plt.show()
# Инвертирование изображения перед сегментацией
inverted_image = np.invert(adaptive_filtered)
# Применение пороговой сегментации для выделения светлых участков на инвертированном изображении
gray_threshold = np.percentile(inverted_image, 90) # Порог для серых участков, 70-й перцентиль
binary_image = inverted_image > gray_threshold # Выделяем светлые участки
# Визуализация результата пороговой сегментации
plt.figure(figsize=(6, 6))
plt.imshow(binary_image, cmap="gray")
plt.title("Результат пороговой сегментации (светлые участки на инвертированном изображении)")
plt.axis("off")
plt.show()
# Найдем контуры светлых областей на бинаризованном изображении
contours, _ = cv2.findContours(binary_image.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Отсортируем контуры по площади и выберем 2 самых крупных
contours = sorted(contours, key=cv2.contourArea, reverse=True)[:1] # Выбираем только 2 контуры
# Генерация начальных точек для активных контуров
init_points = []
for contour in contours:
# Найдем центры контуров
M = cv2.moments(contour)
if M['m00'] != 0:
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])
init_points.append((cy, cx))
# Инициализация контуров с центрами
init_contours = []
for point in init_points:
y, x = point
s = np.linspace(0, 2 * np.pi, 400)
r = y + 90 * np.sin(s)
c = x + 90 * np.cos(s)
init = np.array([r, c]).T
init_contours.append(init)
# Применение метода активных контуров
fig, ax = plt.subplots()
ax.imshow(inverted_image, cmap="gray") # Выводим контуры на исходном изображении
# Объединяем пересекающиеся контуры
merged_contours = merge_contours(init_contours, min_distance=1)
# Отображаем объединенные контуры
for init in merged_contours:
snake = active_contour(inverted_image, init, alpha=0.05, beta=0.1, gamma=0.001) # Параметры активного контура
snake[:, 0] = np.clip(snake[:, 0], 0, inverted_image.shape[0] - 1) # ограничиваем по оси Y
snake[:, 1] = np.clip(snake[:, 1], 0, inverted_image.shape[1] - 1) # ограничиваем по оси X
# Проверяем, чтобы контуры не были в темных областях
contour_values = inverted_image[tuple(snake.astype(int).T)]
# Если средняя яркость вдоль контура больше порога, рисуем контур
if np.mean(contour_values) >105: # Порог для яркости, можно настроить
ax.plot(snake[:, 1], snake[:, 0], '-r', lw=2)
ax.set_title(f"Объединенные активные контуры: {os.path.basename(image_path)}")
ax.axis("off")
plt.show()
In [ ]:
import os
import pydicom
import matplotlib.pyplot as plt
import cv2
import numpy as np
from skimage.segmentation import active_contour
from scipy.spatial import distance
from skimage.morphology import disk
# Папка с распакованными изображениями
dicom_folder = "images"
# Сбор всех DICOM-файлов в папке
dicom_files = [filename for filename in os.listdir(dicom_folder) if filename.endswith(".dcm")]
# Запрос у пользователя названий файлов для отображения
file_names = input("Введите названия файлов изображений через запятую: ").split(",")
file_names = [name.strip() for name in file_names]
# Поиск указанных файлов в папке
selected_files = []
for filename in file_names:
found_files = [os.path.join(dicom_folder, f) for f in dicom_files if filename in f]
selected_files.extend(found_files)
# Функция для применения адаптивного медианного фильтра
def adaptive_median_filter(image, max_kernel_size=15):
filtered_image = image.copy()
height, width = image.shape
for i in range(height):
for j in range(width):
kernel_size = 3 # Начальный размер ядра
while kernel_size <= max_kernel_size:
# Получаем область с заданным размером ядра
half_size = kernel_size // 2
x_start = max(j - half_size, 0)
x_end = min(j + half_size + 1, width)
y_start = max(i - half_size, 0)
y_end = min(i + half_size + 1, height)
region = image[y_start:y_end, x_start:x_end]
median_value = np.median(region)
# Если медианное значение близко к текущему пикселю, увеличиваем размер ядра
if abs(median_value - image[i, j]) < 10: # Порог можно настроить
break
kernel_size += 2 # Увеличиваем размер ядра, проверяя на большее
filtered_image[i, j] = median_value
return filtered_image
# Функция для объединения пересекающихся контуров
def merge_contours(contours, min_distance=10):
merged_contours = []
while contours:
contour = contours.pop(0)
merged = False
for i, existing_contour in enumerate(merged_contours):
# Проверяем, пересекаются ли контуры (минимальное расстояние между точками)
if any(distance.euclidean(point, existing_point) < min_distance for point in contour for existing_point in existing_contour):
# Если контуры пересекаются, объединяем их
merged_contours[i] = np.vstack((existing_contour, contour))
merged = True
break
if not merged:
merged_contours.append(contour)
return merged_contours
# Обработка каждого выбранного DICOM файла
for dicom_path in selected_files:
if os.path.exists(dicom_path):
dicom_data = pydicom.dcmread(dicom_path)
image = dicom_data.pixel_array
# Обрезка верхней трети изображения (три восьмых сверху)
height, width = image.shape
cropped_image = image[int(height * 3 / 8):, :]
# Преобразование изображения в формат uint8, если это необходимо
if cropped_image.dtype != np.uint8:
cropped_image = cv2.normalize(cropped_image, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
# Применение фильтра для увеличения яркости (CLAHE)
#clahe = cv2.createCLAHE(clipLimit=5.0, tileGridSize=(1, 1))
enhanced_image = cropped_image
# Визуализация результата CLAHE
plt.figure(figsize=(6, 6))
plt.imshow(enhanced_image, cmap="gray")
# plt.title("После CLAHE (выравнивание гистограммы)")
plt.axis("off")
plt.show()
# Применение пороговой сегментации для выделения светлых участков
gray_threshold = np.percentile(enhanced_image, 90) # Порог для серых участков, 75-й перцентиль
binary_image = enhanced_image > gray_threshold # Выделяем светлые участки
# Инвертируем бинарное изображение, чтобы контуры были на светлых областях
# binary_image = np.invert(binary_image)
# Визуализация результата пороговой сегментации
plt.figure(figsize=(6, 6))
plt.imshow(binary_image, cmap="gray")
plt.title("Результат пороговой сегментации (светлые участки)")
plt.axis("off")
plt.show()
# Найдем контуры светлых областей
contours, _ = cv2.findContours(binary_image.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Отсортируем контуры по площади и выберем 3 самых больших
contours = sorted(contours, key=cv2.contourArea, reverse=True)[:2]
# Генерация начальных точек для активных контуров
init_points = []
for contour in contours:
# Найдем центры контуров
M = cv2.moments(contour)
if M['m00'] != 0:
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])
init_points.append((cy, cx))
# Инициализация контуров с центрами
init_contours = []
for point in init_points:
y, x = point
s = np.linspace(0, 2 * np.pi, 400)
r = y + 90 * np.sin(s)
c = x + 90 * np.cos(s)
init = np.array([r, c]).T
init_contours.append(init)
# Применение метода активных контуров
fig, ax = plt.subplots()
ax.imshow(enhanced_image, cmap="gray")
# Объединяем пересекающиеся контуры
merged_contours = merge_contours(init_contours, min_distance=10)
# Отображаем объединенные контуры
for init in merged_contours:
snake = active_contour(enhanced_image, init, alpha=0.1, beta=0.002, gamma=0.001)
snake[:, 0] = np.clip(snake[:, 0], 0, enhanced_image.shape[0] - 1) # ограничиваем по оси Y
snake[:, 1] = np.clip(snake[:, 1], 0, enhanced_image.shape[1] - 1) # ограничиваем по оси X
# Теперь проверяем, чтобы контуры не были в темных областях
contour_values = enhanced_image[tuple(snake.astype(int).T)]
# Если средняя яркость вдоль контура меньше порога, не рисуем контур
if np.mean(contour_values) > 0: # Порог для яркости, можно настроить
ax.plot(snake[:, 1], snake[:, 0], '-r', lw=2)
ax.set_title(f"Объединенные активные контуры: {os.path.basename(dicom_path)}")
ax.axis("off")
plt.show()
In [ ]:
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
# Создаем простое изображение как матрицу интенсивностей
image = np.array([
[10, 10, 20, 20],
[10, 10, 20, 20],
[30, 30, 40, 40],
[30, 30, 40, 40]
])
# Визуализируем изображение и матрицу интенсивностей
fig, ax = plt.subplots(1, 2, figsize=(10, 5))
ax[0].imshow(image, cmap='gray')
ax[0].set_title('Исходное изображение')
ax[0].axis('off')
# Отображаем матрицу интенсивностей на втором графике
for i in range(image.shape[0]):
for j in range(image.shape[1]):
ax[1].text(j, i, str(image[i, j]), ha='center', va='center', color='black')
ax[1].imshow(image, cmap='gray', alpha=0.5)
ax[1].set_title('Матрица интенсивностей')
ax[1].axis('off')
plt.show()
# Создаем граф из изображения
rows, cols = image.shape
graph = nx.grid_2d_graph(rows, cols)
# Добавляем веса ребрам графа на основе разницы интенсивностей
for i in range(rows):
for j in range(cols):
if i < rows - 1:
weight = np.abs(image[i, j] - image[i + 1, j])
graph.add_edge((i, j), (i + 1, j), weight=weight)
if j < cols - 1:
weight = np.abs(image[i, j] - image[i, j + 1])
graph.add_edge((i, j), (i, j + 1), weight=weight)
# Визуализируем граф
pos = {(i, j): (j, -i) for i, j in graph.nodes()}
weights = [graph[u][v]['weight'] for u, v in graph.edges()]
plt.figure(figsize=(8, 8))
nx.draw(graph, pos, with_labels=True, node_size=500, font_size=8, width=weights, edge_color=weights, edge_cmap=plt.cm.Blues)
plt.title('Графовое представление изображения')
plt.show()
# Простая сегментация на основе порога веса
threshold = 15
segments = []
for component in nx.connected_components(graph):
subgraph = graph.subgraph(component)
if all(graph[u][v]['weight'] <= threshold for u, v in subgraph.edges()):
segments.append(component)
# Визуализируем сегменты
segmented_image = np.zeros_like(image)
for idx, segment in enumerate(segments, start=1):
for (i, j) in segment:
segmented_image[i, j] = 255 - (idx * 50)
plt.figure(figsize=(5, 5))
plt.imshow(segmented_image, cmap='gray')
plt.title('Сегментированное изображение')
plt.show()
In [ ]:
pip install pygraph
In [ ]:
import os
import pydicom
import matplotlib.pyplot as plt
import cv2
import numpy as np
import networkx as nx
# Пример графовой сегментации (графовый минимум разреза)
def graph_cut_segmentation(image, threshold=100, max_weight=100):
# Преобразуем изображение в бинарное
ret, binary_image = cv2.threshold(image, threshold, 255, cv2.THRESH_BINARY)
# Получаем размеры изображения
rows, cols = binary_image.shape
# Создаем граф
G = nx.grid_2d_graph(rows, cols)
# Присваиваем веса рёбрам, которые отражают разницу в яркости пикселей
for i in range(rows):
for j in range(cols):
if i < rows - 1: # Вертикальные рёбра
weight = np.abs(int(binary_image[i, j]) - int(binary_image[i + 1, j]))
weight = max(1, min(weight, max_weight)) # Ограничиваем минимальный вес на 1, максимальный на max_weight
G.add_edge((i, j), (i + 1, j), weight=weight)
if j < cols - 1: # Горизонтальные рёбра
weight = np.abs(int(binary_image[i, j]) - int(binary_image[i, j + 1]))
weight = max(1, min(weight, max_weight)) # Ограничиваем минимальный вес на 1, максимальный на max_weight
G.add_edge((i, j), (i, j + 1), weight=weight)
# Определяем источник и сток (например, верхний левый и нижний правый углы)
source = (0, 0)
sink = (rows - 1, cols - 1)
try:
# Выполняем минимальный разрез
cut_value, partition = nx.minimum_cut(G, source, sink)
reachable, non_reachable = partition
# Сегментированное изображение
segmented_image = np.zeros_like(binary_image)
for (i, j) in reachable:
segmented_image[i, j] = 255
for (i, j) in non_reachable:
segmented_image[i, j] = 0
return segmented_image
except nx.NetworkXUnbounded:
print("Ошибка: Найден путь с бесконечной пропускной способностью. Проверьте веса рёбер.")
return None
# Папка с распакованными изображениями
dicom_folder = "images"
# Сбор всех DICOM-файлов в папке
dicom_files = [filename for filename in os.listdir(dicom_folder) if filename.endswith(".dcm")]
# Запрос у пользователя названий файлов для отображения
file_names = input("Введите названия файлов изображений через запятую: ").split(",")
file_names = [name.strip() for name in file_names]
# Поиск указанных файлов в папке
selected_files = []
for filename in file_names:
found_files = [os.path.join(dicom_folder, f) for f in dicom_files if filename in f]
selected_files.extend(found_files)
# Обработка и сегментация изображений
for dicom_path in selected_files:
if os.path.exists(dicom_path):
dicom_data = pydicom.dcmread(dicom_path)
image = dicom_data.pixel_array
# Обрезка верхних 40% изображения (оставляем нижние 60%)
height = image.shape[0]
cropped_image = image[height // 3:, :] # Обрезаем верхнюю 40%
# Проверка размера после обрезки
print(f"Размер обрезанного изображения: {cropped_image.shape}")
# Визуализация обрезанного изображения
plt.imshow(cropped_image, cmap="gray")
plt.title(f"Обрезанное изображение: {os.path.basename(dicom_path)}")
plt.axis("off")
plt.show()
# Преобразование изображения в формат uint8, если это необходимо
if cropped_image.dtype != np.uint8:
cropped_image = cv2.normalize(cropped_image, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
# Применение адаптивного медианного фильтра для сглаживания шума
filtered_image = cv2.fastNlMeansDenoising(cropped_image, None, 10, 7, 21)
# Преобразование фильтрованного изображения обратно в формат uint8
filtered_image = (filtered_image * 255).astype(np.uint8)
# Применение графового метода сегментации
segmented_image = graph_cut_segmentation(filtered_image, threshold=70, max_weight=50)
# Если сегментация прошла успешно, выводим результат
if segmented_image is not None:
plt.imshow(segmented_image, cmap="gray")
plt.title(f"Графовая сегментация (минимальный разрез): {os.path.basename(dicom_path)}")
plt.axis("off")
plt.show()
In [ ]:
!pip install cupy-cuda11x
!pip install scikit-learn
In [ ]:
import cv2
import matplotlib.pyplot as plt
from skimage import segmentation, color
import numpy as np
# Путь к изображению на Google Диске
image_path = '/content/7.png'
# Загружаем изображение с помощью OpenCV
image = cv2.imread(image_path)
# OpenCV загружает изображение в формате BGR, но для отображения используем RGB
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# Отображаем оригинальное изображение
plt.imshow(image_rgb)
plt.axis('off')
plt.title('Original Image')
plt.show()
# Преобразуем изображение в формат для сегментации (float)
image_float = np.float32(image_rgb) / 255.0
# Применяем алгоритм Felzenszwalb-Huttenlocher для сегментации
segments = segmentation.felzenszwalb(image_float, scale=500, sigma=0.05, min_size=50)
# Отображаем результаты сегментации
fig, ax = plt.subplots(1, 2, figsize=(12, 6))
# Оригинальное изображение
ax[0].imshow(image_rgb)
ax[0].set_title('Original Image')
ax[0].axis('off')
# Сегментированное изображение
ax[1].imshow(segments)
ax[1].set_title('Segmented Image (Felzenszwalb-Huttenlocher)')
ax[1].axis('off')
plt.show()
# Применяем цветовую карту для сегментации
segmented_image = color.label2rgb(segments, image_rgb, kind='avg')
# Отображаем цветную сегментацию
plt.imshow(segmented_image)
plt.title('Segmented Image with Colors')
plt.axis('off')
plt.show()
In [ ]:
pip install scikit-learnIn [ ]:
import cv2
import matplotlib.pyplot as plt
from skimage import segmentation, color
import numpy as np
from sklearn.cluster import SpectralClustering
from skimage import img_as_float
from sklearn.neighbors import kneighbors_graph
# Путь к изображению на Google Диске
image_path = '/content/7.png'
# Загружаем изображение с помощью OpenCV
image = cv2.imread(image_path)
# OpenCV загружает изображение в формате BGR, но для отображения используем RGB
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# Отображаем оригинальное изображение
plt.imshow(image_rgb)
plt.axis('off')
plt.title('Original Image')
plt.show()
# Преобразуем изображение в формат для сегментации (float)
image_float = np.float32(image_rgb) / 255.0
# **Метод 1: Felzenszwalb-Huttenlocher**
segments_fz = segmentation.felzenszwalb(image_float, scale=200, sigma=0.05, min_size=150)
# **Метод 2: Graph Cut (Quickshift)**
segments_quickshift = segmentation.quickshift(image_float, kernel_size=3, max_dist=6, ratio=0.9)
# **Метод 3: Spectral Clustering**
# Преобразуем изображение в граф с соседями
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
graph = kneighbors_graph(image_gray.reshape(-1, 1), n_neighbors=10, mode='distance', include_self=False)
graph = 0.5 * (graph + graph.T) # Симметризация графа
# Применяем спектральную кластеризацию
sc = SpectralClustering(n_clusters=5, affinity='precomputed', n_init=10)
segments_spectral = sc.fit_predict(graph.toarray()).reshape(image_gray.shape)
# Отображаем результаты сегментации
fig, ax = plt.subplots(1, 4, figsize=(16, 6))
# Оригинальное изображение
ax[0].imshow(image_rgb)
ax[0].set_title('Original Image')
ax[0].axis('off')
# Felzenszwalb-Huttenlocher
ax[1].imshow(segments_fz)
ax[1].set_title('Felzenszwalb-Huttenlocher')
ax[1].axis('off')
# Graph Cut (Quickshift)
ax[2].imshow(segments_quickshift)
ax[2].set_title('Graph Cut (Quickshift)')
ax[2].axis('off')
# Spectral Clustering
ax[3].imshow(segments_spectral)
ax[3].set_title('Spectral Clustering')
ax[3].axis('off')
plt.tight_layout()
plt.show()
# Применяем цветовую карту для сегментации
segmented_image_fz = color.label2rgb(segments_fz, image_rgb, kind='avg')
segmented_image_quickshift = color.label2rgb(segments_quickshift, image_rgb, kind='avg')
segmented_image_spectral = color.label2rgb(segments_spectral, image_rgb, kind='avg')
# Отображаем цветные сегментации
fig, ax = plt.subplots(1, 3, figsize=(18, 6))
# Felzenszwalb-Huttenlocher
ax[0].imshow(segmented_image_fz)
ax[0].set_title('Segmented Image (Felzenszwalb-Huttenlocher)')
ax[0].axis('off')
# Graph Cut (Quickshift)
ax[1].imshow(segmented_image_quickshift)
ax[1].set_title('Segmented Image (Graph Cut - Quickshift)')
ax[1].axis('off')
# Spectral Clustering
ax[2].imshow(segmented_image_spectral)
ax[2].set_title('Segmented Image (Spectral Clustering)')
ax[2].axis('off')
plt.tight_layout()
plt.show()