1522 lines
59 KiB
Plaintext
1522 lines
59 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "btIcF4lpu_Xx"
|
|
},
|
|
"source": [
|
|
"import requests\n",
|
|
"\n",
|
|
"# Пример запроса к TCIA API\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "j4rCtvc9u_XD"
|
|
},
|
|
"source": [
|
|
"**Шаг 1**. The Cancer Imaging Archive (TCIA) предоставляет доступ к медицинским изображениям через API. Вы можете использовать библиотеку requests для загрузки данных из TCIA:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 6172,
|
|
"status": "ok",
|
|
"timestamp": 1733077549943,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "uR4WCv5yrzNl",
|
|
"outputId": "0a2a3495-5147-4bed-a209-c800c26cda8d"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import requests\n",
|
|
"\n",
|
|
"# Пример запроса к TCIA API\n",
|
|
"url = \"https://services.cancerimagingarchive.net/services/v3/TCIA/query/getSeries?Collection=TCGA-BRCA\"\n",
|
|
"response = requests.get(url)\n",
|
|
"\n",
|
|
"# Проверка ответа\n",
|
|
"if response.status_code == 200:\n",
|
|
" print(\"Данные получены успешно\")\n",
|
|
"else:\n",
|
|
" print(\"Ошибка получения данных\")\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "AlwoAu-ju7SC"
|
|
},
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "LuW1z73XvxYF"
|
|
},
|
|
"source": [
|
|
"**Шаг 2.** Данные приходят в JSON формате.\n",
|
|
"В этом примере запрос отправляется с параметром format=json, чтобы вернуть данные в формате JSON.\n",
|
|
"Преобразование ответа в JSON:\n",
|
|
"response.json() позволяет конвертировать ответ в словарь Python, с которым будем работать дальше.\n",
|
|
"Обработка JSON-ответа:\n",
|
|
"Сначала печатаем весь JSON для ознакомления."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 7356,
|
|
"status": "ok",
|
|
"timestamp": 1733077563733,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "0rA31BsAuGeM",
|
|
"outputId": "fac4ab13-ddbb-41fd-ade9-279df305554a"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import requests\n",
|
|
"import json\n",
|
|
"\n",
|
|
"# Пример запроса к TCIA API, предполагающий JSON формат\n",
|
|
"url = \"https://services.cancerimagingarchive.net/services/v3/TCIA/query/getSeries?Collection=TCGA-BRCA&format=json\"\n",
|
|
"response = requests.get(url)\n",
|
|
"\n",
|
|
"# Проверка ответа\n",
|
|
"if response.status_code == 200:\n",
|
|
" print(\"Данные получены успешно\")\n",
|
|
"\n",
|
|
" # Преобразование ответа в JSON\n",
|
|
" data = response.json()\n",
|
|
" print(json.dumps(data, indent=4)) # Печать данных в формате JSON с отступами\n",
|
|
"\n",
|
|
" # Обработка данных\n",
|
|
" for item in data:\n",
|
|
" series_instance_uid = item.get('SeriesInstanceUID', 'N/A')\n",
|
|
" modality = item.get('Modality', 'N/A')\n",
|
|
" protocol_name = item.get('ProtocolName', 'N/A')\n",
|
|
" body_part_examined = item.get('BodyPartExamined', 'N/A')\n",
|
|
"\n",
|
|
" # Печать извлеченной информации\n",
|
|
" print(f\"SeriesInstanceUID: {series_instance_uid}\")\n",
|
|
" print(f\"Modality: {modality}\")\n",
|
|
" print(f\"ProtocolName: {protocol_name}\")\n",
|
|
" print(f\"BodyPartExamined: {body_part_examined}\")\n",
|
|
" print('-' * 30)\n",
|
|
"else:\n",
|
|
" print(\"Ошибка получения данных\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "G3VSxAgX6RbK"
|
|
},
|
|
"source": [
|
|
"**Шаг3**.**Получение идентификаторов для загрузки изображений**\n",
|
|
"\n",
|
|
"Используя первый запрос к TCIA API, получили метаданные, такие как SeriesInstanceUID для каждой серии изображений.\n",
|
|
"Эти идентификаторы нужны для следующего шага — получения ссылок на сами изображения.\n",
|
|
"Запрос на загрузку изображений с использованием SeriesInstanceUID\n",
|
|
"Чтобы загрузить все изображения в определенной серии, нужно выполнить запрос к TCIA API с использованием SeriesInstanceUID"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 17756,
|
|
"status": "ok",
|
|
"timestamp": 1733077587143,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "AexV0o2gJahr",
|
|
"outputId": "06c3167c-931f-4f15-917e-a5fe6d7463d5"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import os\n",
|
|
"import requests\n",
|
|
"\n",
|
|
"# Пример использования SeriesInstanceUID\n",
|
|
"series_instance_uid = \"1.3.6.1.4.1.14519.5.2.1.6450.4002.265963154110062013582166845425\" # Пример идентификатора\n",
|
|
"\n",
|
|
"# URL для загрузки изображений\n",
|
|
"url = f\"https://services.cancerimagingarchive.net/services/v3/TCIA/query/getImage?SeriesInstanceUID={series_instance_uid}\"\n",
|
|
"response = requests.get(url, stream=True)\n",
|
|
"\n",
|
|
"# Путь для сохранения ZIP-файла\n",
|
|
"output_path = \"/content/images.zip\"\n",
|
|
"\n",
|
|
"# Создание необходимых папок, если их нет\n",
|
|
"folder_path = os.path.dirname(output_path)\n",
|
|
"os.makedirs(folder_path, exist_ok=True)\n",
|
|
"\n",
|
|
"# Проверка ответа и сохранение изображения\n",
|
|
"if response.status_code == 200:\n",
|
|
" print(f\"Сохранение файла в {output_path}\")\n",
|
|
" with open(output_path, \"wb\") as file:\n",
|
|
" for chunk in response.iter_content(chunk_size=128):\n",
|
|
" file.write(chunk)\n",
|
|
" print(f\"Изображения успешно загружены и сохранены как {output_path}\")\n",
|
|
"else:\n",
|
|
" print(\"Ошибка при загрузке изображений\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 380,
|
|
"status": "ok",
|
|
"timestamp": 1733077591492,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "-PwPLc8aKV9h",
|
|
"outputId": "821075b5-c777-451e-e84f-6ea3f69c092a"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import zipfile\n",
|
|
"\n",
|
|
"# Распаковка загруженного ZIP-файла\n",
|
|
"with zipfile.ZipFile(\"images.zip\", 'r') as zip_ref:\n",
|
|
" zip_ref.extractall(\"images\") # Папка для распакованных изображений\n",
|
|
"print(\"Файлы успешно распакованы\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "DVVYma3wM4vf"
|
|
},
|
|
"source": [
|
|
"**Шаг. 4**# Для чтения DICOM файлов используйте pydicom, а для визуализации изображений — matplotlib."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 27607,
|
|
"status": "ok",
|
|
"timestamp": 1733077622368,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "Tw2PTwQrOlLe",
|
|
"outputId": "d21f3b3b-c985-45ad-fdc6-a8c36cd10335"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"!pip install pydicom\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 839
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 13,
|
|
"status": "ok",
|
|
"timestamp": 1732301923418,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "OLMmOFkCM59-",
|
|
"outputId": "f4370e76-ad70-45da-8192-fe2de2232455"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import os\n",
|
|
"import pydicom\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"\n",
|
|
"# Папка с распакованными изображениями\n",
|
|
"dicom_folder = \"images\"\n",
|
|
"\n",
|
|
"# Чтение всех DICOM-файлов в папке и визуализация первого изображения\n",
|
|
"for filename in os.listdir(dicom_folder):\n",
|
|
" if filename.endswith(\".dcm\"):\n",
|
|
" dicom_path = os.path.join(dicom_folder, filename)\n",
|
|
" dicom_data = pydicom.dcmread(dicom_path)\n",
|
|
"\n",
|
|
" # Получение массива пикселей изображения\n",
|
|
" image = dicom_data.pixel_array\n",
|
|
"\n",
|
|
" # Визуализация изображения\n",
|
|
" plt.imshow(image, cmap=\"gray\")\n",
|
|
" plt.title(f\"Пациент ID: {dicom_data.PatientID}\")\n",
|
|
" plt.axis(\"off\")\n",
|
|
" plt.show()\n",
|
|
" break # Визуализируем только первое изображение\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "U-9TfVjKQsFV"
|
|
},
|
|
"source": [
|
|
" библиотеки, как OpenCV, scikit-image, и NumPy предоставляют множество инструментов для фильтрации, повышения контраста и удаления шума."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "rCrnMoLORzQn"
|
|
},
|
|
"source": [
|
|
"**Фильтрация для уменьшения шума**\n",
|
|
"Использование фильтра Гаусса для сглаживания изображения и уменьшения шума"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 429
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 1602,
|
|
"status": "ok",
|
|
"timestamp": 1732302625198,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "xtnFVnjdRtLn",
|
|
"outputId": "b09651c6-b009-4982-fe00-7baeea8f7b19"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import cv2\n",
|
|
"import numpy as np\n",
|
|
"\n",
|
|
"# Применение фильтра Гаусса для уменьшения шума\n",
|
|
"denoised_image = cv2.GaussianBlur(image, (5, 5), 0)\n",
|
|
"\n",
|
|
"# Визуализация результата\n",
|
|
"plt.imshow(denoised_image, cmap=\"gray\")\n",
|
|
"plt.title(\"Изображение после применения фильтра Гаусса (уменьшение шума)\")\n",
|
|
"plt.axis(\"off\")\n",
|
|
"plt.show()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 1000
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 8014,
|
|
"status": "ok",
|
|
"timestamp": 1732303361685,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "iPL6bf_nU02U",
|
|
"outputId": "749deb76-b4bb-4965-f988-25a87c298274"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import os\n",
|
|
"import cv2\n",
|
|
"import numpy as np\n",
|
|
"import pydicom\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"from skimage import exposure\n",
|
|
"\n",
|
|
"# Папка с распакованными изображениями\n",
|
|
"dicom_folder = \"images\"\n",
|
|
"\n",
|
|
"# Чтение первого DICOM-файла в папке\n",
|
|
"dicom_path = os.path.join(dicom_folder, os.listdir(dicom_folder)[0])\n",
|
|
"dicom_data = pydicom.dcmread(dicom_path)\n",
|
|
"\n",
|
|
"# Получение массива пикселей изображения\n",
|
|
"image = dicom_data.pixel_array\n",
|
|
"\n",
|
|
"# Функция для отображения сравнения изображений \"До\" и \"После\"\n",
|
|
"def show_comparison(original, processed, title):\n",
|
|
" plt.figure(figsize=(10, 5))\n",
|
|
" # Оригинальное изображение\n",
|
|
" plt.subplot(1, 2, 1)\n",
|
|
" plt.imshow(original, cmap='gray')\n",
|
|
" plt.title('До обработки')\n",
|
|
" plt.axis('off')\n",
|
|
" # Обработанное изображение\n",
|
|
" plt.subplot(1, 2, 2)\n",
|
|
" plt.imshow(processed, cmap='gray')\n",
|
|
" plt.title(title)\n",
|
|
" plt.axis('off')\n",
|
|
" plt.show()\n",
|
|
"\n",
|
|
"# 1. Применение фильтра Гаусса для уменьшения шума\n",
|
|
"denoised_image = cv2.GaussianBlur(image, (5, 5), 0)\n",
|
|
"show_comparison(image, denoised_image, 'После фильтра Гаусса (уменьшение шума)')\n",
|
|
"\n",
|
|
"# 2. Выравнивание гистограммы для улучшения контраста\n",
|
|
"equalized_image = exposure.equalize_hist(image)\n",
|
|
"show_comparison(image, equalized_image, 'Выравнивание гистограммы (улучшение контраста)')\n",
|
|
"\n",
|
|
"# 3. Адаптивное выравнивание гистограммы (CLAHE)\n",
|
|
"# Преобразование типа данных изображения к uint8\n",
|
|
"image_uint8 = cv2.normalize(image, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)\n",
|
|
"\n",
|
|
"# Применение CLAHE\n",
|
|
"clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))\n",
|
|
"clahe_image = clahe.apply(image_uint8)\n",
|
|
"show_comparison(image, clahe_image, 'Адаптивное выравнивание гистограммы (CLAHE)')\n",
|
|
"\n",
|
|
"# 4. Выделение краев с использованием фильтра Собеля\n",
|
|
"sobelx = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)\n",
|
|
"sobely = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)\n",
|
|
"sobel_image = np.hypot(sobelx, sobely)\n",
|
|
"show_comparison(image, sobel_image, 'Выделение краев (фильтр Собеля)')\n",
|
|
"\n",
|
|
"# 5. Увеличение резкости изображения (Unsharp Masking)\n",
|
|
"blurred_image = cv2.GaussianBlur(image, (9, 9), 10.0)\n",
|
|
"sharpened_image = cv2.addWeighted(image, 1.5, blurred_image, -0.5, 0)\n",
|
|
"show_comparison(image, sharpened_image, 'Увеличение резкости (Unsharp Masking)')\n",
|
|
"\n",
|
|
"# 6. Пороговое преобразование для удаления фона\n",
|
|
"_, threshold_image = cv2.threshold(image, 100, 255, cv2.THRESH_BINARY)\n",
|
|
"show_comparison(image, threshold_image, 'Пороговое преобразование (удаление фона)')\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 3476,
|
|
"status": "ok",
|
|
"timestamp": 1733077641046,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "tpL-XSGBdKhg",
|
|
"outputId": "fe5ae1ba-c850-4520-8e8f-edf4e6ed96f1"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"!pip install scikit-image"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 13600,
|
|
"status": "ok",
|
|
"timestamp": 1733077659472,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "wMIQ8oaTdhm8",
|
|
"outputId": "cd993480-6b9f-436d-efa7-e9b1f029e78b"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"!pip install SimpleITK\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 8678,
|
|
"status": "ok",
|
|
"timestamp": 1733077668145,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "d-nLd0SGd08v",
|
|
"outputId": "15c4bb63-d405-4a0a-a6ae-e91e1c5e5b24"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"!pip install bm3d\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "7GMcFMIQGJd_"
|
|
},
|
|
"source": [
|
|
"Частотные фильтры"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 1000
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 6330,
|
|
"status": "ok",
|
|
"timestamp": 1732797241901,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "sDhJ92f5eow1",
|
|
"outputId": "7fe797a2-778d-486c-834e-5185734ae3f5"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import os\n",
|
|
"import cv2\n",
|
|
"import numpy as np\n",
|
|
"import pydicom\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"from skimage import exposure\n",
|
|
"\n",
|
|
"# Папка с распакованными изображениями\n",
|
|
"dicom_folder = \"images\"\n",
|
|
"\n",
|
|
"# Чтение всех DICOM-файлов в папке и наложение изображений\n",
|
|
"dicom_files = [os.path.join(dicom_folder, f) for f in os.listdir(dicom_folder) if f.endswith('.dcm')]\n",
|
|
"combined_image = None\n",
|
|
"\n",
|
|
"for dicom_path in dicom_files:\n",
|
|
" dicom_data = pydicom.dcmread(dicom_path)\n",
|
|
" image = dicom_data.pixel_array\n",
|
|
"\n",
|
|
" # Преобразование изображения в формат uint8\n",
|
|
" image_uint8 = cv2.normalize(image, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)\n",
|
|
"\n",
|
|
" if combined_image is None:\n",
|
|
" combined_image = image_uint8\n",
|
|
" else:\n",
|
|
" combined_image = cv2.addWeighted(combined_image, 0.5, image_uint8, 0.5, 0)\n",
|
|
"\n",
|
|
"# Функция для отображения изображения\n",
|
|
"def show_image(image, title):\n",
|
|
" plt.figure(figsize=(6, 6))\n",
|
|
" plt.imshow(image, cmap='gray')\n",
|
|
" plt.title(title)\n",
|
|
" plt.axis('off')\n",
|
|
" plt.show()\n",
|
|
"\n",
|
|
"# Гауссовский НЧ фильтр (Low Pass Filter)\n",
|
|
"gaussian_low_pass = cv2.GaussianBlur(combined_image, (15, 15), 0)\n",
|
|
"\n",
|
|
"# Гауссовский ВЧ фильтр (High Pass Filter)\n",
|
|
"gaussian_blurred = cv2.GaussianBlur(combined_image, (15, 15), 0)\n",
|
|
"gaussian_high_pass = cv2.addWeighted(combined_image, 1.5, gaussian_blurred, -0.5, 0)\n",
|
|
"\n",
|
|
"# Идеальный НЧ фильтр в частотной области\n",
|
|
"def ideal_low_pass_filter(image, D0):\n",
|
|
" dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT)\n",
|
|
" dft_shift = np.fft.fftshift(dft)\n",
|
|
"\n",
|
|
" rows, cols = image.shape\n",
|
|
" crow, ccol = rows // 2 , cols // 2\n",
|
|
" mask = np.zeros((rows, cols, 2), np.uint8)\n",
|
|
" for i in range(rows):\n",
|
|
" for j in range(cols):\n",
|
|
" if np.sqrt((i - crow) ** 2 + (j - ccol) ** 2) <= D0:\n",
|
|
" mask[i, j] = 1\n",
|
|
"\n",
|
|
" fshift = dft_shift * mask\n",
|
|
" f_ishift = np.fft.ifftshift(fshift)\n",
|
|
" img_back = cv2.idft(f_ishift)\n",
|
|
" img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])\n",
|
|
" return np.uint8(cv2.normalize(img_back, None, 0, 255, cv2.NORM_MINMAX))\n",
|
|
"\n",
|
|
"ideal_low_pass = ideal_low_pass_filter(combined_image, 30)\n",
|
|
"\n",
|
|
"# Идеальный ВЧ фильтр в частотной области\n",
|
|
"def ideal_high_pass_filter(image, D0):\n",
|
|
" dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT)\n",
|
|
" dft_shift = np.fft.fftshift(dft)\n",
|
|
"\n",
|
|
" rows, cols = image.shape\n",
|
|
" crow, ccol = rows // 2 , cols // 2\n",
|
|
" mask = np.ones((rows, cols, 2), np.uint8)\n",
|
|
" for i in range(rows):\n",
|
|
" for j in range(cols):\n",
|
|
" if np.sqrt((i - crow) ** 2 + (j - ccol) ** 2) <= D0:\n",
|
|
" mask[i, j] = 0\n",
|
|
"\n",
|
|
" fshift = dft_shift * mask\n",
|
|
" f_ishift = np.fft.ifftshift(fshift)\n",
|
|
" img_back = cv2.idft(f_ishift)\n",
|
|
" img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])\n",
|
|
" return np.uint8(cv2.normalize(img_back, None, 0, 255, cv2.NORM_MINMAX))\n",
|
|
"\n",
|
|
"ideal_high_pass = ideal_high_pass_filter(combined_image, 30)\n",
|
|
"\n",
|
|
"# НЧ фильтр Баттерворта\n",
|
|
"def butterworth_low_pass_filter(image, D0, n):\n",
|
|
" dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT)\n",
|
|
" dft_shift = np.fft.fftshift(dft)\n",
|
|
"\n",
|
|
" rows, cols = image.shape\n",
|
|
" crow, ccol = rows // 2 , cols // 2\n",
|
|
" mask = np.zeros((rows, cols, 2), np.float32)\n",
|
|
" for i in range(rows):\n",
|
|
" for j in range(cols):\n",
|
|
" D = np.sqrt((i - crow) ** 2 + (j - ccol) ** 2)\n",
|
|
" mask[i, j] = 1 / (1 + (D / D0) ** (2 * n))\n",
|
|
"\n",
|
|
" fshift = dft_shift * mask\n",
|
|
" f_ishift = np.fft.ifftshift(fshift)\n",
|
|
" img_back = cv2.idft(f_ishift)\n",
|
|
" img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])\n",
|
|
" return np.uint8(cv2.normalize(img_back, None, 0, 255, cv2.NORM_MINMAX))\n",
|
|
"\n",
|
|
"butterworth_low_pass = butterworth_low_pass_filter(combined_image, 30, 2)\n",
|
|
"\n",
|
|
"# ВЧ фильтр Баттерворта\n",
|
|
"def butterworth_high_pass_filter(image, D0, n):\n",
|
|
" dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT)\n",
|
|
" dft_shift = np.fft.fftshift(dft)\n",
|
|
"\n",
|
|
" rows, cols = image.shape\n",
|
|
" crow, ccol = rows // 2 , cols // 2\n",
|
|
" mask = np.ones((rows, cols, 2), np.float32)\n",
|
|
" for i in range(rows):\n",
|
|
" for j in range(cols):\n",
|
|
" D = np.sqrt((i - crow) ** 2 + (j - ccol) ** 2)\n",
|
|
" mask[i, j] = 1 / (1 + (D0 / D) ** (2 * n))\n",
|
|
"\n",
|
|
" fshift = dft_shift * mask\n",
|
|
" f_ishift = np.fft.ifftshift(fshift)\n",
|
|
" img_back = cv2.idft(f_ishift)\n",
|
|
" img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])\n",
|
|
" return np.uint8(cv2.normalize(img_back, None, 0, 255, cv2.NORM_MINMAX))\n",
|
|
"\n",
|
|
"butterworth_high_pass = butterworth_high_pass_filter(combined_image, 30, 2)\n",
|
|
"\n",
|
|
"# Отображение всех изображений\n",
|
|
"show_image(combined_image, 'Исходное изображение')\n",
|
|
"show_image(gaussian_low_pass, 'Гауссовский НЧ фильтр')\n",
|
|
"show_image(gaussian_high_pass, 'Гауссовский ВЧ фильтр')\n",
|
|
"show_image(ideal_low_pass, 'Идеальный НЧ фильтр')\n",
|
|
"show_image(ideal_high_pass, 'Идеальный ВЧ фильтр')\n",
|
|
"show_image(butterworth_low_pass, 'НЧ фильтр Баттерворта')\n",
|
|
"show_image(butterworth_high_pass, 'ВЧ фильтр Баттерворта')\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 1000
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 7867,
|
|
"status": "ok",
|
|
"timestamp": 1732974353790,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "TUaa8cviKcC7",
|
|
"outputId": "5e755024-a392-4d61-88a6-6efbcb852901"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import os\n",
|
|
"import cv2\n",
|
|
"import numpy as np\n",
|
|
"import pydicom\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"from skimage import exposure\n",
|
|
"\n",
|
|
"# Папка с распакованными изображениями\n",
|
|
"dicom_folder = \"images\"\n",
|
|
"\n",
|
|
"# Чтение всех DICOM-файлов в папке и наложение изображений\n",
|
|
"dicom_files = [os.path.join(dicom_folder, f) for f in os.listdir(dicom_folder) if f.endswith('.dcm')]\n",
|
|
"combined_image = None\n",
|
|
"\n",
|
|
"for dicom_path in dicom_files:\n",
|
|
" dicom_data = pydicom.dcmread(dicom_path)\n",
|
|
" image = dicom_data.pixel_array\n",
|
|
"\n",
|
|
" # Преобразование изображения в формат uint8\n",
|
|
" image_uint8 = cv2.normalize(image, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)\n",
|
|
"\n",
|
|
" if combined_image is None:\n",
|
|
" combined_image = image_uint8\n",
|
|
" else:\n",
|
|
" combined_image = cv2.addWeighted(combined_image, 0.5, image_uint8, 0.5, 0)\n",
|
|
"\n",
|
|
"# Функция для отображения изображения\n",
|
|
"def show_image(image, title):\n",
|
|
" plt.figure(figsize=(6, 6))\n",
|
|
" plt.imshow(image, cmap='gray')\n",
|
|
" plt.title(title)\n",
|
|
" plt.axis('off')\n",
|
|
" plt.show()\n",
|
|
"\n",
|
|
"# Гауссовский НЧ фильтр (Low Pass Filter)\n",
|
|
"gaussian_low_pass = cv2.GaussianBlur(combined_image, (15, 15), 0)\n",
|
|
"\n",
|
|
"# Гауссовский ВЧ фильтр (High Pass Filter)\n",
|
|
"gaussian_blurred = cv2.GaussianBlur(combined_image, (15, 15), 0)\n",
|
|
"gaussian_high_pass = cv2.addWeighted(combined_image, 1.5, gaussian_blurred, -0.5, 0)\n",
|
|
"\n",
|
|
"# Идеальный НЧ фильтр в частотной области\n",
|
|
"def ideal_low_pass_filter(image, D0):\n",
|
|
" dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT)\n",
|
|
" dft_shift = np.fft.fftshift(dft)\n",
|
|
"\n",
|
|
" rows, cols = image.shape\n",
|
|
" crow, ccol = rows // 2 , cols // 2\n",
|
|
" mask = np.zeros((rows, cols, 2), np.uint8)\n",
|
|
" for i in range(rows):\n",
|
|
" for j in range(cols):\n",
|
|
" if np.sqrt((i - crow) ** 2 + (j - ccol) ** 2) <= D0:\n",
|
|
" mask[i, j] = 1\n",
|
|
"\n",
|
|
" fshift = dft_shift * mask\n",
|
|
" f_ishift = np.fft.ifftshift(fshift)\n",
|
|
" img_back = cv2.idft(f_ishift)\n",
|
|
" img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])\n",
|
|
" return np.uint8(cv2.normalize(img_back, None, 0, 255, cv2.NORM_MINMAX))\n",
|
|
"\n",
|
|
"ideal_low_pass = ideal_low_pass_filter(combined_image, 30)\n",
|
|
"\n",
|
|
"# Идеальный ВЧ фильтр в частотной области\n",
|
|
"def ideal_high_pass_filter(image, D0):\n",
|
|
" dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT)\n",
|
|
" dft_shift = np.fft.fftshift(dft)\n",
|
|
"\n",
|
|
" rows, cols = image.shape\n",
|
|
" crow, ccol = rows // 2 , cols // 2\n",
|
|
" mask = np.ones((rows, cols, 2), np.uint8)\n",
|
|
" for i in range(rows):\n",
|
|
" for j in range(cols):\n",
|
|
" if np.sqrt((i - crow) ** 2 + (j - ccol) ** 2) <= D0:\n",
|
|
" mask[i, j] = 0\n",
|
|
"\n",
|
|
" fshift = dft_shift * mask\n",
|
|
" f_ishift = np.fft.ifftshift(fshift)\n",
|
|
" img_back = cv2.idft(f_ishift)\n",
|
|
" img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])\n",
|
|
" return np.uint8(cv2.normalize(img_back, None, 0, 255, cv2.NORM_MINMAX))\n",
|
|
"\n",
|
|
"ideal_high_pass = ideal_high_pass_filter(combined_image, 30)\n",
|
|
"\n",
|
|
"# НЧ фильтр Баттерворта\n",
|
|
"def butterworth_low_pass_filter(image, D0, n):\n",
|
|
" dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT)\n",
|
|
" dft_shift = np.fft.fftshift(dft)\n",
|
|
"\n",
|
|
" rows, cols = image.shape\n",
|
|
" crow, ccol = rows // 2 , cols // 2\n",
|
|
" mask = np.zeros((rows, cols, 2), np.float32)\n",
|
|
" for i in range(rows):\n",
|
|
" for j in range(cols):\n",
|
|
" D = np.sqrt((i - crow) ** 2 + (j - ccol) ** 2)\n",
|
|
" mask[i, j] = 1 / (1 + (D / D0) ** (2 * n))\n",
|
|
"\n",
|
|
" fshift = dft_shift * mask\n",
|
|
" f_ishift = np.fft.ifftshift(fshift)\n",
|
|
" img_back = cv2.idft(f_ishift)\n",
|
|
" img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])\n",
|
|
" return np.uint8(cv2.normalize(img_back, None, 0, 255, cv2.NORM_MINMAX))\n",
|
|
"\n",
|
|
"butterworth_low_pass = butterworth_low_pass_filter(combined_image, 30, 2)\n",
|
|
"\n",
|
|
"# ВЧ фильтр Баттерворта\n",
|
|
"def butterworth_high_pass_filter(image, D0, n):\n",
|
|
" dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT)\n",
|
|
" dft_shift = np.fft.fftshift(dft)\n",
|
|
"\n",
|
|
" rows, cols = image.shape\n",
|
|
" crow, ccol = rows // 2 , cols // 2\n",
|
|
" mask = np.ones((rows, cols, 2), np.float32)\n",
|
|
" for i in range(rows):\n",
|
|
" for j in range(cols):\n",
|
|
" D = np.sqrt((i - crow) ** 2 + (j - ccol) ** 2)\n",
|
|
" mask[i, j] = 1 / (1 + (D0 / D) ** (2 * n))\n",
|
|
"\n",
|
|
" fshift = dft_shift * mask\n",
|
|
" f_ishift = np.fft.ifftshift(fshift)\n",
|
|
" img_back = cv2.idft(f_ishift)\n",
|
|
" img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])\n",
|
|
" return np.uint8(cv2.normalize(img_back, None, 0, 255, cv2.NORM_MINMAX))\n",
|
|
"\n",
|
|
"butterworth_high_pass = butterworth_high_pass_filter(combined_image, 30, 2)\n",
|
|
"\n",
|
|
"# Билатеральный фильтр (Bilateral Filter)\n",
|
|
"bilateral_filtered = cv2.bilateralFilter(combined_image, d=15, sigmaColor=7, sigmaSpace=7)\n",
|
|
"\n",
|
|
"# Отображение всех изображений\n",
|
|
"show_image(combined_image, 'Исходное изображение')\n",
|
|
"show_image(gaussian_low_pass, 'Гауссовский НЧ фильтр')\n",
|
|
"show_image(gaussian_high_pass, 'Гауссовский ВЧ фильтр')\n",
|
|
"show_image(ideal_low_pass, 'Идеальный НЧ фильтр')\n",
|
|
"show_image(ideal_high_pass, 'Идеальный ВЧ фильтр')\n",
|
|
"show_image(butterworth_low_pass, 'НЧ фильтр Баттерворта')\n",
|
|
"show_image(butterworth_high_pass, 'ВЧ фильтр Баттерворта')\n",
|
|
"show_image(bilateral_filtered, 'Билатеральный фильтр')\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "_zwhKwJVL7gT"
|
|
},
|
|
"source": [
|
|
"С использованием изображения с компьютера"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 1000,
|
|
"output_embedded_package_id": "1owFR5aZk0s6YEDFr_aMh3c1WryCNolwa"
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 25693,
|
|
"status": "ok",
|
|
"timestamp": 1732877156436,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "1pelwlcrU3Kh",
|
|
"outputId": "a840dd2b-8380-4c13-b44c-6ee1f5e3e5c8"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import os\n",
|
|
"import cv2\n",
|
|
"import numpy as np\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"from skimage import exposure\n",
|
|
"\n",
|
|
"# Загрузка изображения с компьютера\n",
|
|
"image_path = \"/content/3.jpg\" # Укажите путь к вашему изображению\n",
|
|
"combined_image = cv2.imread(image_path) # Загрузка цветного изображения\n",
|
|
"\n",
|
|
"# Проверка успешной загрузки изображения\n",
|
|
"if combined_image is None:\n",
|
|
" raise FileNotFoundError(f\"Не удалось загрузить изображение по указанному пути: {image_path}\")\n",
|
|
"\n",
|
|
"# Функция для отображения изображения\n",
|
|
"def show_image(image, title):\n",
|
|
" plt.figure(figsize=(6, 6))\n",
|
|
" plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))\n",
|
|
" plt.title(title)\n",
|
|
" plt.axis('off')\n",
|
|
" plt.show()\n",
|
|
"\n",
|
|
"# Вывод загруженного изображения\n",
|
|
"show_image(combined_image, 'Загруженное цветное изображение')\n",
|
|
"\n",
|
|
"# Гауссовский НЧ фильтр (Low Pass Filter)\n",
|
|
"gaussian_low_pass = cv2.GaussianBlur(combined_image, (15, 15), 0)\n",
|
|
"\n",
|
|
"# Гауссовский ВЧ фильтр (High Pass Filter)\n",
|
|
"gaussian_blurred = cv2.GaussianBlur(combined_image, (15, 15), 0)\n",
|
|
"gaussian_high_pass = cv2.addWeighted(combined_image, 1.5, gaussian_blurred, -0.5, 0)\n",
|
|
"\n",
|
|
"# Применение DFT к трехканальному изображению (каждому каналу отдельно)\n",
|
|
"def dft_three_channels(image, D0, filter_type='low'):\n",
|
|
" # Разделение цветного изображения на три канала (B, G, R)\n",
|
|
" channels = cv2.split(image)\n",
|
|
" filtered_channels = []\n",
|
|
"\n",
|
|
" for channel in channels:\n",
|
|
" # Преобразование Фурье каждого канала\n",
|
|
" dft = cv2.dft(np.float32(channel), flags=cv2.DFT_COMPLEX_OUTPUT)\n",
|
|
" dft_shift = np.fft.fftshift(dft)\n",
|
|
"\n",
|
|
" # Создание маски для фильтрации (идеальный НЧ или ВЧ фильтр)\n",
|
|
" rows, cols = channel.shape\n",
|
|
" crow, ccol = rows // 2, cols // 2\n",
|
|
" mask = np.zeros((rows, cols, 2), np.uint8)\n",
|
|
"\n",
|
|
" for i in range(rows):\n",
|
|
" for j in range(cols):\n",
|
|
" distance = np.sqrt((i - crow) ** 2 + (j - ccol) ** 2)\n",
|
|
" if filter_type == 'low':\n",
|
|
" mask[i, j] = 1 if distance <= D0 else 0\n",
|
|
" elif filter_type == 'high':\n",
|
|
" mask[i, j] = 0 if distance <= D0 else 1\n",
|
|
"\n",
|
|
" # Применение фильтра в частотной области\n",
|
|
" fshift = dft_shift * mask\n",
|
|
" f_ishift = np.fft.ifftshift(fshift)\n",
|
|
" img_back = cv2.idft(f_ishift)\n",
|
|
" img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])\n",
|
|
"\n",
|
|
" # Нормализация изображения и добавление в список\n",
|
|
" filtered_channels.append(np.uint8(cv2.normalize(img_back, None, 0, 255, cv2.NORM_MINMAX)))\n",
|
|
"\n",
|
|
" # Объединение каналов обратно в цветное изображение\n",
|
|
" filtered_image = cv2.merge(filtered_channels)\n",
|
|
" return filtered_image\n",
|
|
"\n",
|
|
"# Применение фильтров к трехканальному изображению\n",
|
|
"ideal_low_pass_color = dft_three_channels(combined_image, 30, filter_type='low')\n",
|
|
"ideal_high_pass_color = dft_three_channels(combined_image, 30, filter_type='high')\n",
|
|
"\n",
|
|
"# НЧ фильтр Баттерворта для цветного изображения\n",
|
|
"def butterworth_filter_three_channels(image, D0, n, filter_type='low'):\n",
|
|
" channels = cv2.split(image)\n",
|
|
" filtered_channels = []\n",
|
|
"\n",
|
|
" for channel in channels:\n",
|
|
" dft = cv2.dft(np.float32(channel), flags=cv2.DFT_COMPLEX_OUTPUT)\n",
|
|
" dft_shift = np.fft.fftshift(dft)\n",
|
|
"\n",
|
|
" rows, cols = channel.shape\n",
|
|
" crow, ccol = rows // 2, cols // 2\n",
|
|
" mask = np.zeros((rows, cols, 2), np.float32)\n",
|
|
"\n",
|
|
" for i in range(rows):\n",
|
|
" for j in range(cols):\n",
|
|
" D = np.sqrt((i - crow) ** 2 + (j - ccol) ** 2)\n",
|
|
" if filter_type == 'low':\n",
|
|
" mask[i, j] = 1 / (1 + (D / D0) ** (2 * n))\n",
|
|
" elif filter_type == 'high':\n",
|
|
" mask[i, j] = 1 / (1 + (D0 / D) ** (2 * n))\n",
|
|
"\n",
|
|
" fshift = dft_shift * mask\n",
|
|
" f_ishift = np.fft.ifftshift(fshift)\n",
|
|
" img_back = cv2.idft(f_ishift)\n",
|
|
" img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])\n",
|
|
"\n",
|
|
" filtered_channels.append(np.uint8(cv2.normalize(img_back, None, 0, 255, cv2.NORM_MINMAX)))\n",
|
|
"\n",
|
|
" filtered_image = cv2.merge(filtered_channels)\n",
|
|
" return filtered_image\n",
|
|
"\n",
|
|
"# Применение фильтров Баттерворта к трехканальному изображению\n",
|
|
"butterworth_low_pass_color = butterworth_filter_three_channels(combined_image, 30, 2, filter_type='low')\n",
|
|
"butterworth_high_pass_color = butterworth_filter_three_channels(combined_image, 30, 2, filter_type='high')\n",
|
|
"\n",
|
|
"# Билатеральный фильтр (Bilateral Filter)\n",
|
|
"bilateral_filtered = cv2.bilateralFilter(combined_image, d=9, sigmaColor=100, sigmaSpace=100)\n",
|
|
"\n",
|
|
"# Отображение всех изображений\n",
|
|
"show_image(combined_image, 'Исходное изображение')\n",
|
|
"show_image(gaussian_low_pass, 'Гауссовский НЧ фильтр')\n",
|
|
"show_image(gaussian_high_pass, 'Гауссовский ВЧ фильтр')\n",
|
|
"show_image(ideal_low_pass_color, 'Идеальный НЧ фильтр для цветного изображения')\n",
|
|
"show_image(ideal_high_pass_color, 'Идеальный ВЧ фильтр для цветного изображения')\n",
|
|
"show_image(butterworth_low_pass_color, 'НЧ фильтр Баттерворта для цветного изображения')\n",
|
|
"show_image(butterworth_high_pass_color, 'ВЧ фильтр Баттерворта для цветного изображения')\n",
|
|
"show_image(bilateral_filtered, 'Билатеральный фильтр')\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 1000,
|
|
"output_embedded_package_id": "1uvbcPc5Mg3W5hnDhdi9U0B3JKTxiY1Ny"
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 8791,
|
|
"status": "ok",
|
|
"timestamp": 1732877745096,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "zrzUTEYMj4Od",
|
|
"outputId": "42281a9c-4adb-4f47-8bd2-74d360a6a00c"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import os\n",
|
|
"import cv2\n",
|
|
"import numpy as np\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"from skimage import exposure\n",
|
|
"\n",
|
|
"# Загрузка изображения с компьютера\n",
|
|
"image_path = \"/content/3.jpg\" # Укажите путь к вашему изображению\n",
|
|
"combined_image = cv2.imread(image_path) # Загрузка цветного изображения\n",
|
|
"\n",
|
|
"# Добавление шума на исходное изображение (цветные точки)\n",
|
|
"def add_salt_and_pepper_noise(image, amount=0.02):\n",
|
|
" noisy_image = image.copy()\n",
|
|
" num_salt = np.ceil(amount * image.size * 0.5)\n",
|
|
" coords = [np.random.randint(0, i - 1, int(num_salt)) for i in image.shape]\n",
|
|
" noisy_image[coords[0], coords[1], :] = [255, 255, 255] # Белые точки (\"соль\")\n",
|
|
"\n",
|
|
" num_pepper = np.ceil(amount * image.size * 0.5)\n",
|
|
" coords = [np.random.randint(0, i - 1, int(num_pepper)) for i in image.shape]\n",
|
|
" noisy_image[coords[0], coords[1], :] = [0, 0, 0] # Черные точки (\"перец\")\n",
|
|
"\n",
|
|
" return noisy_image\n",
|
|
"\n",
|
|
"combined_image = add_salt_and_pepper_noise(combined_image)\n",
|
|
"\n",
|
|
"# Проверка успешной загрузки изображения\n",
|
|
"if combined_image is None:\n",
|
|
" raise FileNotFoundError(f\"Не удалось загрузить изображение по указанному пути: {image_path}\")\n",
|
|
"\n",
|
|
"# Функция для отображения изображения\n",
|
|
"def show_image(image, title):\n",
|
|
" plt.figure(figsize=(6, 6))\n",
|
|
" plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))\n",
|
|
" plt.title(title)\n",
|
|
" plt.axis('off')\n",
|
|
" plt.show()\n",
|
|
"\n",
|
|
"# Вывод изображения с добавленным шумом\n",
|
|
"show_image(combined_image, 'Загруженное цветное изображение')\n",
|
|
"\n",
|
|
"# Гауссовский НЧ фильтр (Low Pass Filter)\n",
|
|
"gaussian_low_pass = cv2.GaussianBlur(combined_image, (15, 15), 0)\n",
|
|
"\n",
|
|
"# Медианный фильтр для удаления шума \"соль и перец\"\n",
|
|
"median_filtered = cv2.medianBlur(combined_image, 5)\n",
|
|
"\n",
|
|
"# Билатеральный фильтр (Bilateral Filter)\n",
|
|
"bilateral_filtered = cv2.bilateralFilter(median_filtered, d=9, sigmaColor=100, sigmaSpace=100)\n",
|
|
"\n",
|
|
"# Отображение всех изображений\n",
|
|
"show_image(median_filtered, 'Медианный фильтр')\n",
|
|
"show_image(combined_image, 'Исходное изображение')\n",
|
|
"show_image(gaussian_low_pass, 'Гауссовский НЧ фильтр')\n",
|
|
"show_image(bilateral_filtered, 'Билатеральный фильтр')\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "0osd9hgPwgHw"
|
|
},
|
|
"source": [
|
|
"LIME"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 1000,
|
|
"output_embedded_package_id": "1YI5PIcRyu6wjNI3yjocXgx-ZtjEr1hlF"
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 6877,
|
|
"status": "ok",
|
|
"timestamp": 1732973578497,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "qQeyiTfCRVQS",
|
|
"outputId": "178f3f89-9e4e-44fa-98d3-6410271222a5"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import cv2\n",
|
|
"import numpy as np\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"from skimage import restoration\n",
|
|
"\n",
|
|
"# Загрузка изображения\n",
|
|
"image_path = \"/content/3.jpg\" # Укажите путь к вашему изображению\n",
|
|
"input_image = cv2.imread(image_path)\n",
|
|
"if input_image is None:\n",
|
|
" raise FileNotFoundError(f\"Не удалось загрузить изображение по указанному пути: {image_path}\")\n",
|
|
"\n",
|
|
"# Функция для отображения изображения\n",
|
|
"def show_image(image, title):\n",
|
|
" plt.figure(figsize=(10, 10))\n",
|
|
" plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))\n",
|
|
" plt.title(title)\n",
|
|
" plt.axis('off')\n",
|
|
" plt.show()\n",
|
|
"\n",
|
|
"# Функция для оценки карты освещенности\n",
|
|
"def estimate_illumination_map(image, kernel_size=15):\n",
|
|
" epsilon = 1e-11 # Определение epsilon для использования в функции\n",
|
|
" illumination_map = np.max(image, axis=2)\n",
|
|
" illumination_map = cv2.GaussianBlur(illumination_map, (kernel_size, kernel_size), 0)\n",
|
|
"\n",
|
|
" return illumination_map\n",
|
|
"\n",
|
|
"# Функция для применения LIME улучшения\n",
|
|
"def lime_enhancement(image, alpha=1, epsilon=1e-11):\n",
|
|
" illumination_map = cv2.normalize(estimate_illumination_map(image).astype(np.float32), None, alpha=0.0, beta=255.0, norm_type=cv2.NORM_MINMAX)\n",
|
|
" illumination_map = illumination_map[:, :, np.newaxis] # Добавление размерности для каналов\n",
|
|
" enhanced_image = np.clip((image.astype(np.float32) / (illumination_map / 255.0)) * alpha, 0, 255)\n",
|
|
" enhanced_image = enhanced_image.astype(np.uint8)\n",
|
|
" return enhanced_image\n",
|
|
"\n",
|
|
"# Применение LIME улучшения\n",
|
|
"lime_result = lime_enhancement(input_image, alpha=1)\n",
|
|
"\n",
|
|
"# Отображение исходного и обработанного изображений\n",
|
|
"show_image(input_image, 'Input Image')\n",
|
|
"show_image(lime_result, 'LIME Enhanced Image')\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "qk3M1b9FRmnM"
|
|
},
|
|
"source": [
|
|
"Преобразование Фурье"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 342
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 4699,
|
|
"status": "ok",
|
|
"timestamp": 1732973654601,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "FBCiNQELRuRK",
|
|
"outputId": "4baa1b06-90e6-42da-d8b2-2dd51f561c39"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import numpy as np\n",
|
|
"import cv2\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"\n",
|
|
"# Функции для фильтрации изображений\n",
|
|
"def gaussian_low_pass_filter(image, D0):\n",
|
|
" rows, cols = image.shape\n",
|
|
" crow, ccol = rows // 2, cols // 2\n",
|
|
"\n",
|
|
" # Перевод изображения в частотную область\n",
|
|
" dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT)\n",
|
|
" dft_shift = np.fft.fftshift(dft)\n",
|
|
"\n",
|
|
" # Создание маски Гауссовского фильтра\n",
|
|
" mask = np.zeros((rows, cols, 2), np.float32)\n",
|
|
" for i in range(rows):\n",
|
|
" for j in range(cols):\n",
|
|
" D = np.sqrt((i - crow)**2 + (j - ccol)**2)\n",
|
|
" mask[i, j] = np.exp(-D**2 / (2 * D0**2))\n",
|
|
"\n",
|
|
" # Применение маски\n",
|
|
" fshift = dft_shift * mask\n",
|
|
" f_ishift = np.fft.ifftshift(fshift)\n",
|
|
" img_back = cv2.idft(f_ishift)\n",
|
|
" img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])\n",
|
|
"\n",
|
|
" return img_back\n",
|
|
"\n",
|
|
"def gaussian_high_pass_filter(image, D0):\n",
|
|
" rows, cols = image.shape\n",
|
|
" crow, ccol = rows // 2, cols // 2\n",
|
|
"\n",
|
|
" # Перевод изображения в частотную область\n",
|
|
" dft = cv2.dft(np.float32(image), flags=cv2.DFT_COMPLEX_OUTPUT)\n",
|
|
" dft_shift = np.fft.fftshift(dft)\n",
|
|
"\n",
|
|
" # Создание маски Гауссовского фильтра\n",
|
|
" mask = np.ones((rows, cols, 2), np.float32)\n",
|
|
" for i in range(rows):\n",
|
|
" for j in range(cols):\n",
|
|
" D = np.sqrt((i - crow)**2 + (j - ccol)**2)\n",
|
|
" mask[i, j] = 1 - np.exp(-D**2 / (2 * D0**2))\n",
|
|
"\n",
|
|
" # Применение маски\n",
|
|
" fshift = dft_shift * mask\n",
|
|
" f_ishift = np.fft.ifftshift(fshift)\n",
|
|
" img_back = cv2.idft(f_ishift)\n",
|
|
" img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])\n",
|
|
"\n",
|
|
" return img_back\n",
|
|
"\n",
|
|
"# Загрузка изображения\n",
|
|
"def load_image(image_path):\n",
|
|
" image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)\n",
|
|
" if image is None:\n",
|
|
" raise FileNotFoundError(f\"Не удалось загрузить изображение по указанному пути: {image_path}\")\n",
|
|
" return image\n",
|
|
"\n",
|
|
"# Отображение исходного и фильтрованных изображений\n",
|
|
"def show_images(original, low_pass, high_pass):\n",
|
|
" plt.figure(figsize=(18, 6))\n",
|
|
" titles = ['Original Image', 'Low Pass Filtered Image', 'High Pass Filtered Image']\n",
|
|
" images = [original, low_pass, high_pass]\n",
|
|
"\n",
|
|
" for i in range(3):\n",
|
|
" plt.subplot(1, 3, i + 1)\n",
|
|
" plt.imshow(images[i], cmap='gray')\n",
|
|
" plt.title(titles[i])\n",
|
|
" plt.axis('off')\n",
|
|
" plt.show()\n",
|
|
"\n",
|
|
"# Основной код\n",
|
|
"image_path = \"/content/3.jpg\" # Укажите путь к вашему изображению\n",
|
|
"input_image = cv2.imread(image_path)\n",
|
|
"if input_image is None:\n",
|
|
" raise FileNotFoundError(f\"Не удалось загрузить изображение по указанному пути: {image_path}\")\n",
|
|
"\n",
|
|
"# Преобразование изображения в градации серого\n",
|
|
"input_image = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)\n",
|
|
"\n",
|
|
"# Применение фильтров\n",
|
|
"low_pass_result = gaussian_low_pass_filter(input_image, D0=30)\n",
|
|
"high_pass_result = gaussian_high_pass_filter(input_image, D0=30)\n",
|
|
"\n",
|
|
"# Отображение результатов\n",
|
|
"show_images(input_image, low_pass_result, high_pass_result)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "YAeox9QRbgjt"
|
|
},
|
|
"source": [
|
|
"Медианный и адаптивный медианный фильры"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 342
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 53805,
|
|
"status": "ok",
|
|
"timestamp": 1732976525949,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "SjZXNds2boW9",
|
|
"outputId": "579e3438-1517-4a88-86a0-0988ab336fdf"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import numpy as np\n",
|
|
"import cv2\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"\n",
|
|
"# Загрузка изображения\n",
|
|
"image_path = \"/content/3.jpg\" # Укажите путь к вашему изображению\n",
|
|
"input_image = cv2.imread(image_path)\n",
|
|
"if input_image is None:\n",
|
|
" raise FileNotFoundError(f\"Не удалось загрузить изображение по указанному пути: {image_path}\")\n",
|
|
"\n",
|
|
"# Добавление шума к изображению\n",
|
|
"noise = np.random.randint(2, 200, input_image.shape, dtype='uint8')\n",
|
|
"noisy_image = cv2.add(input_image, noise)\n",
|
|
"\n",
|
|
"# Функция для отображения изображения\n",
|
|
"def show_image(image, title):\n",
|
|
" plt.figure(figsize=(10, 10))\n",
|
|
" plt.imshow(image, cmap='gray')\n",
|
|
" plt.title(title)\n",
|
|
" plt.axis('off')\n",
|
|
" plt.show()\n",
|
|
"\n",
|
|
"# Функция для применения медианного фильтра\n",
|
|
"def median_filter(image, kernel_size=3):\n",
|
|
" return cv2.medianBlur(image, kernel_size)\n",
|
|
"\n",
|
|
"# Функция для применения адаптивного медианного фильтра\n",
|
|
"def adaptive_median_filter(image, max_kernel_size=7):\n",
|
|
" filtered_image = image.copy()\n",
|
|
" rows, cols, channels = image.shape\n",
|
|
" for i in range(rows):\n",
|
|
" for j in range(cols):\n",
|
|
" k = 3\n",
|
|
" while k <= max_kernel_size:\n",
|
|
" half_k = k // 2\n",
|
|
" # Определение границ окна\n",
|
|
" rmin = max(0, i - half_k)\n",
|
|
" rmax = min(rows, i + half_k + 1)\n",
|
|
" cmin = max(0, j - half_k)\n",
|
|
" cmax = min(cols, j + half_k + 1)\n",
|
|
" # Извлечение окна\n",
|
|
" window = image[rmin:rmax, cmin:cmax, :]\n",
|
|
" # Применение медианного фильтра к окну\n",
|
|
" z_min = np.min(window, axis=(0, 1))\n",
|
|
" z_max = np.max(window, axis=(0, 1))\n",
|
|
" z_med = np.median(window, axis=(0, 1))\n",
|
|
" z_xy = image[i, j, :]\n",
|
|
" if np.all(z_min < z_med) and np.all(z_med < z_max):\n",
|
|
" if np.all(z_min < z_xy) and np.all(z_xy < z_max):\n",
|
|
" filtered_image[i, j, :] = z_xy\n",
|
|
" else:\n",
|
|
" filtered_image[i, j, :] = z_med\n",
|
|
" break\n",
|
|
" else:\n",
|
|
" k += 2\n",
|
|
" if k > max_kernel_size:\n",
|
|
" filtered_image[i, j] = z_med\n",
|
|
" return filtered_image\n",
|
|
"\n",
|
|
"# Применение фильтров\n",
|
|
"median_result = median_filter(noisy_image, kernel_size=5)\n",
|
|
"adaptive_median_result = adaptive_median_filter(noisy_image, max_kernel_size=7)\n",
|
|
"\n",
|
|
"# Отображение исходного и фильтрованных изображений\n",
|
|
"plt.figure(figsize=(18, 6))\n",
|
|
"titles = ['Noisy Image', 'Median Filtered Image', 'Adaptive Median Filtered Image']\n",
|
|
"images = [noisy_image, median_result, adaptive_median_result]\n",
|
|
"\n",
|
|
"for i in range(3):\n",
|
|
" plt.subplot(1, 3, i + 1)\n",
|
|
" plt.imshow(cv2.cvtColor(images[i], cv2.COLOR_BGR2RGB) if len(images[i].shape) == 3 else images[i], cmap='gray')\n",
|
|
" plt.title(titles[i])\n",
|
|
" plt.axis('off')\n",
|
|
"plt.show()\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "-KQytGBmdq0y"
|
|
},
|
|
"source": [
|
|
"Многоуровневая декомпозиция"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/",
|
|
"height": 1000,
|
|
"output_embedded_package_id": "1i9Cm5n7h6VTlYMNGaajM76TMHCqBUzjE"
|
|
},
|
|
"executionInfo": {
|
|
"elapsed": 4169,
|
|
"status": "ok",
|
|
"timestamp": 1732993395080,
|
|
"user": {
|
|
"displayName": "E Shuvalova",
|
|
"userId": "09074408506229732964"
|
|
},
|
|
"user_tz": -180
|
|
},
|
|
"id": "5h6qkfj7XvDS",
|
|
"outputId": "7a26fcd1-4abf-4dd6-a74f-aa9d8905eea9"
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"import cv2\n",
|
|
"import numpy as np\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"from scipy.special import expit\n",
|
|
"\n",
|
|
"# Загрузка изображения\n",
|
|
"image_path = \"/content/5.png\" # Укажите путь к вашему изображению\n",
|
|
"input_image = cv2.imread(image_path)\n",
|
|
"if input_image is None:\n",
|
|
" raise FileNotFoundError(f\"Не удалось загрузить изображение по указанному пути: {image_path}\")\n",
|
|
"\n",
|
|
"# Функция для отображения изображения\n",
|
|
"def show_image(image, title):\n",
|
|
" plt.figure(figsize=(10, 10))\n",
|
|
" plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))\n",
|
|
" plt.title(title)\n",
|
|
" plt.axis('off')\n",
|
|
" plt.show()\n",
|
|
"\n",
|
|
"# Функция для разложения изображения на базовый слой и детали\n",
|
|
"def multiscale_decomposition(image, kernel_size=15):\n",
|
|
" base_layer = cv2.GaussianBlur(image, (kernel_size, kernel_size), 0)\n",
|
|
" detail_layer_1 = cv2.subtract(image, base_layer)\n",
|
|
" detail_layer_2 = cv2.subtract(base_layer, cv2.GaussianBlur(base_layer, (kernel_size, kernel_size), 0))\n",
|
|
" return base_layer, detail_layer_1, detail_layer_2\n",
|
|
"\n",
|
|
"# Функция для применения сигмоиды к каждому пикселю\n",
|
|
"def sigmoid(x, a=1):\n",
|
|
" return expit(a * x)\n",
|
|
"\n",
|
|
"# Функция для применения тонового улучшения на основе трехуровневой декомпозиции\n",
|
|
"def multiscale_tone_enhancement(image, delta_0=1.0, delta_1=1.5, delta_2=1.2, alpha=1.0):\n",
|
|
" # Разложение изображения на базовый слой и два слоя детализации\n",
|
|
" base_layer, detail_layer_1, detail_layer_2 = multiscale_decomposition(image, kernel_size=15)\n",
|
|
"\n",
|
|
" # Среднее значение яркости для каждого канала\n",
|
|
" mu = np.mean(base_layer, axis=(0, 1))\n",
|
|
"\n",
|
|
" # Применение S-симгмоиды для управления усилением деталей\n",
|
|
" S = lambda x: sigmoid((x - mu) / 255.0, a=alpha)\n",
|
|
"\n",
|
|
" # Усиление базового слоя и слоев детализации\n",
|
|
" enhanced_image = base_layer + delta_0 * (base_layer - mu) + \\\n",
|
|
" 3 * S(detail_layer_1) * (delta_1 * detail_layer_1) + \\\n",
|
|
" 3 * S(detail_layer_2) * (delta_2 * detail_layer_2)\n",
|
|
"\n",
|
|
" # Клиппинг результата в допустимый диапазон [0, 255]\n",
|
|
" enhanced_image = np.clip(enhanced_image, 0, 255).astype(np.uint8)\n",
|
|
" return enhanced_image\n",
|
|
"\n",
|
|
"# Применение тонового улучшения\n",
|
|
"base_layer, detail_layer_1, detail_layer_2 = multiscale_decomposition(input_image, kernel_size=15)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Отображение всех слоев\n",
|
|
"show_image(base_layer, 'Base Layer')\n",
|
|
"combined_detail_1 = cv2.add(input_image, detail_layer_1)\n",
|
|
"show_image(combined_detail_1, 'Detail Layer 1 Combined with Original')\n",
|
|
"combined_detail_2 = cv2.add(input_image, detail_layer_2)\n",
|
|
"show_image(combined_detail_2, 'Detail Layer 2 Combined with Original')\n",
|
|
"\n",
|
|
"enhanced_image = multiscale_tone_enhancement(input_image)\n",
|
|
"\n",
|
|
"# Отображение исходного и улучшенного изображения\n",
|
|
"show_image(input_image, 'Original Image')\n",
|
|
"show_image(enhanced_image, 'Enhanced Image')\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "hnBtqO8gdk5O"
|
|
},
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"colab": {
|
|
"authorship_tag": "ABX9TyMDq1Nn8Tgi9q1bF37fu8j4",
|
|
"provenance": []
|
|
},
|
|
"kernelspec": {
|
|
"display_name": "Python 3",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"name": "python"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 0
|
|
}
|