MATLAB图像处理的实例

图像处理实验实例

MATLAB图像处理的实例_第1张图片

作者:@猫西柿


主要说明

  • MATLAB实现
  • 基础的案例
  • 案例相关参考

HSI/HSV 简单图像增强

imread('d:/911.png');
RGB = ans;
RGB1 = imcrop(RGB,[1000 1000 640 480]);
HSV = rgb2hsv(RGB1);
RGB2 =imadjust(RGB1,[0.15 0.9],[0 1]);

I=RGB1;
I=double(I);
J=(I-30)*255/70;
row=size(I,1);
col=size(I,2);
for i=1:row
    for j=1:col
        if(J(i,j)<0)
            J(i,j)=0;
        end
        if J(i,j)>255;
            J(i,j)=255;
        end
    end
end
subplot(2,2,1);imshow(RGB1);subplot(2,2,2);imshow(HSV);
subplot(2,2,3);imshow(RGB2);subplot(2,2,4);imshow(uint8(J));

相关函数介绍:

  1. imreade(url) 读取url路径指定图像(RGB存储)
  2. imcrop(rgb,n) 裁剪rgb为n(二维数对)大小
  3. imadjust() 参考链接

参考网址:

图像增强——灰度线性、直方图均衡、同态滤波
图像处理——对比度增强
histeq从用法到原理——Matlab直方图均衡化函数


图片裁剪直方图统计/均衡化

实现代码

RGB=imread('d:/911.png');
rgb1=rgb2gray(RGB);
rgb=imresize(rgb1,[240 320]);

[w, h] = size(rgb)
hcount = zeros([1 256]);%直方图统计
for i = 1:w
    for j = 1:h
        % Accumulation
        hcount(rgb(i, j)) = hcount(rgb(i, j)) + 1;
    end
end;

figure;

subplot(3,2,2);
imshow(rgb);

subplot(3,2,1);
stem(0:255, hcount,'.');
axis([0 255 0 5000]);

image = rgb%直方图统计
[height, width] = size(image);
NumPixel = zeros(1,256);
for i = 1 : height
   for j = 1 : width
       k = image(i,j);
       NumPixel(k+1) = NumPixel(k+1) + 1;
   end
end

%由此开始 直方图均衡化
ProbPixel = zeros(1,256);
for i = 1 : 256
    ProbPixel(i) = NumPixel(i) / (height * width);
end

CumPixel = cumsum(ProbPixel);
CumPixel = uint8((256-1) .* CumPixel + 0.5);

outImage = uint8(zeros(height, width));

for i = 1 : height
   for j = 1 : width
      outImage(i,j) = CumPixel(image(i,j));
   end
end


[w, h] = size(outImage);
hcount = zeros([1 256]);
for i = 1:w
    for j = 1:h
        hcount(outImage(i, j)) = hcount(outImage(i, j)) + 1;
    end
end;
%由此开始 直方图均衡化结束

subplot(3,2,3);
stem(0:255, hcount,'.');
axis([0 255 0 5000]);

subplot(3,2,4);
imshow(outImage);

subplot(3,2,5);
imshow(RGB);

相关函数介绍

  1. imresize()函数缩放

参考网址:

直方图 matlab 均值化 直方图
灰度图实现


实现图像的旋转(插值处理)

实现的函数:function im2= MyRotaFun(X,Y)

function im2= MyRotaFun(X,Y)
%函数文件名 MyRotaFun.m

% 读入图片
im = X
% 求出旋转矩阵
a = Y / 180 * pi;
R = [cos(a), -sin(a); sin(a), cos(a)];
R = R'; % 求出旋转矩阵的逆矩阵进行逆向查找
% 计算原图大小
sz = size(im);
h = sz(1);
w = sz(2);
ch = sz(3);
c1 = [h; w] / 2;
% 计算显示完整图像需要的画布大小
hh = floor(w*sin(a)+h*cos(a))+1;
ww = floor(w*cos(a)+h*sin(a))+1;
c2 = [hh; ww] / 2;
% 初始化目标画布
im2 = uint8(ones(hh, ww, 3)*128);
for k = 1:ch
    for i = 1:hh
       for j = 1:ww
          p = [i; j];
          pp = (R*(p-c2)+c1);
          mn = floor(pp);
          ab = pp - mn;
          a = ab(1);
          b = ab(2);
          m = mn(1);
          n = mn(2);
          % 线性插值方法
          if (pp(1) >= 2 && pp(1) <= h-1 && pp(2) >= 2 && pp(2) <= w-1)
             im2(i, j, k) = (1-a)*(1-b)*im(m, n, k) + a*(1-b)*im(m+1, n, k)...
                          + (1-a)*b*im(m, n, k)     + a*b*im(m, n, k);
          end
       end
    end
