kaggle CBIS-DDSM 依照breast density分类图片

kaggle上的CBIS-DDSM下面又有两个文件夹[csv, jpeg]。 csv文件夹中有六个文件分别为:[calc_case_description_test_set.csv calc_case_description_train_set.csv dicom_info.csv mass_case_description_test_set.csv mass_case_description_train_ set.csv meta.csv]。 另外, jpeg 文件夹中分别有好几个名子类似为“1.3.6.1.4.1.9590.100.1.2.100018879311824535125115145152454291132”的文件夹里面有“cropped images”,“full mammogram images”,“ROI mask images”。 请帮我依据“breast density”的等级分成四个文件夹1 2 3 4。 并且1 2 3 4文件夹中又个别有子文件夹“cropped images”,“full mammogram images”,“ROI mask images”。
声明: 请勿用chatGPT, 因为他给的答案是错的


import os
import shutil
import pandas as pd
import re
import cv2

#区分roi和cropped图片
def classify_img(filename):
    img=cv2.imread(filename)
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    r, c = gray_img.shape[:2]
    piexs_sum = r * c

    dark_points = (gray_img < 20)
    target_array = gray_img[dark_points]
    dark_sum = target_array.size
    dark_prop = dark_sum / (piexs_sum)
    if dark_prop >= 0.85:
        return True
    else:
        return False
    
#复制文件函数
def copy_files(dd):
    global num
    for n in range(len(dd)):
        #取出full images的路径
        d=re.findall(r'/(.*)/', dd.loc[n,'image file path'])[0]
        a=re.findall(r'/(.*)', d)[0]
        old_path=f"D:/workstation/CBIS_DDSM/jpeg/{a}"
        patient_id=dd.loc[n,'patient_id']
        abnormality_id=dd.loc[n,'abnormality id']
        left_or_right=dd.loc[n,'left or right breast']
        pathology=dd.loc[n,'pathology']
        _class={'BENIGN_WITHOUT_CALLBACK':0,'BENIGN':1,'MALIGNANT':2}
        view=dd.loc[n,'image view']
        density=dd.iat[n,1]
        if os.path.exists(old_path):
            full_filenames=os.listdir(old_path)
            #完整图片只有一个
            for i in full_filenames:
                shutil.copy(f"{old_path}/{i}", f'd:/workstation/images/{density}/full/{patient_id}_{left_or_right}_{view}_{abnormality_id}_{_class[pathology]}_{density}.jpg')
                num+=1
        #取出cropped 和roi image的路径,同一个路径下        
        d=re.findall(r'/(.*)/', dd.loc[n,'cropped image file path'])[0]
        a=re.findall(r'/(.*)', d)[0]
        old_path=f"D:/workstation/CBIS_DDSM/jpeg/{a}"
        #裁剪图片和标注图片各一个,同一个文件夹下,使用图像识别
        if os.path.exists(old_path):
            cropped_filenames=os.listdir(old_path)
            for i in cropped_filenames:
                if classify_img(f"{old_path}/{i}"):
                    shutil.copy(f"{old_path}/{i}", f'd:/workstation/images/{density}/roi/{patient_id}_{left_or_right}_{view}_{abnormality_id}_{_class[pathology]}_{density}.jpg')
                    num+=1
                else:
                    shutil.copy(f"{old_path}/{i}", f'd:/workstation/images/{density}/cropped/{patient_id}_{left_or_right}_{view}_{abnormality_id}_{_class[pathology]}_{density}.jpg')
                    num+=1
                    
name_list={'calc_test':'calc_case_description_test_set','calc_train':'calc_case_description_train_set',\
           'mass_test':'mass_case_description_test_set','mass_train':'mass_case_description_train_set'}
#创建4个文件夹及其子文件夹
for i in range(5):
    os.makedirs(f"d:/workstation/images/{i}/full",exist_ok=True)
    os.makedirs(f"d:/workstation/images/{i}/cropped",exist_ok=True)
    os.makedirs(f"d:/workstation/images/{i}/roi",exist_ok=True)
num=0#记录复制文件数
#每个csv的结构是一样的,所以调用同一个函数
for i in name_list.keys():
    dd=pd.read_csv(f'D:/workstation/CBIS_DDSM/csv/{name_list[i]}.csv')
    copy_files(dd)
    print(f'复制了{num}个文件')

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
首先,我们需要读取csv文件夹中的mass_case_description_train_set.csv和mass_case_description_test_set.csv文件来获取每个图像的密度。

import pandas as pd

train_df = pd.read_csv('csv/mass_case_description_train_set.csv')
test_df = pd.read_csv('csv/mass_case_description_test_set.csv')

# 获取密度信息
train_density = train_df['breast_density']
test_density = test_df['breast_density']

然后,我们需要根据每个图像的密度将它们分类到相应的文件夹中。我们可以使用os和shutil库来完成这一步骤。

import os
import shutil

# 创建1,2,3,4文件夹和子文件夹
for folder in ['1/cropped images', '1/full mammogram images', '1/ROI mask images',
               '2/cropped images', '2/full mammogram images', '2/ROI mask images',
               '3/cropped images', '3/full mammogram images', '3/ROI mask images',
               '4/cropped images', '4/full mammogram images', '4/ROI mask images']:
    os.makedirs(folder, exist_ok=True)

