自学内容网 自学内容网

数字图像处理:实验三

         hello!uu们大家好,这里是我们第三章实验的学习,在这里我们将学到以下几个任务,第一、基本灰度变换操作,第二、二值化的应用,额外的还有GMM模型的操作等,我们先从前面开始,了解知识点后,现在我们开始吧!

本次任务:

 内容:

       完成对图像的基本灰度变换、 扣取图片前景和背景信息的基本操作:

       1.图像反转:输出灰度=255-输入灰度              即:变量名=255-变量名;

       2.对数变换:输出灰度=c×log(1+输入灰度)      即:变量名=c.*log(1+变量名);

       3.幂次变换:输出灰度=c×(输入灰度)γ             即:变量名=c.*变量名.^γ;

       4.二值化: 输出灰度=0(输入灰度≤平均灰度的k倍) 输出灰度=1(输入灰度>平均灰度的k倍)

要求:

       1)选择一幅彩色图,对彩色图像及对应的分层图像(对红、绿、 蓝,取其中一个)按以上内容进行图像操作;其中“二值化”除了调用函数实现外,还必须用for循环实现;

        2)每幅图(一共两幅:对原图及分层图操作的结果)包含6幅子图, 包含:“原图”、 “反转”、“对数变换”、“幂次变换”、“二 值化(函数)”、“二值化(for循环)”,抬头都要有对应的名称;

A=imread('1.JPG');%获取图像,并赋值给A  
  
