基于MATLAB的胃癌检测实现方案

2025-12-12

基于MATLAB的胃癌检测实现方案,结合主动轮廓分割(Active Contour)与支持向量机(SVM)分类,包含图像处理、特征提取和模型训练全流程


一、核心代码

1. 图像预处理与主动轮廓分割

function [segmented, features] = preprocess_and_segment(image_path, mask_path)
    % 读取图像并灰度化
    img = imread(image_path);
    gray_img = rgb2gray(img);
    
    % 高斯滤波去噪(σ=1)
    blurred = imgaussfilt(gray_img, 1);
    
    % 加载初始掩膜(需手动标注或自动初始化)
    mask = imread(mask_path);
    mask = imbinarize(mask);
    
    % 主动轮廓迭代优化(Chan-Vese模型)
    snake = activecontour(blurred, mask, 300, 'Chan-Vese', 'ContractionBias', 0.3);
    
    % 形态学后处理
    kernel = strel('disk', 2);
    cleaned = imopen(snake, kernel);
    
    % 特征提取
    features = extract_features(cleaned);
end

function features = extract_features(segmented)
    % 形态学特征
    stats = regionprops(segmented, 'Area', 'Perimeter', 'Eccentricity');
    area = stats.Area;
    perimeter = stats.Perimeter;
    circularity = 4*pi*area/perimeter^2;
    
    % 纹理特征(GLCM)
    glcm = graycomatrix(segmented, 'NumLevels', 16, 'GrayLimits', []);
    contrast = graycoprops(glcm, 'Contrast');
    homogeneity = graycoprops(glcm, 'Homogeneity');
    
    features = [area, perimeter, circularity, contrast.Contrast, homogeneity.Homogeneity];
end

2. SVM分类模型训练

function svm_model = train_svm(features, labels)
    % 数据归一化
    [features_norm, ps_input] = mapminmax(features', 0, 1);
    
    % 划分训练集/测试集(70%训练)
    cv = cvpartition(size(features,1),'HoldOut',0.3);
    train_data = features_norm(:,cv.training);
    test_data = features_norm(:,cv.test);
    train_labels = labels(cv.training);
    test_labels = labels(cv.test);
    
    % 模型训练(RBF核)
    svm_model = fitcsvm(train_data', train_labels, ...
        'KernelFunction', 'rbf', ...
        'BoxConstraint', 10, ...
        'KernelScale', 'auto', ...
        'Standardize', true);
    
    % 模型评估
    predicted = predict(svm_model, test_data');
    accuracy = sum(predicted == test_labels)/numel(test_labels);
    fprintf('分类准确率: %.2f%%
', accuracy*100);
end

二、完整工作流程

%% 数据准备(示例路径)
image_dir = 'gastric_images/';
mask_dir = 'masks/';
labels = [ones(50,1); 2*ones(50,1)];  % 1:正常, 2:胃癌

all_features = [];
all_labels = [];

%% 批量处理图像
for idx = 1:100
    img_path = fullfile(image_dir, sprintf('img_%03d.jpg', idx));
    mask_path = fullfile(mask_dir, sprintf('mask_%03d.png', idx));
    
    % 分割与特征提取
    [segmented, features] = preprocess_and_segment(img_path, mask_path);
    
    % 数据存储
    all_features = [all_features; features];
    all_labels = [all_labels; labels(idx)];
end

%% 训练SVM模型
svm_model = train_svm(all_features, all_labels);

%% 模型保存
save('gastric_cancer_svm_model.mat', 'svm_model');

三、关键参数优化

  1. 主动轮廓参数调整

    % 改进参数设置(提升分割精度)
    snake = activecontour(blurred, mask, 500, 'Chan-Vese', ...
        'ContractionBias', 0.5,  % 增强收缩趋势
        'Smoothing', 2);         % 平滑迭代次数
    
  2. SVM参数调优

    % 网格搜索优化
    cmd = '-v 5 -t 2 -c [0.1,10](@ref)-g [0.01,1]';
    best_params = svmtrain(train_labels, train_data', cmd);
    

参考代码 利用主动轮廓分割和SVM分类方法进行胃癌检测的源代码 www.3dddown.com/csa/65085.html

四、工程实践建议

  1. 数据增强

    % 生成增强数据
    augmented_images = imageDataAugmenter(...
        'RandRotation', [-10,10], ...
        'RandXReflection', true, ...
        'RandYReflection', true);
    
  2. 交叉验证

    % 10折交叉验证
    cv = cvpartition(size(features,1),'KFold',10);
    cv_accuracy = zeros(cv.NumTestSets,1);
    
    for i = 1:cv.NumTestSets
        train_data = features(cv.training(i),:);
        test_data = features(cv.test(i),:);
        train_labels = labels(cv.training(i));
        test_labels = labels(cv.test(i));
    
        model = fitcsvm(train_data', train_labels);
        cv_accuracy(i) = sum(predict(model,test_data') == test_labels)/numel(test_labels);
    end
    mean_accuracy = mean(cv_accuracy);
    

五、典型应用场景

  1. 内镜图像分析

    % 加载胃镜图像
    endo_img = imread('endoscope_image.jpg');
    [segmented, features] = preprocess_and_segment(endo_img, []);
    predicted_class = predict(svm_model, features');
    
  2. 病理切片分析

    % 处理WSI切片
    slide_img = imread('pathology_slide.tif');
    [segmented, features] = preprocess_and_segment(slide_img, []);