目前算法工匠卫通(副总工)、过冷水(电化学)博士、好学懿(电子电力)博士和伟SSS(联合物理仿真)博士都已经在仿真秀平台创作。
一、写在前面
20世纪20年代,通过海底电缆从英国的伦敦到美国的纽约采用数字压缩技术传输了第一张数字照片,开启了数字图像时代。此后,由于遥感等领域的应用,图像处理技术逐步受到关注并得到相应的发展。
随着计算机科学技术的不断发展以及人们在日常生活中对图像信息的需求不断增大,数字图像处理作为一个跨学科的前沿科技领域,在工程学、计算机科学、信息学、统计学、物理、遥感、生物医学、地质、海洋、气象、农业等许多学科中都得到广泛的应用,并显示出广阔的前景。
近年来,图像处理以其信息量大、传输速度快等一系列优点,已成为人类获取信息的重要来源及传输信息的重要手段,并且数字图像处理正以强劲的发展态势朝着智能化、网络化、个人化、实时化等方向发展。在信息社会中,图像处理技术无论是在理论上还是在实践中,都有着巨大的潜力。
过冷水还清晰的第一次参加数学建模大赛遇到的参赛题目就是图像处理。
数学建模大赛题目
当时过冷水只是菜鸟层次,是别人带着解决问题,只做代码编辑工的工作,对图像处理了解的并不多。随着学习的深入,开始接触各种图像处理应用,比较简单的有提取图像边缘轮廓,计算图像面积等等这样的问题。
仿真秀平台最近在不断完善Matlab数字图像方面的内容,过冷水因此抛转引玉给读者分享一下常见的Matlab六大实用图像处理技巧。欢迎大家一起来分享和交流。
二、图像压缩
imwrite(A,B,’quality’,ratio)
使用该技能可以降低图像的品质,虽然是说一般网友都喜欢看高清、大图,但有时候高清大图是会被禁的啊!所以在特殊场合下为了有效的传递信息,就可以采用该方式减低图像品质(模糊化),就不会有什么问题了。
clc;clear
A=imread('1.jpg');
imshow(A)
imwrite(A,'2.jpg','quality',0.2)
B=imread('2.jpg');
subplot(1,2,1);imshow(A);title('原始图像');
subplot(1,2,2);imshow(B);title('压缩图像');
精通图像处理的大佬们应该了解图像二值化处理和灰度化处理简直是图像中简单的不能再简单的内容了,过冷水也没有什么可讲的,只是作为通识知识有必要进行简单普及分享。
clc;clear
A=imread('3.jpg');
B=rgb2gray(A);
C=imbinarize(B);
subplot(1,3,1);imshow(A);title('原始图像');
subplot(1,3,2);imshow(B);title('灰度图像');
subplot(1,3,3);imshow(C);title('二值化');
%图像边缘检测
clc;clear
A=imread('4.jpg');
B=rgb2gray(A);
C=imbinarize(B);
D=edge(C);
subplot(1,2,1);imshow(C);title('原始图像');
subplot(1,2,2);imshow(D);title('边缘检测');
前段时间过冷水就用灰度化、二值化、边缘化解决了两个具体的问题。计算不规则图像面积,识别图像中圆形的个数。
图像面积的求解基本思路就是将其用Matlab进行识别,提出其轮廓坐标,然后再用Matlab求面积坐标函数,就可以实现面积的计算,图像处理就是如何获取边缘轮廓坐标。
clc;clear
A=imread('4.jpg');
B=rgb2gray(A);
C=imbinarize(B);
D=edge(C)
[col,row]=find(D == 1);
S=polyarea(col,row)
%检查小圆的个数
clc;
clear
image = imread('5.jpg');
[height,width,channel] =size(image);%确定输入突变的长宽
rc =sqrt(width^2 height^2)/2; %搜索圆的最大半径
n=30; %划分区间个数
dr = rc/n;%确定半径区间
%检测输入图片上的圆
gray =rgb2gray(image); %灰度化
bw = imbinarize(gray); %二值化
bw_inverse =imcomplement(bw); %二值图像反转,即0变1,1变0
[centers,radius] =imfindcircles(bw_inverse,[5,20]); %检测图像上半径在5~20之间的圆,也可以是其它,看实际情况需要
particle_num =length(radius(:)); %统计圆的个数
%显示图像
figure;
imshow(bw_inverse);
hold on;
viscircles(centers,radius,'EdgeColor','b');
%计算每个单位圆内的原子个数
[row,col] = size(centers);
这么一看平平无奇的灰度转换、二值转换、边缘检测确实能够做一些很实用的工作。所以说没有简单的代码函数,只有呆滞的程序员。
五、图像亮度处理
对于摄影爱好者来说有时候会经常需要调节图片的亮度,Matlab当然可以实现图像的亮度调节。
1、亮度转换的意思是直接对图像像素进行处理。用到的是一个非常简单的公式:
g(x,y)=T{f(x,y)};
其中f(x,y)代表的是原图像,x,y分别代表行数和列数。T代表队图像进行处理的操作符。代表的是一个简单的映射关系。
g=imadjust(f,[low_in,hing_in],[low_out,high_out],gamma)
这是专用于这项工作的函数,其中的亮度映射关系如下,
[low_in,high_in]----> [low_out,high_out]。gamma作用是调节权值。
依据刚刚三行代码你就可以实现以下操作
%图像亮度处理
warning off
f=imread('6.jpg');
subplot(2,2,1);
imshow(f);
g2=imadjust(f,[0;1],[1;0]);
subplot(2,2,2);imshow(g2);
g3=imadjust(f,[0;1],[0.5;0]);
subplot(2,2,3);imshow(g3);
g4=imadjust(f,[0;0.3],[1;0.4]);
subplot(2,2,4);imshow(g4);
五、线性滤波
空间滤波器可以去掉图像的噪声,处理被污染的图像,比较常见的是拉普拉斯滤波器,使用拉普拉斯滤波器增强图像的基本公式如下
其中倒三角表示拉普拉斯算子,比较复杂,这里只介绍它的计算过程,
%%线性空间滤波
f=imread('7.jpg');
h1=fspecial('laplacian',0);
g1=f-imfilter(f,h1);
h2=[1 1 1; 1 -8 1; 1 1 1];
g2=f-imfilter(f,h2);
subplot(1,3,1),imshow(f);title('原图');
subplot(1,3,2),imshow(g1);title('线性加噪');
subplot(1,3,3),imshow(g2);title('除噪');
在矩阵中进行的就是这样的运算。下面举一个例子,用滤波器对模糊图像进行修复。我们已经知道详细滤波空间可以用于添加噪声和去除噪声,在此过冷水给大家分享一点有难度系数的高阶应用。
过冷水身边的朋友经常反映自己将图片上传到网上一段时间后会发现图片出现噪点,有点不够很清晰。这是一件很烦的事情这就是因为图片被噪声污染了,当然可以成功降噪。
可以很明显的对比出来两幅图的噪声差别很大,这是因为添加噪声的方式不一样引起的,虽然都是应用的滤波方法,但是一个是线性滤波,一个是非线性滤波。
非线性滤波函数为g=ordfilt2(f,order,domain)。然鹅这个函数只能用于处理二维图片不可以处理三维图片,过冷水先给大家讲二维图片处理,然后用其他办法搞定三维的彩色图片。
其中g就是它的输出图像,它的原理非常简单,它可以生成统计排序滤波器,它的响应是基于对图像邻域包含的像素进行排序。然后用排序结果确定的值来代替邻域的中心像素的值。
其中order代表使用排序元素的第order个元素代替f中的每一个元素。而该邻域由domain中的非零元素指定。
比较有名的滤波叫做中值滤波。它对应的是第50个百分位。也就是像素点总和的一半。
语法如下:
g=ordfilt2(f,median(1:m*n),ones(m,n))
还有最小滤波器,对应第0个百分位。
语法如下:
g=ordfilt2(f,1,ones(m,n))
还有对应100个百分位的滤波器。也就是像素点总和。
g=ordfilt2(f,m*n,ones(m,n))
外中值滤波还有一个专用的工具箱
g=medfilts(f)
首先给大家讲讲简单的灰白图像的去噪问题。
clear
clc
f=imread('9.jpg'); %读原图像
f=rgb2gray(f);
f1=imnoise(f,'salt & pepper',0.09); %加椒盐噪声
g=medfilt2(f1); %进行中值滤波
subplot(1,3,1),imshow(f),title('原图像')
subplot(1,3,2),imshow(f1),title('被椒盐噪声污染的图像')
subplot(1,3,3),imshow(g),title('中值滤波图像')
该图像处理我们有进行灰度化转换,所以得到的图像自然是黑白图像,不想邪的读者可以尝试不进行灰度化处理看该程序能不能正常得到彩色图。从图像效果上来看人为污染和去噪效果很好的。But黑白图片并不能满足大家的学习需求,还是彩色照片的需求高一点,那么如何处理彩色图片,需要注意的是才是图片是三维矩阵 有三个颜色通道,只需要分别处理这三个颜色通道。然后组合在一起,彩色图片就自然解决掉了。
clear
clc
f=imread('8.jpg');
imshow(f)
f1=imnoise(f(:,:,1),'salt & pepper',0.09); %加椒盐噪声
f2=imnoise(f(:,:,2),'salt & pepper',0.09); %加椒盐噪声
f3=imnoise(f(:,:,3),'salt & pepper',0.09); %加椒盐噪声
f_noise(:,:,1)=f1;
f_noise(:,:,2)=f2;
f_noise(:,:,3)=f3;
imshow(f_noise)
g1=medfilt2(f1);%中值滤波
g2=medfilt2(f2);%中值滤波
g3=medfilt2(f3);%中值滤波
g_1(:,:,1)=g1;
g_1(:,:,2)=g2;
g_1(:,:,3)=g3;
subplot(1,3,1),imshow(f),title('原图像');
subplot(1,3,2),imshow(f_noise),title('添加椒盐噪声的图像');
subplot(1,3,3),imshow(g_1),title('处理以后的图像');
七、图像加密
在我们掌握了图像压缩、线性滤波、非线性滤波后我们就可以组合起来做点interesiting 的事,将图像的不清晰处理做到极致,实现图像的加密处理。如下图所示:
clear
A=imread('10.jpg');
subplot(2,2,1);imshow(A);title('原图')
[M,N]=size(A);%原始图像A的尺寸一MxN
u1=4;u2=4;x1(1)=0.2;x2(1)=0.7;
sumA=sum(sum(A));
k=mod(sumA,256)*1.0/255;
x1(1)=(x1(1) 0.7804)/2;x2(1)=(x2(1) 0.7809)/2;
y1(1)=(1/3.1415926)*asin(sqrt(x1(1)));
y2(1)=(1/3.1415926)*asin(sqrt(x2(1)));
for i=1:1:M*N-1 %产生2个Logistic混沌序列
x1(i 1)=u1*x1(i)*(1-x1(i));
x2(i 1)=u2*x2(i)*(1-x2(i));
end
for i=1:1:M*N %改造2个Logistic,得到两个y序列
y1(i)=(1/3.1415926)*asin(sqrt(x1(i)));
y2(i)=(1/3.1415926)*asin(sqrt(x2(i)));
end
n=1;
for i=1:1:M %由yl和y2序列对原图像进行值替代加密
for j=1:1:N
if mod(n,1)==0
k(n)=mod(floor(y1(n)*10^15),256);
else
k(n)=mod(floor(y2(n)*10^15),256);
end
A1(i,j)=bitxor(A(i,j),k(n)); %得到加密像素
n=n 1;
end
end
subplot(2,2,3);imshow(A1);title('混沌加密图像') %输出得到的加密图像
n=1;
for i=1:1:M
for j=1:1:N
if mod(n,1)==0
k(n)=mod(floor(y1(n)*10^15),256);
else
k(n)=mod(floor(y2(n)*10^15),256);
end
A2(i,j)=bitxor(A1(i,j),k(n)); %得到加密像素
n=n 1;
end
end
subplot(2,2,4);imshow(A2);title('解密图像') %输出得到的解密图像
我们成功做到了将图像变成马赛克,然后再恢复成图像,but和非线性滤波函数一样,处理后的图像变成了灰度图像,我们需要的是彩色图像,所以该方法不够完美,经过过冷水的摸索发现该方法只能化彩色为黑白,我们可以换一种方式来实现彩色图像的加密。
%彩色图像加密
img=imread('11.jpg');%img代表原图像矩阵
img(1,1,1)
img=double(img);
sizel=size(img)
img_1=img(:);%img_1代表拉直后的图像矩阵
password=[8,12,14,16,3,7,9];
vx=password
size(password);%密码的长和宽 =
k=1;
while x2<1000
p2=password*3
password=[password p2]
size(password) =
k=k 1
end
size(password) =
img_new=zeros(size(img));%新图像的矩阵
c1=zeros(size(img));
j=1;
for x=1:sizel(1)
for y=1:sizel(2)
for z=1:sizel(3)
img(x,y,z) password(j); =
mod(img_new(x,y,z),256); =
j=j 1;
if j==n
j=1;
end
end
end
end
%%图像解密
img=double(img_new);
j=1;
for x=1:sizel(1)
for y=1:sizel(2)
for z=1:sizel(3)
img(x,y,z)-password(j); =
mod(img_new(x,y,z),256); =
j=j 1;
if j==n
j=1;
end
end
end
end
subplot(1,3,3);imshow(uint8(img_new));title('解密图')
通过一些列的简单图像处理方式我们最终实现了数值图像处理中一个特别有意思的研究点——图像加密。
一想到图像加密正如过冷水之前说的,有些东西平常你不想让人看见,比如说一些学习资料图片,你就可以日常加密。有需要的时候再解密,当然图像加密解密用在这种地方会显得肤浅,具体深入应用还的依靠图像研究者的摸索解释,我们才知道原来还可以这样用。
以上就是过冷水老师本期推荐的文章,与大家分享的Matlab六大图像处理技巧,希望能够对大家有所帮助。
作者:过冷水 Matlab电化学博士 仿真秀专栏作者
声明:原创文章,如有不当请联系我们,欢迎分享,禁止私自转载,转载请联系我们。欢迎向我投稿,我们向你支付满意稿酬和尊重署名权等。