Из моего предыдущего поста мы смогли сегментировать изображения на основе нескольких подходов, таких как обнаружение blob и подключенные компоненты. Вы когда-нибудь думали, что, как только эти объекты будут идентифицированы, мы действительно сможем создавать функции на основе того, как были созданы метки?
Давайте еще раз взглянем на эритроциты из моей статьи об обнаружении капель и скопируем оттуда все необходимые коды и выходные данные. Мы еще вернемся к следующему:
- Исходное изображение
- Этапы очистки данных
- Сегментация изображений
Как только эти шаги будут выполнены, мы сможем перейти к части машинного обучения.
Очистка исходного изображения и данных
#library imports import os import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec from skimage.io import imread, imshow from skimage.color import rgb2gray from skimage.measure import label, regionprops, regionprops_table from skimage.morphology import (erosion, dilation, closing, opening, area_closing, area_opening) from glob import glob #Source Image rbc = imread("medium/rbc.jpg") #Image preprocessing and data cleaning im2 = rgb2gray(rbc) im2_bw = im2<0.85 img_morph = area_closing(area_opening(im2_bw, 200), 200) imshow(img_morph)
Теперь, когда предварительная обработка завершена, мы можем приступить к сегментации клеток крови.
#initialize rbc for labeling and segmentation rbc_files = glob('medium/rbc.jpg') #initialize properties for features properties = ['area', 'centroid', 'convex_area', 'bbox', 'bbox_area', 'eccentricity', 'equivalent_diameter', 'extent', 'filled_area', 'major_axis_length', 'minor_axis_length', 'perimeter', 'orientation', 'solidity'] clean_rbc = [] # List of two tuples (img, regionprops) fig = plt.figure(figsize=(20, 20)) file_count = len(rbc_files) thres = 0.4 no_col = 6 no_row = int(np.ceil(file_count * 2 / no_col)) gs = gridspec.GridSpec(no_row, no_col) for i, file in enumerate(rbc_files): #Show images #Subplot was made to be able to adjust to same image prefixes with different shots (ex. rbc_1, rbc_2, etc.) img = imread(file) fn = file.split()[-1].split('.')[0] ax0 = fig.add_subplot(gs[i * 2]) ax1 = fig.add_subplot(gs[i * 2 + 1]) ax0.axis('off') ax1.axis('off') # Display Threshold Image ax0.imshow(img) ax0.set_title(fn) # Get region properties of image img_label = label(img_morph) df_regions = pd.DataFrame(regionprops_table(img_label, properties=properties)) # Filter regions using area area_thres = df_regions.convex_area.mean()/3 df_regions = df_regions.loc[df_regions.convex_area > area_thres] mask_equal_height = ((df_regions['bbox-2'] - df_regions['bbox-0']) != img_label.shape[0]) mask_equal_width = ((df_regions['bbox-3'] - df_regions['bbox-1']) != img_label.shape[1]) df_regions = df_regions.loc[mask_equal_height & mask_equal_width] # Compute for Derived features y0, x0 = df_regions['centroid-0'], df_regions['centroid-1'] orientation = df_regions.orientation x1 = (x0 + np.cos(df_regions.orientation) * 0.5 * df_regions.minor_axis_length) y1 = (y0 - np.sin(df_regions.orientation) * 0.5 * df_regions.minor_axis_length) x2 = (x0 - np.sin(df_regions.orientation) * 0.5 * df_regions.major_axis_length) y2 = (y0 - np.cos(df_regions.orientation) * 0.5 * df_regions.major_axis_length) df_regions['major_length'] = np.sqrt((x2 - x0)**2 + (y2 - y0)**2) df_regions['minor_length'] = np.sqrt((x1 - x0)**2 + (y1 - y0)**2) df_regions['circularity'] = (4 * np.pi * df_regions.filled_area / (df_regions.perimeter ** 2)) # Display segmented image ax1.imshow(img_label) ax1.set_title(f'{fn} segmented: {df_regions.shape[0]}') df_regions['target']='target' clean_rbc.append(df_regions)
Затем мы можем преобразовать идентифицированные регионы в Pandas DataFrame.
#You can concatenate different types of "clean_rbc" lists as a dataframe using these codes df_rbc = pd.concat([*clean_rbc]) #Retain necessary features req_feat = ['area', 'convex_area', 'bbox_area', 'eccentricity', 'equivalent_diameter', 'extent', 'filled_area', 'perimeter', 'solidity', 'major_length', 'minor_length', 'circularity', 'target'] df_rbc = df_rbc[req_feat]
Что касается машинного обучения, я буду использовать Pycaret, чтобы упростить процесс машинного обучения. Давайте создадим пример регрессии с circularity
в качестве целевой переменной с разбиением 75–25
#where the magic happens from pycaret.regression import * df_pycaret = setup(data = df_rbc, target = 'circularity', numeric_features=['area', 'convex_area', 'bbox_area', 'eccentricity', 'equivalent_diameter', 'extent', 'filled_area','perimeter', 'solidity', 'major_length', 'minor_length'], train_size = 0.75) compare_models()
С начальными результатами Pycaret, регрессор дополнительных деревьев является наиболее эффективной моделью для этого набора данных. Давайте попробуем настроить его с помощью еще пары строк кода.
et = create_model('et') tuned_et = tune_model(et,choose_better=True)
На основе сгенерированных моделей Pycaret предлагает сохранить исходную сгенерированную модель регрессора Extra Trees, поскольку она обеспечивает более высокое значение R-квадрата (если мы собираемся использовать это в качестве основного показателя). С другой стороны, если R-квадрат не обязательно является метрикой, которую вы выбрали, то оптимальным вариантом будут настроенные дополнительные деревья.
И вот оно! Машинное обучение в сочетании с обработкой изображений
Заинтересованы в моей работе? Вы можете увидеть больше историй в моем профиле