% 从A中提取红色图层 
A_r=A(:,:,1);  %将A的红色图层赋给A_r  
% 从A中提取绿色图层A_g=A(:,:,2);  %将A的绿色图层赋给A_g( 
% 从A中提取蓝色图层  
A_b=A(:,:,3);  %将A的蓝色图层赋给A_b
  
% 将图像A转换为double类型,以便进行数学运算,像素值范围从0到1  
AC=im2double(A);%将图像A转为double类型  
% 将红色图层A_r转换为double类型,以便进行数学运算,像素值范围从0到1  
BC=im2double(A_r);%将红色图层A_r转为double类型  
  
% 对图像A进行反转,得到其负像  
A1=255-A;  
% 对红色图层A_r进行反转,得到其负像  
B1=255-A_r;  
  
% 对图像AC进行对数变换,以增强图像的对比度  
% 公式:AC_A = log(AC*255+1)/log(256)*255 将像素值转换回0-255范围  
AC_A=log(AC*255+1)/log(256)*255;  
% 对红色图层BC进行对数变换,以增强图像的对比度  
BC_A=log(BC*255+1)/log(256)*255;%将像素值转换回0-255范围  
% 将对数变换后的图像AC_A和BC_A转换为uint8类型,以便显示  
A2=uint8(AC_A);  
B2=uint8(BC_A)%防止溢出,转换为uint8类型  
  
% 对图像A进行幂次变换,以调整图像的亮度(此处γ=1,因此实际上只是进行了线性放大)  
A3=1.5.*A.^(1);%c=1.5,γ=1,进行线性放大  
% 对红色图层A_r进行幂次变换,以调整图像的亮度  
B3=1.5.*A_r.^(1);%c=1.5,γ=1,进行线性放大  
  
% 定义二值化处理的阈值M  
M = 128;% 设置阈值(范围在0到255之间)  
% 使用自定义函数imageBinarization对图像A进行二值化处理  
A4 = imageBinarization(A, M);% 调用二值化函数,得到二值图像  
% 使用自定义函数imageBinarization对红色图层A_r进行二值化处理  
B4 = imageBinarization(A_r, M);% 调用二值化函数,得到二值图像  
  
% 定义二值化处理的阈值N  
N = 128;% 设置阈值(范围在0到255之间)  
% 使用自定义函数binaryzationWithLoop对图像A进行二值化处理  
A5 = binaryzationWithLoop(A, N);  
% 使用自定义函数binaryzationWithLoop对红色图层A_r进行二值化处理  
B5 = binaryzationWithLoop(A_r, N);  
  
% 创建第一个图形窗口,并命名为'原图处理'  
figure(1),title('原图处理')         %绘制并命名  
  
% 在第一个图形窗口中绘制原图A  
subplot(2,3,1),imshow(A)  
title('原图');  
  
% 在第一个图形窗口中绘制红色反转图像A1  
subplot(2,3,2),imshow(A1)  
title('红色反转');  
  
% 在第一个图形窗口中绘制对数变换后的图像A2  
subplot(2,3,3),imshow(A2)  
title('对数变换');  
  
% 在第一个图形窗口中绘制幂次变换后的图像A3  
subplot(2,3,4),imshow(A3)  
title('幂次变换');  
  
% 在第一个图形窗口中绘制使用函数进行二值化处理后的图像A4  
subplot(2,3,5),imshow(A4)  
title('二值化(函数)');  
  
% 在第一个图形窗口中绘制使用for循环进行二值化处理后的图像A5  
subplot(2,3,6),imshow(A5)  
title('二值化(for循环)');  
  
% 创建第二个图形窗口,并命名为'红色分层处理'  
figure(2),title('红色分层处理')           %绘制并命名  
  
% 在第二个图形窗口中绘制红色分层图像A_r  
subplot(2,3,1),imshow(A_r)  
title('红色分层');  
  
% 在第二个图形窗口中绘制红色反转图像B1  
subplot(2,3,2),imshow(B1)  
title('红色反转');  
  
% 在第二个图形窗口中绘制对数变换后的红色图层图像B2  
subplot(2,3,3),imshow(B2)  
title('对数变换');  
  
% 在第二个图形窗口中绘制幂次变换后的红色图层图像B3  
subplot(2,3,4),imshow(B3)  
title('幂次变换');  
  
% 在第二个图形窗口中绘制使用函数进行二值化处理后的红色图层图像B4  
subplot(2,3,5),imshow(B4)  
title('二值化(函数)');  
  
% 在第二个图形窗口中绘制使用for循环进行二值化处理后的红色图层图像B5  
subplot(2,3,6),imshow(B5)  
title('二值化(for循环)');  
  
% 自定义函数:使用给定阈值M对输入图像进行二值化处理  
% 如果输入图像是彩色的,则先将其转换为灰度图像  
% 然后根据阈值M将图像二值化,大于M的像素值设为1,小于等于M的设为0  
function binaryImage = imageBinarization(inputImage, M)  
    % 检查输入图像是否为灰度图像  
    if size(inputImage, 3) == 3  
        inputImage = rgb2gray(inputImage); % 将彩色图像转换为灰度图像  
    end  
      
    % 使用给定的阈值M进行二值化  
    binaryImage = inputImage > M;  
      
    % 将逻辑值(true/false)转换为0和1(可选,但便于后续处理)  
    binaryImage = double(binaryImage);  
end  
  
% 自定义函数:使用给定阈值N对输入图像进行二值化处理(使用for循环实现)  
% 如果输入图像是彩色的,则先将其转换为灰度图像  
% 然后遍历图像的每个像素,根据阈值N将像素值转换为0或1  
function binaryImage = binaryzationWithLoop(inputImage, N)  
    % 检查输入图像是否为灰度图像  
    if size(inputImage, 3) == 3  
       inputImage = rgb2gray(inputImage); % 将彩色图像转换为灰度图像  
    end  
      
    % 获取图像的大小  
    [rows, cols] = size(inputImage);  
      
    % 创建一个与原图像大小相同的逻辑数组(用于存储二值化后的图像)  
    binaryImage = false(rows, cols);  
      
    % 遍历图像的每一个像素  
    for i = 1:rows  
        for j = 1:cols  
            % 根据阈值N将像素值转换为0或1  
            if inputImage(i, j) > N  
                binaryImage(i, j) = 1;  
            else  
                binaryImage(i, j) = 0;  
            end  
        end  
    end  
      
    % 将逻辑值(true/false)转换为double类型(可选,但imshow可以直接显示逻辑数组)  
    binaryImage = double(binaryImage);  
End

结果:

重点:高斯混合模型(Gaussian Mixture Model)可以近似任意形状的概率分布。

GMM的核心思想:任意形状的概率分布可以通过多个单高斯分布的线性组合进行近似。

高斯混合模型内容都集中在一个叫做:gmdistribution的类中。可以在MATLAB中输入:help gmdistribution,查看这个类的详细介绍和帮助文档。下面是对这个类简单的介绍。

gmdistribution类的介绍:

gmdistribution对象存储高斯混合分布, 也称为高斯混合模型 (GMM), 它是由多元高斯分布分量组成的多变量分布。每个分量由其平均值和协方差定义, 混合物由混合比例向量定义。

创造:可以通过两种方式创建gmdistribution模型对象。使用gmdistribution函数 (此处描述) 通过指定分布参数来创建gmdistribution模型对象。使用 fitgmdist 函数可以将gmdistribution模型对象与给定固定数量的组件的数据相匹配。

使用方法:

gm = gmdistribution(mu,sigma) 创建一个gmdistribution模型对象使用指定的手段mu和方差sigma以相等的混合的比例。
gm = gmdistribution(mu,sigma,p) 指定多变量高斯分布分量的混合比例。

      以上是使用指定的均值和方差构造高斯混合模型类,也就是根据给定的参数得到数据。然而我们常用的是根据数据的分布求得这些参数:均值、协方差、混合权重等,这时就要用到上文提到的fitgmdist函数了。

       在MATLAB中输入:hlep gmdistribution,或者输入:help fitgmdist函数可以查看此函数的帮助文档,并且帮助文档中会给出部分例子。下面为对这个函数的介绍:

gmdistribution.fit(高斯混合参数估计)

gmdistribution.fit(高斯混合参数估计)

注意

   fit将被删除在未来的版本。改用 fitgmdist。(MATLAB的帮助文档很温馨,特意指出了这个函数在未来的版本可能会被删除,并且给出了修改使用的建议)

语法

obj= gmdistribution.fit(X,k)obj=gmdistribution.fit(...,param1,val1,param2,val2,...)

描述

obj= gmdistribution.fit(X,k)obj=gmdistribution.fit(...,param1,val1,param2,val2,...)  

       使用期望最大化 (EM) 算法构造包含最大似然的 gmdistribution 类的对象obj高斯混合模型中的参数的估计与k分量的数据在n-m矩阵X, 其中n是观察的数量和m是数据的维度。gmdistributionNaN值视为缺少的数据。包含NaN值的X行被排除在合适的范围内。

 obj = gmdistribution.fit(...,param1,val1,param2,val2,...)  

gmdistribution.fit(函数可以在MATLAB帮助文档里查找到):

在某些情况下, gmdistribution可能收敛到一个或多个元件具有病态或奇异协方差矩阵的解。

下面的问题可能导致病态的协方差矩阵:

(1)数据的维数相对较高, 没有足够的观测。

(2)数据的某些功能 (变量) 是高度相关的。

(3)部分或全部功能是离散的。

(4)您试图将数据与太多组件相匹配。

通常, 通过使用下列预防措施之一, 可以避免获得病态的协方差矩阵:

(1)预处理数据以删除相关功能。

(2)将'SharedCov'设置为true可对每个组件使用相等的协方差矩阵。

(3)将'CovType' " 设置为'diagonal'.

(4)使用'Regularize'将一个非常小的正数添加到每个协方差矩阵的对角线上。

(5)请尝试另一组初始值。

在其他情况下, gmdistribution可能通过中间步骤, 其中一个或多个组件具有病态的协方差矩阵。尝试另一组初始值可能会避免此问题, 而不会更改数据或模型。

fitgmdist(拟合高斯混合模型数据)

语法

GMModel = fitgmdist(X,k)
GMModel = fitgmdist(X,k,Name,Value)

fitgmdist使用示例代码:

mu1 = [1 2];
Sigma1 = [2 0; 0 0.5];
mu2 = [-3 -5];
Sigma2 = [1 0;0 1];
rng(1); % For reproducibility
X = [mvnrnd(mu1,Sigma1,1000);mvnrnd(mu2,Sigma2,1000)];
%适合高斯混合模型。指定有两个组件。
GMModel = fitgmdist(X,2);
%在拟合的高斯混合模型轮廓上绘制数据。
figure
y = [zeros(1000,1);ones(1000,1)];
h = gscatter(X(:,1),X(:,2),y);
hold on
ezcontour(@(x1,x2)pdf(GMModel,[x1 x2]),get(gca,{'XLim','YLim'}))
title('{\bf Scatter Plot and Fitted Gaussian Mixture Contours}')
legend(h,'Model 0','Model1')
hold off

       相关数学计算和表示可以参考这篇文章,咸鱼哥这里不再详细的赘述,之后会把这里总结成简化的知识点给大家理解。GMM:高斯混合模型原理实现与应用 - 知乎

       好的,实验三的内容基本上就是这些,但实际操作中还有很多的方法还需要去借助书来进行学习,冈萨雷斯课本上的网址大家可以学习的时候作为课下练习和学习的参考,课本习题上也有部分解答,学习不断,诸君共勉,这是咸鱼哥对大家的期许,uu们,下章见!


原文地址:https://blog.csdn.net/weixin_73924253/article/details/145227267

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!