基于matlab实现8种不同类型树叶的分类

直接上代码,数据预处理很重要,其它没啥了

        %第一部分:读取图像
        % 定义树叶种类和每种树叶的图片数量
        %% 
        leafTypes = {'Quercussuber', 'Salixatrocinerea', 'Populusnigra', 'Alnussp', 'Quercusrobur', 'Crataegusmonogyna', 'Ilexaquifolium', 'Neriumoleander'};
        numImagesPerType =8;%每种树叶选取8张导入数据集
        pi=3.14;
        % 初始化数据集
        dataset = struct();%原始图像
        %data2bw=struct();%二值图像
        %datargbgray = struct();%灰度图像
        %datargbhsi = struct();%HSI图像


        % 通过for循环读取图片并添加到数据集中
        for i = 1:length(leafTypes)
            for j = 1:numImagesPerType
                imagePath = ['C:\Users\灰太狼\OneDrive\桌面\图片训练集\', leafTypes{i}, '\iPAD2_C0_EX0', num2str(j), '.jpg'];
                imageData = imread(imagePath);
                dataset.(leafTypes{i}){j} = imageData;
                %datargbgray.(leafTypes{i}){j}=imageData;
                %datargbhsi.(leafTypes{i}){j}=imageData;
                %data2bw.(leafTypes{i}){j}=imageData;
                %figure;
                %imshow(imageData);%显示原始图像
            end
        end
        
        %
        %for leafType = fieldnames(dataset)'
            %for imageIndex = 1:numImagesPerType
               % imageData = dataset.(leafType{1}){imageIndex};
                
        
%
        %imagegray=im2gray(imageData);
        %imagegrayopen=imopen(imagegray,se);
        %imagegray=imagegrayopen+imagegray;
        %datargbgray.(leafTypes{i}){j}=imagegray;
        %figure;
        %imshow(imagegray);

%
       %imagehsv=rgb2hsv(imageData);
        %images=imagehsv(:,:,2);
        %imagetransit=im2bw(imageData);
        %imagehsv=images.*imagetransit;
        %datargbhsi.(leafTypes{i}){j}=imagehsv;
        %figure;
        %imshow(imagehsv);
   % end
%end

%imshow(data2bw.three{5});

        %第二部分:特征提取

featuredataset=struct();%建立特征数据集
pi=3.14159;
for leafType = fieldnames(dataset)'    %建立循环预处理图像,并在图像处理完成后提取特征储存
for imageIndex = 1:numImagesPerType
       imageDatas = dataset.(leafType{1}){imageIndex};
       
       %二值化预处理,对RGB图像进行调整,提亮绿色,减少黑色
       r = imageDatas(:,:,1);
       g = imageDatas(:,:,2);
       %% 
       b = imageDatas(:,:,3);
       % 减少黑色分量(降低蓝色和红色通道的值)
       r = r * 0.8;
       b = b * 0.8;
       % 增加绿色分量
       g = g * 1.2;

       %处理棕色部分,即绿叶枯萎那部分
       brown_threshold = 125;  % 比如红色和绿色分量都小于 125 可视为棕色
       % 对棕色像素进行处理
       brown_pixels = (r < brown_threshold) & (g < brown_threshold);
       g(brown_pixels) = g(brown_pixels) + 80;  % 增加绿色分量
       
       new_img = cat(3, r, g, b);% 组合修改后的通道
       hsv = rgb2hsv(new_img);%将RGB模型转为HSI模型

       % 提取 V 通道(亮度),调整亮度
       v_channel = hsv(:,:,3);
       threshold = 1;% 设定一个阈值,低于该阈值的认为是较黑部分
       v_channel(v_channel < threshold) = v_channel(v_channel < threshold) + 1; % 将较黑部分的 V 通道值增加一些以变亮一点
       hsv(:,:,3) = v_channel;% 根据调整后的 V 通道更新 HSV
       adjusted_img = hsv2rgb(hsv); % 将 HSV 转换回 RGB
       %figure;
       %imshow(adjusted_img);
        
       %运用超绿指数提取树叶的二值图像
       image = im2double(adjusted_img); %图像运算不能用uint8类型,会发生溢出现象,要转成double类型
       R = image(:,:,1);
       G = image(:,:,2);
       B = image(:,:,3);
       ExG = 2*G-R-B;
       [m,n] = size(ExG);
       T = graythresh(ExG);
       greenpicture = ExG;
    for i = 1:m
        for j= 1:n 
         if greenpicture(i,j) >= T
              greenpicture(i,j)=255;
            else
              greenpicture(i,j)=0;
         end
        end
    end
    se=strel('square',25);
    setest=strel('square',15);
    greenpicture=imopen(greenpicture,setest);%开运算
    greenpicture=imclose(greenpicture,se);%闭运算
    %figure;
    %imshow(greenpicture);
            %运用超绿指数对图像进行灰度预处理

            % 获取图像的三个通道
            red = imageDatas(:,:,1);
            green = imageDatas(:,:,2);
            blue = imageDatas(:,:,3);
            % 减少黑色分量(降低蓝色和红色通道的值)
            red = red * 0.8;
            blue = blue * 0.8;
            % 增加绿色分量
            green = green * 1.15;
            
            %处理棕色部分
            brown_thresholdgray = 80;  % 比如红色和绿色分量都小于 80 可视为棕色
            % 对棕色像素进行处理
            brown_pixelsgray = (red < brown_thresholdgray) & (green < brown_thresholdgray);
            green(brown_pixelsgray) = green(brown_pixelsgray) +10;  % 增加绿色分量
            new_imggray = cat(3, red, green, blue); % 组合修改后的通道
            hsvgray = rgb2hsv(new_imggray);
            
            % 提取 V 通道(亮度)
            v_channelgray = hsvgray(:,:,3);
            thresholdgray = 0.05;% 设定一个阈值,低于该阈值的认为是较黑部分
            v_channelgray(v_channelgray < thresholdgray) = v_channelgray(v_channelgray < thresholdgray) + 0.3;% 将较黑部分的 V 通道值增加一些以变亮一点
            hsvgray(:,:,3) = v_channelgray;% 根据调整后的 V 通道更新 HSV
            adjusted_imggray = hsv2rgb(hsvgray);% 将 HSV 转换回 RGB
            imagegraypicture = im2double(adjusted_imggray); %图像运算不能用uint8类型,会发生溢出现象,要转成double类型
            Red = imagegraypicture(:,:,1);
            Green = imagegraypicture(:,:,2);
            Blue = imagegraypicture(:,:,3);
            ExGgray = 2*Green-Red-Blue;

        %特征提取部分
        area=sum(greenpicture(:)>0);%面积
        glcm = graycomatrix(ExGgray,'Offset',[2 0]);%灰度共生矩阵
        statsglcm = graycoprops(glcm);
        Contrast=statsglcm.Contrast;
        Correlation=statsglcm.Correlation;
        Energy=statsglcm.Energy;
        Homogeneity=statsglcm.Homogeneity;

        % 计算叶片区域的长宽比和矩形度
        statebox = regionprops(greenpicture, 'BoundingBox');
        boundingBox = cat(1, statebox(255).BoundingBox);
        aspectRatio = boundingBox(:,3) ./ boundingBox(:,4);%长宽比
        rectangleAreas = boundingBox(:,3) .* boundingBox(:,4);%矩形度
        rectangularities = area ./ rectangleAreas;

        stateper = regionprops(greenpicture, 'Perimeter');
        perimeter=stateper(255).Perimeter;%周长

        statecon = regionprops(greenpicture, 'ConvexArea');%凸包面积

        circularity = (4.*pi.*area./(perimeter^2))*(1-0.5./(perimeter/(2*pi) + 0.5))^2;%圆形度

        sphericity = (pi^(1/3) * (6 * area).^(2/3)) ./ perimeter;%球状度
        convexArea = [statecon(255).ConvexArea];

        stateecc=regionprops(greenpicture,'Eccentricity');%偏心率
        ecc=stateecc(255).Eccentricity;

        statesolid=regionprops(greenpicture,'Solidity');%实度
        solid=statesolid(255).Solidity;

        statepd=regionprops(greenpicture,'MajorAxisLength');%周长直径比
        majorAxisLengths=statepd(255).MajorAxisLength;
        pd=perimeter./majorAxisLengths;

        moments=imagejui(ExGgray);%不变矩
        moments1=moments(1);
        moments2=moments(2);
        moments3=moments(3);
        moments4=moments(4);
        moments5=moments(5);
        moments6=moments(6);
        moments7=moments(7);

       area=area/100000;%归一化面积
       
       % 将特征存储在特征数据集,共提取了19个特征
       featuredataset.(leafType{1}){imageIndex} = {perimeter,aspectRatio,circularity,ecc,convexArea,solid,pd,rectangularities,moments1,moments2,moments3,moments4,moments5,moments6,moments7,Contrast,Correlation,Energy,Homogeneity};
       %figure;
       %imshow(greenpicture);
    end
end
        %第三部分:特征训练及分类

        % 准备特征矩阵和标签向量
        numFeatures =19;  % 特征数量
        numSamples = length(leafTypes) * numImagesPerType;  % 样本数量
        featureMatrix = zeros(numSamples, numFeatures);
        labels = zeros(numSamples, 1);
        
        % 填充特征矩阵和标签向量
        index = 1;
        for i = 1:length(leafTypes)
            for j = 1:numImagesPerType
                features = cell2mat(featuredataset.(leafTypes{i}){j});
                featureMatrix(index, :) = features;
                labels(index) = i;  % 第 i 类叶片的标签
                index = index + 1;
            end
        end
        % 划分训练集和测试集
        rng(9);  % 设置随机数种子以确保结果可重复
        cv = cvpartition(labels, 'Holdout', 0.2);  % 划分 80% 训练集和 20% 测试集
        idxTrain = training(cv);
        idxTest = test(cv);
        
        XTrain = featureMatrix(idxTrain, :);
        YTrain = labels(idxTrain);
        XTest = featureMatrix(idxTest, :);
        YTest = labels(idxTest);
        
        % 构建和训练 BP 神经网络
        hiddenLayerSize = 12;  % 隐藏层神经元数量
        net = patternnet(hiddenLayerSize);
        net.trainParam.showWindow = true;  % 显示训练过程窗口
        net = train(net, XTrain', ind2vec(YTrain'));
        
        % 测试神经网络并计算准确率
        YTestPredicted = vec2ind(net(XTest'))';
        accuracy = sum(YTestPredicted == YTest) / length(YTest);
        disp(['Accuracy: ', num2str(accuracy * 100), '%']);


        
      

       %第四部分:新图片输入与分类结果输出
       
       % 新输入图片的特征提取
       newImage = imread('C:\Users\灰太狼\OneDrive\桌面\图片训练集\Quercussuber\iPAD2_C0_EX01.JPG');  

       newr = newImage(:,:,1);
       newg = newImage(:,:,2);
       newb = newImage(:,:,3);

       % 减少黑色分量(降低蓝色和红色通道的值)
       newr = newr * 0.8;
       newb = newb * 0.8;

       % 增加绿色分量
       newg = newg * 1.2;

       %处理棕色部分
       newbrown_threshold = 125;  % 比如红色和绿色分量都小于 80 可视为棕色
       % 对棕色像素进行处理
       newbrown_pixels = (newr < newbrown_threshold) & (newg < newbrown_threshold);
       newg(newbrown_pixels) = newg(newbrown_pixels) + 80;  % 增加绿色分量

       % 组合修改后的通道
       new_image = cat(3, newr, newg, newb);
       newhsv = rgb2hsv(new_image);

       % 提取 V 通道(亮度)
       newv_channel = newhsv(:,:,3);

       % 设定一个阈值,低于该阈值的认为是较黑部分
       newthreshold = 1;

       % 将较黑部分的 V 通道值增加一些以变亮一点
       newv_channel(newv_channel < newthreshold) = newv_channel(newv_channel < newthreshold) + 1;

       % 根据调整后的 V 通道更新 HSV
       newhsv(:,:,3) = newv_channel;

       % 将 HSV 转换回 RGB
       newadjusted_img = hsv2rgb(newhsv);

       newimage = im2double(newadjusted_img); %图像运算不能用uint8类型,会发生溢出现象,要转成double类型
       newR = newimage(:,:,1);
       newG = newimage(:,:,2);
       newB = newimage(:,:,3);
       newExG = 2*newG-newR-newB;
       [newm,newn] = size(newExG);
       newT = graythresh(newExG);
       newgreenpicture = newExG;

    for i = 1:newm
        for j= 1:newn 
         if newgreenpicture(i,j) >= newT
               newgreenpicture(i,j)=255;
            else
              newgreenpicture(i,j)=0;
         end
        end
    end
    newse=strel('square',25);
    newsetest=strel('square',15);

    newgreenpicture=imopen(newgreenpicture,newsetest);
    newgreenpicture=imclose(newgreenpicture,newse);

    %灰度图像预处理

            % 获取图像的三个通道
            newred = newImage(:,:,1);
            newgreen = newImage(:,:,2);
            newblue = newImage(:,:,3);
            % 减少黑色分量(降低蓝色和红色通道的值)
            newred = newred * 0.85;
            newblue = newblue * 0.85;
            % 增加绿色分量
            newgreen = newgreen * 1.1;
            
            %处理棕色部分
            newbrown_thresholdgray = 80;  % 比如红色和绿色分量都小于 80 可视为棕色
            % 对棕色像素进行处理
            newbrown_pixelsgray = (newred < newbrown_thresholdgray) & (newgreen < newbrown_thresholdgray);
            newgreen(newbrown_pixelsgray) = newgreen(newbrown_pixelsgray) +10;  % 增加绿色分量
            
            % 组合修改后的通道
            newnew_imggray = cat(3, newred, newgreen, newblue);
            newhsvgray = rgb2hsv(newnew_imggray);
            
            % 提取 V 通道(亮度)
            newv_channelgray = newhsvgray(:,:,3);
            
            % 设定一个阈值,低于该阈值的认为是较黑部分
            newthresholdgray = 0.05;
            
            % 将较黑部分的 V 通道值增加一些以变亮一点
            newv_channelgray(newv_channelgray < newthresholdgray) = newv_channelgray(newv_channelgray < newthresholdgray) + 0.3;
            
            % 根据调整后的 V 通道更新 HSV
            newhsvgray(:,:,3) = newv_channelgray;
            
            % 将 HSV 转换回 RGB
            newadjusted_imggray = hsv2rgb(newhsvgray);
            
            newimagegraypicture = im2double(newadjusted_imggray); %图像运算不能用uint8类型,会发生溢出现象,要转成double类型
            newRed = newimagegraypicture(:,:,1);
            newGreen = newimagegraypicture(:,:,2);
            newBlue = newimagegraypicture(:,:,3);
            newExGgray = 2*newGreen-newRed-newBlue;


        

        %特征提取部分
        newarea=sum(newgreenpicture(:)>0);

        newglcm = graycomatrix(newExGgray,'Offset',[2 0]);%灰度共生矩阵
        newstatsglcm = graycoprops(newglcm);
        newContrast=newstatsglcm.Contrast;
        newCorrelation=newstatsglcm.Correlation;
        newEnergy=newstatsglcm.Energy;
        newHomogeneity=newstatsglcm.Homogeneity;

       

       % 计算叶片区域的长宽比
        newstatebox = regionprops(newgreenpicture, 'BoundingBox');
        newboundingBox = cat(1, newstatebox(255).BoundingBox);
        newaspectRatio = newboundingBox(:,3) ./ newboundingBox(:,4);%长宽比

        newrectangleAreas = newboundingBox(:,3) .* newboundingBox(:,4);%矩形度
        newrectangularities = newarea ./ newrectangleAreas;

        newstateper = regionprops(newgreenpicture, 'Perimeter');
        newperimeter=newstateper(255).Perimeter;%周长

        newstatecon = regionprops(newgreenpicture, 'ConvexArea');

        newcircularity = (4.*pi.*newarea./(newperimeter^2))*(1-0.5./(newperimeter/(2*pi) + 0.5))^2;%圆形度

        newsphericity = (pi^(1/3) * (6 * newarea).^(2/3)) ./ newperimeter;%球状度

        newconvexArea = [newstatecon(255).ConvexArea];
        newstateecc=regionprops(newgreenpicture,'Eccentricity');%偏心率
        newecc=newstateecc(255).Eccentricity;

        newstatesolid=regionprops(newgreenpicture,'Solidity');
        newsolid=newstatesolid(255).Solidity;%实度

        newstatepd=regionprops(newgreenpicture,'MajorAxisLength');
        newmajorAxisLengths=newstatepd(255).MajorAxisLength;
        newpd=newperimeter./newmajorAxisLengths;%周长直径比

        newmoments=imagejui(newExGgray);%不变矩
        newmoments1=newmoments(1);
        newmoments2=newmoments(2);
        newmoments3=newmoments(3);
        newmoments4=newmoments(4);
        newmoments5=newmoments(5);
        newmoments6=newmoments(6);
        newmoments7=newmoments(7);

        newarea=newarea/100000;
        newImageFeatures = [newperimeter,newaspectRatio,newcircularity,newecc,newconvexArea,newsolid,newpd,newrectangularities,newmoments1,newmoments2,newmoments3,newmoments4,newmoments5,newmoments6,newmoments7,newContrast,newCorrelation,newEnergy,newHomogeneity];
        
        
        predictedLabel = vec2ind(net(newImageFeatures'))';
        
        % 打印预测结果
        predictedLeafType = leafTypes{predictedLabel};
        disp(['Predicted leaf type: ', predictedLeafType]);
        imshow(newImage);显示图片并标注预测类别
        txt = predictedLeafType;
        text(250,250,txt)





 

子函数不变距代码,这个是网上找到的。

function y=imagejui(bw)  %图像的不变矩
global x_average y_average
myI=double(bw);[y,x]=size(myI);
m00=sum(sum(myI));m10=0;m01=0;
for i=1:y
    for j=1:x
        m10=m10+j*myI(i,j); m01=m01+i*myI(i,j);%求一阶矩
    end
end
x_average=m10/m00;y_average=m01/m00;
m20=myf(myI,2,0);m02=myf(myI,0,2);
m11=myf(myI,1,1);
m30=myf(myI,3,0);m03=myf(myI,0,3);
m12=myf(myI,1,2);m21=myf(myI,2,1);
m1=m20+m02;%按定义求七个不变矩
m2=(m20-m02)^2+4*m11^2;
m3=(m30-3*m12)^2+(3*m21-m03)^2;
m4=(m30+m12)^2+(m21+m03)^2;
m5=(m30-3*m12)*(m30+m12)*((m30+m12)^2-3*(m12+m03)^2) ...
    +(m03-3*m21)*(m03+m12)*((m03+m21)^2-3*(m12+m03)^2);
m6=(m20-m02)*((m30+m12)^2-(m21+m03)^2)+4*m11*(m30+m12)*(m03+m21);
m7=(3*m21-m03)*(m30+m12)*((m30+m12)^2-3*(m21+m03)^2)...
    +(m30-3*m12)*(m03+m21)*((3*m30+m12)^2-(m21+m03)^2);
y=[m1;m2;m3;m4;m5;m6;m7];
y=abs(log10(abs(y)));%利用对数的方法进行数据压缩,并给出正值
end
 
function m=myf(myI,p,q)%子函数,用于求和
global x_average y_average
[y,x]=size(myI);m00=sum(sum(myI));
m=0;
for i=1:y
    for j=1:x
        m=m+(i-y_average)^q*(j-x_average)^p*myI(i,j);     %求和
    end
end
m=m/m00^((p+q)/2+1);%归一化
end
 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值