end

函数运行主要代码

rgb=imread('你的图像url');
b1 =imresize(rgb,[480 640]);

b15 = imrotate(b1,15);
c15 = MyRotaFun(b1,15);
s15 = imsubtract(b15,c15);

b70 = imrotate(b1,70);
c70 = MyRotaFun(b1,70);
s70 = imsubtract(b70,c70);

subplot(231),imshow(rgb2gray(b15));
subplot(232),imshow(rgb2gray(c15));
subplot(233),imshow(rgb2gray(s15));


subplot(234),imshow(rgb2gray(b70));
subplot(235),imshow(rgb2gray(c70));
subplot(236),imshow(rgb2gray(s70));

参考链接

matlab图像旋转


Edge算子实现(Sobel、apalance)

实验说明:

  1. sobel算子检测边缘
  2. log算子检测边缘
  3. edeg()库函数检测边缘

sobel自定义函数FunSobel()

function output = FunSobel(input)
    img = input;
    [H,W]=size(rgb2gray(img));

    F=double(img);
    U=double(rgb2gray(img));
    uSobel=rgb2gray(img);

    for i=2:H-1
        for j=2:W-1
            Gx=(U(i+1,j-1)+2*U(i+1,j)+F(i+1,j+1))-(U(i-1,j-1)+2*U(i-1,j)+F(i-1,j+1));
            Gy=(U(i-1,j+1)+2*U(i,j+1)+F(i+1,j+1))-(U(i-1,j-1)+2*U(i,j-1)+F(i+1,j-1));
            uSobel(i,j)=sqrt(Gx^2+Gy^2);
        end
    end
    output = im2uint8(uSobel);

end

log自定义函数laplaceFun()

function output = laplaceFun(input)

img_3=mat2gray(input);   %图像矩阵的归一化
[m,n]=size(img_3);
img_4=img_3;       %保留图像的边缘一个像素

L=0;
t=0.2;          %设定阈值

%Laplace算子
for j=2:m-1
    for k=2:n-1
        L=abs(4*img_3(j,k)-img_3(j-1,k)-img_3(j+1,k)-img_3(j,k+1)-img_3(j,k-1));
        if(L > t)
            img_4(j,k)=255;  %else
            img_4(j,k)=0;    %黑
        end
    end
end

output =img_4;
end

主函数

rgb=imread('你的图像url');
rgb=imresize(rgb,[400,400]);

subplot(2,3,1);imshow(rgb);
subplot(2,3,2);imshow(FunSobel(rgb));%Sobel自定义函数实现
subplot(2,3,3);imshow(laplaceFun(rgb2gray(rgb)));%拉普拉斯自定义实现
subplot(2,3,4);imshow(edge(rgb2gray(rgb),'log'));%库函数边缘log实现
subplot(2,3,5);imshow(edge(rgb2gray(rgb),'sobel'));%库函数边缘sobel实现

参考连接

图像边缘检测——Laplace算子、LOG算子、DOG算子


霍夫变换以及检测直线

霍夫变换的定义

霍夫变化matlab实现
霍夫变换理解

实验流程的思路

  1. 获取适当的图形样本
  2. 对图形样本进行边缘化处理获取二值图像
  3. 进行霍夫变换
  4. 寻找霍夫极值并绘制直线

霍夫检测直线实现

%%Hougn变换
I = imread('timg.jpg');
I = imresize(I,[480 640]);
J = I;
I = rgb2gray(I);

f=I;
BW=edge(f,'log');

figure;
subplot(2,2,1);
imshow(f);
title('原始图像')