# 将图像复制到相应的文件夹中
def copy_images(density, folder_name, image_type):
    for subdir, dirs, files in os.walk('jpeg'):
        for file in files:
            if file.endswith('.jpg') and subdir.endswith(image_type):
                file_path = os.path.join(subdir, file)
                folder_num = int(file.split('-')[0])
                if density[folder_num-1] == 1:
                    shutil.copy2(file_path, f'1/{image_type}/')
                elif density[folder_num-1] == 2:
                    shutil.copy2(file_path, f'2/{image_type}/')
                elif density[folder_num-1] == 3:
                    shutil.copy2(file_path, f'3/{image_type}/')
                elif density[folder_num-1] == 4:
                    shutil.copy2(file_path, f'4/{image_type}/')

copy_images(train_density, 'train', 'cropped images')
copy_images(train_density, 'train', 'full mammogram images')
copy_images(train_density, 'train', 'ROI mask images')
copy_images(test_density, 'test', 'cropped images')
copy_images(test_density, 'test', 'full mammogram images')
copy_images(test_density, 'test', 'ROI mask images')

这段代码将遍历文件夹“jpeg”,并将符合要求的文件复制到相应的文件夹中。注意使用os.walk函数遍历文件夹需要为当前文件夹路径加上“jpeg”。

最后,我们将图像分好类后,文件夹结构应该是这样的:

├── 1
│   ├── cropped images
│   ├── full mammogram images
│   └── ROI mask images
├── 2
│   ├── cropped images
│   ├── full mammogram images
│   └── ROI mask images
├── 3
│   ├── cropped images
│   ├── full mammogram images
│   └── ROI mask images
├── 4
│   ├── cropped images
│   ├── full mammogram images
│   └── ROI mask images
├── csv
└── jpeg

希望这个代码可以帮助到你。
如果我的回答解决了您的问题,请采纳!

这个任务需要你使用Python编写代码来实现。大致步骤如下:

读取csv文件:使用Python的pandas库读取csv文件,获取每个病例的breast density的等级以及其它信息。

读取jpeg文件:使用Python的PIL库读取jpeg文件夹中的图片。

根据breast density等级创建文件夹:根据breast density的等级,创建四个文件夹(1、2、3、4)。

将图片按照breast density等级复制到相应的文件夹下:遍历jpeg文件夹中的图片,根据对应的病例的breast density等级,将图片复制到相应的文件夹下。

在1、2、3、4文件夹中再创建cropped images、full mammogram images和ROI mask images子文件夹:使用Python的os库在每个1、2、3、4文件夹下创建三个子文件夹。

将对应的图片复制到子文件夹中:遍历原始jpeg文件夹中的每个病例文件夹,将其中的cropped images、full mammogram images和ROI mask images文件夹中的图片按照对应的breast density等级复制到1、2、3、4文件夹下的相应子文件夹中。

实现代码可能会比较复杂,需要综合运用Python的文件读写、图像处理、字符串处理等各种知识点。需要一定的编程经验和技能。

该回答引用于gpt与OKX安生共同编写:
  • 该回答引用于gpt与OKX安生共同编写:
    以下是一些可能的步骤和思路,用于按照乳房密度等级将图像分类到相应的文件夹中:
  1. 在CSV文件夹中找到与JPEG文件夹中的图像对应的元数据。在CBIS-DDSM数据集中,JPEG文件夹中的每个图像都有一个DICOM文件,其中包含与该图像相关的元数据。您可以使用dicom库或其他DICOM解析库来读取这些DICOM文件,并从中提取“breast density”的等级信息。
  2. 遍历JPEG文件夹中的所有图像,并根据其密度等级将它们分类到相应的文件夹中。例如,可以使用os库中的walk()函数遍历JPEG文件夹中的所有图像路径,并使用Pillow库或其他图像处理库加载并解析每个图像。
  3. 对于每个图像,使用步骤1中提取的“breast density”的等级来确定其所属的密度等级,并创建相应的文件夹。例如,可以使用os库中的mkdir()函数来创建名为1、2、3和4的文件夹,并将具有相应密度等级的图像复制到正确的文件夹中。如果某些图像包含子文件夹,您可以在目标文件夹中创建相应的子文件夹,并将这些图像复制到相应的子文件夹中。

以下是一个简单的示例代码,可供参考:

import os
import dicom
import shutil
from PIL import Image

# Define folder paths
jpeg_folder = '/path/to/jpeg/folder'  # Update with the actual path to JPEG folder
csv_folder = '/path/to/csv/folder'    # Update with the actual path to CSV folder
output_folder = '/path/to/output/folder'

# Walk through JPEG folder and classify images by breast density level
for root, dirs, files in os.walk(jpeg_folder):
    for file in files:
        if file.endswith('.jpg'):
            # Load DICOM metadata and extract breast density level
            dicom_path = os.path.join(root, file.replace('.jpg', '.dcm'))
            ds = dicom.read_file(dicom_path)
            density = str(ds.BreastDensity)
            
            # Create target folder and copy image to correct location
            density_folder = os.path.join(output_folder, density)
            if not os.path.exists(density_folder):
                os.makedirs(density_folder)
            img_path = os.path.join(root, file)
            img = Image.open(img_path)
            img.save(os.path.join(density_folder, file))

请注意,上述代码仅供参考,您需要根据具体情况进行修改和优化。例如,您可能需要添加错误处理和调试代码,以确保程序正确运行并及时发现问题。

  • 如有用的话,还望采纳哦~