[row,col]=size(BW);
rhomax=round((row*row+col*col)^0.5);
A=zeros(2*rhomax,180);   %这里,实际上rho的取值范围为[-rhomax,rhomax]%但是为了后面进行数量统计,转变为[1,2rhomax]
for m=1:row
    for n=1:col
        if BW(m,n)>0 %判断为边缘
            for theta=1:180
                
                r=theta/180*pi; %角度转换
                rho=round(m*cos(r)+n*sin(r));
                %Hough变换
                
                rho=rho+rhomax+1;
                A(rho,theta)=A(rho,theta)+1;
            end
        end
    end
end
[rho,theta]=find(A>150);   %超过n个点视为共线,rho列号,theta行号
nma=length(rho);

subplot(2,2,2);
imshow(J);

for i=1:nma
    hold on
    m=1:row;
    r=theta(i)/180*pi;
    n=(rho(i)-rhomax-m*cos(r))/(0.0001+sin(r));
    plot(n,m,'blue','LineWidth',1);
end

title('hough自定义实现检测');

[H, T, R] = hough(BW);
P = houghpeaks(H,10);
x = T(P(:, 2));
y = R(P(:, 1));
lines = houghlines(BW, T, R, P);

subplot(2, 2, 3);
imshow(H, [], 'XData', T, 'YData', R, 'InitialMagnification', 'fit'); %hough变换的图像
xlabel('\theta'), ylabel('\rho');
axis on, axis square, hold on;
P = houghpeaks(H, 4); %提取3个极值点
x = T(P(:, 2));
y = R(P(:, 1));
plot(x, y, 's', 'color', 'white'); %标出极值点
lines = houghlines(BW, T, R, P); %提取线段

subplot(2,2,4);imshow(J);hold on;
for k = 1:length(lines)
    xy = [lines(k).point1; lines(k).point2];
    plot(xy(:, 1), xy(:, 2), 'LineWidth', 2, 'Color', 'yellow');
    plot(xy(1, 1), xy(1, 2), 'x', 'LineWidth', 2, 'Color', 'red');
    plot(xy(2, 1), xy(2, 2), 'x', 'LineWidth', 2, 'Color', 'blue');
end
title('hough库函数实现');

傅里叶低通滤波

参考网站

傅里叶低通滤波
傅里叶变换

实现代码

img=imread('peppers.png');
img=rgb2gray(img);

subplot(2,2,1);imshow(img);
d0=50; 

F=fft2(img);          %傅里叶变换
F1=log(abs(F)+1);   %取模并进行缩放
subplot(2,2,3);imshow(F1,[]);title('傅里叶变换频谱图');

[m n]=size(img);
m_mid=fix(m/2); 
n_mid=fix(n/2);  
img_f=fftshift(fft2(double(img)));
img_lpf=zeros(m,n);
for i=1:m
    for j=1:n
        d=sqrt((i-m_mid)^2+(j-n_mid)^2);   %理想低通滤波,求距离
        if d<=d0
            h(i,j)=1;
        else
            h(i,j)=0;
        end
        img_lpf(i,j)=h(i,j)*img_f(i,j);  
    end
end
img_lpf=ifftshift(img_lpf);
img_lpf=uint8(real(ifft2(img_lpf)));

subplot(2,2,2);imshow(img_lpf);


Fs=fft2(img_lpf);          %傅里叶变换
F2=log(abs(Fs)+1);   %取模并进行缩放
subplot(2,2,4);imshow(F2,[]);title('傅里叶变换频谱图');

形态学处理

参考链接

函数实现
形态学处理

实验流程

  1. 图片开(闭)运算处理
  2. 均值滤波、中值滤波实现

均值滤波 avefilt.m

%均值滤波函数 x是需要滤波的图像,n是模板大小(即n×n)
function d=avefilt(x,n)
a(1:n,1:n)=1;   %a即n×n模板,元素全是1
p=size(x);   %输入图像是p×q的,且p>n,q>n
x1=double(x);
x2=x1;
%A(a:b,c:d)表示A矩阵的第a到b行,第c到d列的所有元素
for i=1:p(1)-n+1
    for j=1:p(2)-n+1
        c=x1(i:i+(n-1),j:j+(n-1)).*a;  %取出x1中从(i,j)开始的n行n列元素与模板相乘
        s=sum(sum(c));                 %求c矩阵(即模板)中各元素之和
        x2(i+(n-1)/2,j+(n-1)/2)=s/(n*n); %将模板各元素的均值赋给模板中心位置的元素
    end
end
%未被赋值的元素取原值
d=uint8(x2);

中值滤波 midfilt.m

%中值滤波函数。x是需要滤波的图像,n是模板大小(即n×n)
function d=midfilt(x,n)
p=size(x);   %输入图像是p×q的,且p>n,q>n
x1=double(x);
x2=x1;
for i=1:p(1)-n+1
    for j=1:p(2)-n+1
        c=x1(i:i+(n-1),j:j+(n-1));  %取出x1中从(i,j)开始的n行n列元素,即模板(n×n的)
        e=c(1,:);      %是c矩阵的第一行
        for u=2:n
            e=[e,c(u,:)];     %将c矩阵变为一个行矩阵
        end
        mm=median(e);      %mm是中值
        x2(i+(n-1)/2,j+(n-1)/2)=mm;   %将模板各元素的中值赋给模板中心位置的元素
    end
end
%未被赋值的元素取原值
d=uint8(x2);

主要运行函数

clc;
clear all;
close all;
f = imread('图片url');
f = rgb2gray(f);
se=strel('square',20);%结构元素
fc=imclose(f,se);%闭运算

fa=avefilt(f,3);
fm=midfilt(f,3);

figure;

subplot(1,3,1);imshow(f);title('原图');
subplot(1,3,2);imshow(fa);title('均值滤波');
subplot(1,3,3);imshow(fm);title('中值滤波');

K-means划分图片

简单理解

图像识别与k-means算法
聚类算法实例:K-Means实现图像分割

图像分割

图像分割即把图像分割成若干不相交的区域,实质是像素的聚类过程,是图像处理的一种方法。可分为:

  1. 基于区域技术,如聚类算法
  2. 基于边缘技术

实现代码

主函数(k-means聚类划分)

clc;
clear all;
close all;
%用k-means算法对图像进行分割
I=imread('图片url');
%获得图像大小
[M,N]=size(I);
%获得图像的直方图统计
hist_I=Histeq_Num(I,M,N);

%类别的数量
k=3;
%产生随机数
R=randperm(256);
%初始化中心点
m=R(1:k);
%最大误差
E=0.001;
%直方图的长度
L=length(hist_I);
B=zeros(L,1);
cat_Hist=cat(2,hist_I',B);
m_copy=m;
%开始寻找最佳分割点
flag=1;
while flag
    for i=1:L
        if cat_Hist(i,1)~=0
            %计算每一个灰度级与中心点的欧拉距离
            D=abs(m-i);
            [C,ind_min]=min(D);
            cat_Hist(i,2)=ind_min;
        end
    end
    flag1=0;
    for v=1:k
        ind=find(cat_Hist(:,2)==v);
        sum=0;
        num=0;
        for j=1:length(ind)
            sum=sum+ind(j)*cat_Hist(ind(j));
            num=num+cat_Hist(ind(j));
        end
        m_copy(v)=sum/num;
        if abs(m_copy(v)-m(v))<E
            flag1=flag1+1;
        end
    end
    if flag1==3
        flag=0;
    else
        m=m_copy;
    end
end
m=floor(m);
for i=1:L
    if cat_Hist(i,1)~=0
        ind=find(I==i);
        I(ind)=m(cat_Hist(i,2));
    end
end
imshow(I)

Histeq_Num.m直方图统计

%%%直方图计数
function [hist_I]=Histeq_Num(I,M,N)
    hist_I=zeros(1,256);
    %每一个值加1,消除零值,以与矩阵的下标对应
    I=I+1;
    %遍历图像,对每一个灰度分量进行数量统计
    for i=1:M*N
        hist_I(I(i))=hist_I(I(i))+1;
    end
end

MATLAB图像处理的实例_第2张图片
MATLAB图像处理的实例_第3张图片

你可能感兴趣的:(图像处理,算法,图像处理,matlab,计算机视觉)