目錄
實驗描述
設(shè)計思路
功能模塊?編輯
基礎(chǔ)界面?編輯
開發(fā)工具
基礎(chǔ)功能
最重要的全局變量(寫在前面)
導(dǎo)入圖片
從攝像頭獲取照片
彩色圖像灰度化
灰度圖像二值化
兩幅圖像疊加
目標檢測(兩幅圖像相減)
圖像灰度變換(指數(shù)變換、對數(shù)變換)
顯示原圖像直方圖和將原圖像直方圖均衡化(寫在一起)
添加高斯噪聲和椒鹽噪聲
均值濾波器、中值濾波器、高斯濾波器濾波處
采用robert和二階算子提取圖像邊
平滑處理和提取邊緣
運動模糊,并進行圖像復(fù)原處理
腐蝕、膨脹、開運算、閉運算
提取紅蘋果
硬幣檢測及計數(shù)
檢測圓和矩形
?一些些創(chuàng)新功能
返回上一步
水平翻轉(zhuǎn)
垂直翻轉(zhuǎn)?
角度旋轉(zhuǎn)?
相對亮度
?銳化
實驗總結(jié)
參考資料(只能找到當時看的一些了)
-
實驗描述
本文章是基于MATLAB數(shù)字圖像處理課程的結(jié)課作業(yè),利用MATLAB設(shè)計了可視化界面進行基礎(chǔ)版圖像處理,其中功能包括作業(yè)要求的功能,額外還設(shè)計了一些創(chuàng)新功能,包括但不限于相對亮度調(diào)整、返回上一步等。其中內(nèi)容多來自于課程內(nèi)容和上網(wǎng)查詢資料獲取到的內(nèi)容的融會貫通,通過本次實驗,完成了圖像處理app的實現(xiàn)可以進行簡單的圖像處理,以及特殊功能檢測。
-
設(shè)計思路
-
功能模塊
-
基礎(chǔ)界面
-
開發(fā)工具
MATLAB R2021a App Designer
-
基礎(chǔ)功能
-
最重要的全局變量(寫在前面)
properties (Access = private)
originalpicture; % Description
lastpicture;
changedpicture;
changedpicture2;
upgradepicture;
D0;
end
-
導(dǎo)入圖片
函數(shù)uigetfile()打開文件選擇對話框,選擇文件,返回文件名和文件路徑。有了文件名和文件路徑后讀文件函數(shù)讀取相應(yīng)的文件,將返回的文件路徑和文件名賦給圖片,使用imshow將其顯示在界面指定位置上。如果未選擇文件則彈出窗口,顯示提醒未選擇圖片,然后返回圖像界面。
[filename,pathname] = uigetfile({'*.jpg';'*.bmp';'*.*'},'選擇圖片');
if isequal(filename,0)||isequal(pathname,0)
msgbox('您未選擇圖片','溫馨提示','help');
return;
else
x=strcat(pathname,filename);
app.originalpicture=imread(x);
imshow(app.originalpicture,'Parent',app.UIAxes1);
app.lastpicture=app.originalpicture;
app.changedpicture=app.originalpicture;
end
?
?若不選擇圖像,點擊取消的話會彈出提醒窗口
-
從攝像頭獲取照片
使用videoinput函數(shù)生成窗口對象并同步畫面。利用函數(shù)獲取圖片的幀,當關(guān)閉窗口時,將關(guān)閉窗口時的截取圖像顯示在規(guī)定的坐標中。
obj = videoinput('winvideo',1);
h=preview(obj);
while ishandle(h)
app.originalpicture = getsnapshot(obj); % 獲取幀
app.changedpicture=app.originalpicture;
imshow(app.originalpicture,'Parent',app.UIAxes1);
title(app.UIAxes1,'原始圖片');
drawnow
end
?
-
彩色圖像灰度化
利用im2gray()函數(shù)將彩色影像RGB轉(zhuǎn)換成灰度影像Grayscale,由im2gray創(chuàng)建的灰度圖像是一個由強度值組成的單一平面。im2gray函數(shù)將RGB值轉(zhuǎn)換為灰度值,將R、G、B分量加權(quán)和:0.2989*R+0.5870*G+0.1140*B。
if isequal(app.originalpicture,'')
msgbox('無圖片','提示',"help");
else
gray=im2gray(app.originalpicture);
app.lastpicture=app.changedpicture;
imshow(gray,'Parent',app.UIAxes2);
app.changedpicture=gray;
end
-
灰度圖像二值化
函數(shù)im2bw使用閾值(threshold)變換法把灰度圖像(grayscale image)轉(zhuǎn)換成二值圖像。所謂二值圖像, 一般意義上是指只有純黑(0)、純白(255)兩種顏色的圖像。BW = im2bw(I,level),其將灰度圖像 I 轉(zhuǎn)換為二進制圖像。輸出圖像 BW 將輸入圖像中亮度值大于 level 的像素替換為值1 (白色),其他替換為值0(黑色)。你指定 level 在 [0,1]之間,不用管輸入圖像的等級。函數(shù)graythresh 能用來自動計算變量 level 。如果你不指定 level ,im2bw 使用 0.5。
if isequal(app.originalpicture,'')
msgbox('無圖片','提示',"help");
else
black=im2bw(app.originalpicture);
app.lastpicture=app.changedpicture;
imshow(black,'Parent',app.UIAxes2);
app.changedpicture=black;
end
?
-
兩幅圖像疊加
進行兩幅圖像的加法,或者給一幅圖像加上一個常數(shù),可以調(diào)用imadd函數(shù)來實現(xiàn)。imadd函數(shù)將某一幅輸入圖像的每一個像素值與另一幅圖像相應(yīng)的像素值相加,返回相應(yīng)的像素值之和作為輸出圖像。Z = imadd(X,Y),其中,X和Y表示需要相加的兩幅圖像,返回值Z表示得到的加法操作結(jié)果。
[filename,pathname] = uigetfile({'*.jpg';'*.bmp';'*.*'},'選擇圖片');
if isequal(filename,0)||isequal(pathname,0)
msgbox('您未選擇圖片','溫馨提示','help');
return;
else
x=strcat(pathname,filename);
addpic=imread(x);
imshow(addpic,'Parent',app.UIAxes2);
end
result=imadd(app.originalpicture,addpic);
imshow(result,'Parent',app.UIAxes3);
-
目標檢測(兩幅圖像相減)
圖像減法也稱為差分方法,是一種常用于檢測圖像變化及運動物體的圖像處理方法。imsubtract函數(shù)可以將一幅圖像從另一幅圖像中減去,或者從一幅圖像中減去一個常數(shù)。imsubtract函數(shù)將一幅輸入圖像的像素值從另一幅輸入圖像相應(yīng)的像素值中減去,再將這個結(jié)果作為輸出圖像相應(yīng)的像素值。Z = imsubtract(X,Y),其中,Z是X-Y操作的結(jié)果。以下代碼首先根據(jù)原始圖像生成其背景亮度圖像,然后再從原始圖像中將背景亮度圖像減去,從而生成減去后的圖像。
[filename,pathname] = uigetfile({'*.jpg';'*.bmp';'*.*'},'選擇圖片');
if isequal(filename,0)||isequal(pathname,0)
msgbox('您未選擇圖片','溫馨提示','help');
return;
else
x=strcat(pathname,filename);
targetpic=imread(x);
imshow(targetpic,'Parent',app.UIAxes2);
end
result=imabsdiff(targetpic,app.originalpicture);
imshow(result,'Parent',app.UIAxes3);
app.changedpicture=result;
圖像的相減可以用來檢測兩幅圖中不同的部分,檢測圖像之間的差異,增強細節(jié),也可以用于一幅圖像減去像素值,使圖片變暗。但需要注意的是,相減的兩幅圖像尺寸應(yīng)該相同。
-
圖像灰度變換(指數(shù)變換、對數(shù)變換)
采用log函數(shù)進行對數(shù)變換(參數(shù)值必須為double類型),用im2uint8()函數(shù)將灰度圖像轉(zhuǎn)換為8位圖,可視化顯示新生成的圖。指數(shù)變換能增強圖像中亮區(qū)域的細節(jié)(對比度提高),同時弱化圖像中暗區(qū)域的細節(jié)(對比度降低)。
%指數(shù)變換
app.lastpicture=app.changedpicture;
if isequal(app.originalpicture,'')
msgbox('無圖片','提示',"help");
else
if (ndims(app.originalpicture)==3)
app.originalpicture=rgb2gray(app.originalpicture);
end
A1 = double(app.originalpicture);
A2 = 1.5.^(A1*0.070)-1;
A2 = uint8(A2);
imshow(A2,'Parent',app.UIAxes2);
app.changedpicture=A2;
%對數(shù)變換
app.lastpicture=app.changedpicture;
if isequal(app.originalpicture,'')
msgbox('無圖片','提示',"help");
else
if (ndims(app.originalpicture)==3)
app.originalpicture=rgb2gray(app.originalpicture);
end
h=log(1+double(app.originalpicture));
h=mat2gray(h);
h=im2uint8(h);
imshow(h,'Parent',app.UIAxes2);
app.changedpicture=h;
end
(指數(shù))
(對數(shù))
指數(shù)變換能增強圖像中亮區(qū)域的細節(jié)(對比度提高),同時弱化圖像中暗區(qū)域的細節(jié)(對比度降低),而對數(shù)變換可以增強低灰度,減弱高灰度值。
-
顯示原圖像直方圖和將原圖像直方圖均衡化(寫在一起)
圖像的直方圖事實上就是圖像的亮度分布的概率密度函數(shù),是一幅圖像的所有象素集合的最基本的統(tǒng)計規(guī)律。直方圖反映了圖像的明暗分布規(guī)律,可以通過圖像變換進行直方圖調(diào)整,獲得較好的視覺效果。直方圖均衡化是通過灰度變換將一幅圖像轉(zhuǎn)換為另一幅具有均衡直方圖,即在每個灰度級上都具有相同的象素點數(shù)的過程。使用imhist函數(shù)顯示直方圖。
if isequal(app.originalpicture,'')
msgbox('無圖片','提示',"help");
elseif isequal(app.changedpicture,'')
msgbox('圖片未處理','提示',"help");
else
subplot(231),imhist(im2gray(app.originalpicture)),title('原始圖像直方圖');
subplot(232),imhist(im2gray(app.changedpicture)),title('處理圖像直方圖');
subplot(233),imhist(im2gray(app.changedpicture2)),title('二次處理直方圖');
end
直方圖均衡化的目的是使圖像在整個灰度值動態(tài)變化范圍內(nèi)的分布均勻化,改善圖像的亮度分布狀態(tài),增強圖像的視覺效果。直方圖均衡化是通過灰度變換將一幅圖像轉(zhuǎn)換為另一幅具有均衡直方圖,即在每個灰度級上都具有相同的象素點數(shù)的過程。用histeq()函數(shù)對圖像進行均衡化,均衡化后圖像的直方圖可以修改灰度級數(shù)量。
if isequal(app.originalpicture,'')
msgbox('無圖片','提示',"help");
elseif isequal(app.changedpicture,'')
msgbox('圖片未處理','提示',"help");
else
hist1=histeq(im2gray(app.originalpicture));
hist2=histeq(im2gray(app.changedpicture));
hist3=histeq(im2gray(app.changedpicture2));
subplot(234),imhist(hist1),title('原始圖像直方圖');
subplot(235),imhist(hist2),title('處理圖像直方圖');
subplot(236),imhist(hist3),title('二次處理直方圖');
end
灰度直方圖反映了圖像中各灰度值出現(xiàn)的頻數(shù),根據(jù)灰度值分布的范圍和均勻程度,就可以判斷出該圖像曝光是否合適。
圖像直方圖均衡化,是指尋找一個灰度變換函數(shù),使變換后圖像的像素值占有全部的灰度級并且分布均勻,從而得到一幅灰度級豐富且動態(tài)范圍大的圖像。
-
添加高斯噪聲和椒鹽噪聲
imnoise 是表示添加噪聲污染一幅圖像,叫做噪聲污染圖像函數(shù)。利用imnoise 命令在圖像上加入高斯(gaussian) 噪聲,高斯噪聲即呈正態(tài)分布的干擾噪聲,用作增加光譜的擾動或圖像的干擾。利用imnoise 命令在圖像上加入椒鹽噪聲(salt & pepper)。椒鹽噪聲也稱為脈沖噪聲,是圖像中經(jīng)常見到的?種噪聲,它是?種隨機出現(xiàn)的?點或者?點,可能是亮的區(qū)域有??像素或是在暗的區(qū)域有??像素(或是兩者皆有)。
%高斯噪聲
changingValue = event.Value;
app.lastpicture=app.changedpicture;
if isequal(app.originalpicture, '')
msgbox("無圖片",'warning','help');
return;
else
Image=app.originalpicture;
noisepic=imnoise(Image,'gaussian',changingValue);
imshow(noisepic,'Parent',app.UIAxes2);
app.changedpicture=noisepic;
end
%椒鹽噪聲
changingValue = event.Value;
app.lastpicture=app.changedpicture;
if isequal(app.originalpicture, '')
msgbox("無圖片",'warning','help');
return;
else
Image=app.originalpicture;
noisepic=imnoise(Image,'salt & pepper',changingValue);
imshow(noisepic,'Parent',app.UIAxes2);
app.changedpicture=noisepic;
end
(高斯噪聲)
(椒鹽噪聲)?
高斯噪聲在每個像素上都會出現(xiàn),賦值服從高斯分布。椒鹽噪聲出現(xiàn)位置隨機,所以可以控制椒鹽噪聲的密度,椒鹽噪聲的幅度確定,椒噪聲偏暗,鹽噪聲偏亮。
-
均值濾波器、中值濾波器、高斯濾波器濾波處
把模板運算運用于圖像的空間域增強的技術(shù)稱為空間域濾波。這三個濾波器主要是對于添加了噪聲以后的圖像進行依據(jù)濾波頻率空間域濾波,平滑濾波(減弱和去除高頻分量),分別采用不同大小的模板,分別用均值濾波器、中值濾波器以及高斯濾波器,對加入噪聲的圖像進行處理并觀察不同噪聲水平下不同濾波器處理的結(jié)果。線性濾波器的原始數(shù)據(jù)與濾波結(jié)果是一種算術(shù)運算,即用加減乘除等運算實現(xiàn),如均值濾波器、高斯濾波器等。非線性濾波器的原始數(shù)據(jù)與濾波結(jié)果是一種邏輯關(guān)系,也就是用邏輯運算來實現(xiàn)的,比如中值濾波器等,是通過比較一定鄰域內(nèi)的灰度值大小來實現(xiàn)的。
%均值濾波器
changingValue = event.Value;
app.lastpicture=app.changedpicture;
noisepic=app.changedpicture;
h=fspecial('average',changingValue);
reuslt = imfilter(noisepic,h);
imshow(reuslt,'Parent',app.UIAxes3);
app.changedpicture2=reuslt;
%中值濾波器
value = app.Spinner_4.Value;
app.lastpicture=app.changedpicture;
noisepic=app.changedpicture;
if (ndims(noisepic)==3)
noisepic=rgb2gray(noisepic);
end
result=medfilt2(noisepic,[value value]);
imshow(result,'Parent',app.UIAxes3);
%高斯濾波器
value = app.Spinner_5.Value;
app.lastpicture=app.changedpicture;
noisepic=app.changedpicture;
result=imgaussfilt(noisepic,[value value]);
imshow(result,'Parent',app.UIAxes3);
app.changedpicture2=result;
(均值濾波器)
(高斯濾波器)
(中值濾波器)
?中值濾波器、均值濾波器、高斯濾波器可以去除圖像的噪聲,使圖像變得模糊。尤其中值濾波對椒鹽噪聲的處理效果格外好,不但是也需要選取合適的參數(shù)。
-
采用robert和二階算子提取圖像邊
邊緣檢測首先檢測出圖像局部不連續(xù)性,然后將這些不連續(xù)的邊緣像素連成完備的邊界。邊緣的特性是沿邊緣走向的像素變化平緩,而垂直于邊緣方向的像素變化劇烈。所以,從這個意義上說,提取邊緣的算法就是檢出符合邊緣特性的邊緣像素的數(shù)學(xué)算子。
把模板運算運用于圖像的空間域增強的技術(shù)稱為空間域濾波。依據(jù)濾波頻率空間域濾波的銳化濾波,即減弱和去除低頻分量。采用Roberts算子,LoG算子分別進行圖像銳化。Roberts算子涉及絕對值運算,直接遍歷所有點求出其近似梯度幅值。高斯-拉普拉斯算子(Laplacian of a Gaussian)簡稱LoG算子,也稱為Marr邊緣檢測算子。應(yīng)用LoG算子時,高斯函數(shù)中標準差參數(shù)σ的選擇很關(guān)鍵,對圖像邊緣檢測效果有很大的影響,對于不同圖像應(yīng)選擇不同參數(shù)。
%Roberts算子
value = app.RobertsSlider.Value;
value1=value./255;
app.lastpicture=app.changedpicture;
if isequal(app.originalpicture, '')
msgbox("無圖片",'warning','help');
return;
else
I=im2gray(app.originalpicture);
J = edge(I, 'Roberts', value1);
imshow(J,'Parent',app.UIAxes2);
app.changedpicture=J;
End
%二階算子(log)
value = app.Slider_4.Value;
value1 = value./255;
app.lastpicture=app.changedpicture;
if isequal(app.originalpicture, '')
msgbox("無圖片",'warning','help');
return;
else
I=im2gray(app.originalpicture);
J=edge(I,'log',value1);
imshow(J,'Parent',app.UIAxes2);
app.changedpicture=J;
end
?
(Roberts算子)
(二階算子log)
通過調(diào)節(jié)不同參數(shù)發(fā)現(xiàn),二階算子在參數(shù)比較小是效果較好,對參數(shù)的變化很敏感,稍微大一點就無法檢測邊緣,而Roberts算子檢測邊緣時噪聲比二階算子更多,不過我還是認為Roberts算子更適合用于檢測邊緣。
-
平滑處理和提取邊緣
頻域濾波分為低通濾波和高通濾波兩類,對應(yīng)的濾波器分別為低通濾波器和高通濾波器。
低通濾波器實質(zhì)上就是對圖像進行平滑處理。低通濾波器包括:理想低通濾波器、n階巴特沃茲低通濾波器、高斯低通濾波器。頻域低通過濾的基本思想:G(u,v)=F(u,v)H(u,v)。F(u,v)是需要鈍化圖像的傅立葉變換形式,H(u,v)是選取的一個低通過濾器變換函數(shù),G(u,v)是通過H(u,v)減少F(u,v)的高頻部分來得到的結(jié)果,運用傅立葉逆變換得到鈍化后的圖像。
高通濾波器實質(zhì)上就是對圖像進行邊緣提?。ㄤJ化處理)。相應(yīng)的高通濾波器也包括:理想高通濾波器、n階巴特沃茲高通濾波器、高斯高通濾波器。相應(yīng)高通濾波器的傳遞函數(shù):。?
頻域濾波最重要的點是指定的非負數(shù)D0的的值的選取。這決定了濾波以后的效果。
——————————平滑處理(低通濾波器)————————————————
%理想低通濾波器
s=fftshift(fft2(im2double(app.originalpicture)));%傅里葉變換
if(ndims(s)==3)
s=rgb2gray(s);
end
[m,n]=size(s);
m0=round(m/2);
n0=round(n/2);
for i=1:m %雙重for循環(huán)計算頻率點(i,j)與頻域中心的距離 D(i,j)=sqrt((i-round(m/2)^2+(j-round(n/2)^2))
for j=1:n
L=sqrt((i-m0)^2+(j-n0)^2);
if L<=app.D0
%根據(jù)理想低通濾波器產(chǎn)生公式,當D(i,j)<=D0,置為1
h=1;
else
h=0;
%根據(jù)理想低通濾波器產(chǎn)生公式,當D(i,j)>D0,置為0
end
s1(i,j)=h*s(i,j);%頻域圖像乘以濾波器的系數(shù)
end
end
s1=real(ifft2(ifftshift(s1)));
%最后進行二維傅里葉反變換轉(zhuǎn)換為時域圖像
subplot(2,3,1),imshow(s1,[]),title('理想低通濾波器');
%巴特沃斯低通濾波器
I=im2double(app.originalpicture);
if(ndims(I)==3)
I=rgb2gray(I);
end
M=2*size(I,1);
N=2*size(I,2);
u=-M/2:(M/2-1);
v=-N/2:(N/2-1);
[U,V]=meshgrid(u,v);
D=sqrt(U.^2+V.^2);
n=6;
H1=1./(1+(D./app.D0).^(2*n));
J1=fftshift(fft2(I,size(H1,1),size(H1,2)));
K1=J1.*H1;
L1=ifft2(ifftshift(K1));
L1=L1(1:size(I,1),1:size(I,2));
subplot(232);imshow(L1),title('巴特沃斯低通濾波器');
%高斯低通濾波器
s=fftshift(fft2(im2double(app.originalpicture)));
if(ndims(s)==3)
s=rgb2gray(s);
end
[m,n]=size(s);
m0=round(m/2);
n0=round(n/2);
for i=1:m
for j=1:n
L=sqrt((i-m0)^2+(j-n0)^2); %根據(jù)高斯低通濾波器公式H(u,v)=e^-[D^2(u,v)/(2*D0^2)]
h=exp(-(L*L)/(2*(app.D0^2))); %exp表示以e為底的指數(shù)函數(shù)
s0(i,j)=h*s(i,j);%頻域圖像乘以濾波器的系數(shù)
end
end
s=real(ifft2(ifftshift(s0)));%最后進行二維傅里葉反變換轉(zhuǎn)換為時域圖像
subplot(233),imshow(s),title('高斯低通濾波器');
——————————————————提取邊緣(高通濾波器)——————————————————
%理想低通濾波器
s=fftshift(fft2(im2double(app.originalpicture)));%傅里葉變換
if(ndims(s)==3)
s=rgb2gray(s);
end
[m,n]=size(s);
m0=round(m/2);
n0=round(n/2);
%將理想高通濾波器的截止頻率D0設(shè)置為5
for i=1:m %雙重for循環(huán)計算頻率點(i,j)與頻域中心的距離 D(i,j)=sqrt((i-round(m/2)^2+(j-round(n/2)^2))
for j=1:n
L=sqrt((i-m0)^2+(j-n0)^2);
if L<=app.D0
%根據(jù)理想高通濾波器產(chǎn)生公式,當D(i,j)<=D0,置為0
h=0;
else
h=1;
%根據(jù)理想高通濾波器產(chǎn)生公式,當D(i,j)>D0,置為1
end
s(i,j)=h*s(i,j);%頻域圖像乘以濾波器的系數(shù)
end
end
%real函數(shù)取元素的實部
s=real(ifft2(ifftshift(s)));
%最后進行二維傅里葉反變換轉(zhuǎn)換為時域圖像
subplot(234),imshow(s),title('理想高通濾波器');
%巴特沃斯低通濾波器
I=im2double(app.originalpicture);
if(ndims(I)==3)
I=rgb2gray(I);
end
M=2*size(I,1);
N=2*size(I,2);
u=-M/2:(M/2-1);
v=-N/2:(N/2-1);
[U,V]=meshgrid(u,v);
D=sqrt(U.^2+V.^2);
n=6;
h=1-1./(1+(D./app.D0).^(2*n));
j=fftshift(fft2(I,size(h,1),size(h,2)));
k=j.*h;
L=ifft2(ifftshift(k));
L=L(1:size(I,1),1:size(I,2));
subplot(235);imshow(L),title('巴特沃斯高通濾波器');
%高斯低通濾波器
s=fftshift(fft2(im2double(app.originalpicture)));
if(ndims(s)==3)
s=rgb2gray(s);
end
[m,n]=size(s);
m0=round(m/2);
n0=round(n/2);
for i=1:m
for j=1:n
L=sqrt((i-m0)^2+(j-n0)^2); %根據(jù)高斯低通濾波器公式 H(u,v)=e^-[D^2(u,v)/(2*D0^2)]
h=1-exp(-(L*L)/(2*(app.D0^2)));
%exp表示以e為底的指數(shù)函數(shù)
s0(i,j)=h*s(i,j);%頻域圖像乘以濾波器的系數(shù)
end
end
s=real(ifft2(ifftshift(s0)));
%最后進行二維傅里葉反變換轉(zhuǎn)換為時域圖像
subplot(236),imshow(s),title('高斯高通濾波器');
?低通濾波器對圖像進行平滑處理,高通濾波器對圖像邊緣進行提取,濾波器高通和低通的運算效果對比,高通和低通傳遞函數(shù)H(u,v)的互補,同時并非D0值越大濾波效果更好。
-
運動模糊,并進行圖像復(fù)原處理
fspecial函數(shù)用于創(chuàng)建濾波器,imfilter函數(shù),對影像進行濾波處理:h = fspecial('motion',len,theta),返回一個過濾器,使其在與圖像卷積后近似相機的線性運動。len指定運動的長度,theta指定逆時針方向的運動角度(以度為單位)。過濾器將成為水平和垂直運動的矢量。len是20,默認的theta是30,這對應(yīng)于20個像素的水平運動。J = deconvwnr(I,psf,nsr),使用維納濾波算法對圖像I進行解卷積,返回去模糊圖像J。psf是對I進行卷積的點擴展函數(shù)(psf)。nsr是加性噪聲的噪聲與信號功率比。
————————運動模糊————————————
if isequal(app.originalpicture,'')
msgbox('無圖片','提示',"help");
return;
else
app.lastpicture=app.changedpicture;
%app.originalpicture=rgb2gray(app.originalpicture);
app.originalpicture=im2double(app.originalpicture);
len=20;
theta=30;
PSF=fspecial('motion',len,theta);%產(chǎn)生PSF obscureway1=imfilter(app.originalpicture,PSF,'conv','circular');
imshow(obscureway1,'Parent',app.UIAxes2);
app.changedpicture=obscureway1;
app.upgradepicture=obscureway1;
——————————————圖像復(fù)原————————————
if isequal(app.originalpicture,'')
msgbox('無圖片','提示',"help");
return;
else
app.lastpicture=app.changedpicture;
len=20;
theta=30;
PSF=fspecial('motion',len,theta);%產(chǎn)生PSF
NSR = 0;
recoverpic = deconvwnr(app.upgradepicture,PSF,NSR);
%維納濾波復(fù)原
imshow(recoverpic,'Parent',app.UIAxes3);
end
?對于運動模糊和復(fù)原,效果最好的時候是模糊和復(fù)原參數(shù)數(shù)值相同的時候,維納濾波復(fù)原在估計圖像和真實圖像之間的最小均方誤差意義下是最優(yōu)的.
-
腐蝕、膨脹、開運算、閉運算
膨脹:對邊界點進行擴充,填充空洞,使邊界向外部擴張的過程。
腐蝕:消除物體邊界點,使邊界向內(nèi)部收縮的過程,把小于結(jié)構(gòu)元素的物體去除掉。
開運算:?先腐蝕后膨脹的過程稱為開運算,作用:去除孤立的小點,毛刺,消除小物體,平滑較大物體邊界,同時不改變其面積。
閉運算:先膨脹后腐蝕的過程是閉運算。作用:填充物體內(nèi)細小的空洞,連接臨近物體,平滑邊界,同時不改變其面積。其中,對灰度圖像的腐蝕相等于對灰度圖像變暗;對灰度圖像的膨脹(閉運算)相等于對灰度圖像變亮。
————————————膨脹——————————
SE = strel('diamond',3);
if isequal(app.originalpicture,'')
msgbox('無圖片','提示',"help");
return;
else
result1=imdilate(app.originalpicture,SE);
%膨脹灰度圖像result1=imdilate(Image,se);%膨脹灰度圖像
subplot(221),imshow(result1),title('膨脹');
end
——————————————腐蝕——————————————
SE = strel('diamond',3);
if isequal(app.originalpicture,'')
msgbox('無圖片','提示',"help");
return;
else
result2=imerode(app.originalpicture,SE);
%腐蝕灰度圖像result1=imdilate(Image,se);%膨脹灰度圖像
subplot(222),imshow(result2),title('腐蝕');
end
————————————開運算————————————
SE = strel('diamond',3);
if isequal(app.originalpicture,'')
msgbox('無圖片','提示',"help");
return;
else
result3=imopen(app.originalpicture,SE);
%開運算灰度圖像result1=imdilate(Image,se);%膨脹灰度圖像
subplot(223),imshow(result3),title('開運算');
end
————————————閉運算————————————————
SE = strel('diamond',3);
if isequal(app.originalpicture,'')
msgbox('無圖片','提示',"help");
return;
else
result4=imclose(app.originalpicture,SE);
%閉運算灰度圖像result1=imdilate(Image,se);%膨脹灰度圖像
subplot(224),imshow(result4),title('閉運算');
end
?基于灰度圖像的各種操作,對圖像進行腐蝕后,圖像變暗,亮細節(jié)被削弱,因為亮的區(qū)域被縮小了,反之,對圖像進行膨脹,使較亮的局部區(qū)域被擴大了,而較暗的區(qū)域被變小了,圖像整體變得更亮。相同的是,進行膨脹腐蝕操作后都會使圖像變得模糊。
-
提取紅蘋果
將圖像從rgb轉(zhuǎn)換為hsv,提取圖中紅色的部分。遍歷圖像所有像素,不是紅色的像素變成黑的像素(R=G=B=0)。圖像還是有許多噪聲的,可采用數(shù)學(xué)形態(tài)學(xué)的方法除去噪聲。對圖像進行開運算處理,可去除非常小或窄的像素,用MATLAB內(nèi)置函數(shù)先進行腐蝕再進行膨脹,完成開運算。形態(tài)學(xué)處理盡量去除小的孔洞。
app.lastpicture=app.changedpicture;
hsv=rgb2hsv(app.originalpicture);
h=hsv(:,:,1);
h(h>330/360)=0;
training=h(:);
startdata = [0;60/360;120/360;180/360;240/360;300/360];
[IDX,C]= kmeans(training,6,'Start',startdata);
idbw = (IDX == 1);
template = reshape(idbw, size(h));%重新排列矩陣
SE = strel('diamond',3);
result=imopen(template,SE);
imshow(result,'Parent',app.UIAxes2);
app.changedpicture=result;
通過多組實驗圖片結(jié)果對比,該算法對紅色蘋果可以實現(xiàn)大致的提取,但會有很多小的噪點無法消除或者是將非紅色部分錯誤提取,也對一些顏色較深的顏色無法進行判斷,同時這個算法的本質(zhì)是對紅色進行檢驗提取,所以對蘋果的形狀無法保證,蘋果自身產(chǎn)生的黑色陰影也會導(dǎo)致被賦為黑色。
-
硬幣檢測及計數(shù)
將圖像轉(zhuǎn)化成灰度圖,灰度圖二值化成黑白的,以顏色值99作為分界線,灰度圖中顏色值大于等于99的將變?yōu)?,小于99的變?yōu)?,消除噪點,使統(tǒng)計更準確,經(jīng)過初步除噪后,仍然還有幾個小的噪點,選擇合適的結(jié)構(gòu)袁術(shù)進行腐蝕和膨脹。經(jīng)過去除噪點后,每一個硬幣都已經(jīng)成為了一個單獨的圖像區(qū),bwlabel(BW)就是用來對二維二值圖像中的連通分量進行標注的,即在BW中找到的連通對象的數(shù)量并返回,最后得出的就是計數(shù)后的結(jié)果使用消息框彈出。
app.lastpicture=app.changedpicture;
if ndims(app.originalpicture)==3
I_gray=rgb2gray(app.originalpicture);
end
%轉(zhuǎn)換為灰度圖
BW=I_gray>99;%二值化(重點為確定閾值)
% 去除噪聲
I_gray1=imfill(BW,'holes');%填充空洞 消除噪點
imshow(BW,'Parent',app.UIAxes2);
SE = strel('disk',4,4);
%確定半徑(此處半徑可自行調(diào)整,主要應(yīng)用于后面的膨脹和腐蝕中)
SE1 = strel('octagon',9);
%確定半徑(此處半徑可自行調(diào)整,主要應(yīng)用于后面的膨脹和腐蝕中)
I_gray2=imerode(I_gray1,SE);%腐蝕
I_gray3=imdilate(I_gray2,SE);%膨脹
I_gray4=imerode(I_gray3,SE1);%腐蝕
imshow(I_gray4,'Parent',app.UIAxes3);
%計算硬幣數(shù)量
[L,n] = bwlabel(I_gray4);%n為硬幣數(shù)目
S=sprintf('檢測到的硬幣個數(shù)為:%d',n);
msgbox(S);%彈窗顯示運行結(jié)果
app.changedpicture=I_gray4
?
本算法實現(xiàn)對硬幣的提取是建立在硬幣圖像平鋪且不連通的情況下,對圖片的要求較高,如果硬幣連通,膨脹腐蝕操作無法將硬幣單獨提取,就會使結(jié)果不準確。對于挨得較近的硬幣圖像,在腐蝕的時候要選擇腐蝕程度大的結(jié)構(gòu)元素,將硬幣區(qū)域區(qū)分出來才能更好計數(shù)。并且在選擇檢驗圖片的時候要選擇背景深的圖片,因為這個算法檢測的是白色連通區(qū)域,如果背景淺色,二值化填充孔洞會將整幅圖填充為白色,檢測出硬幣個數(shù)永遠為1。
-
檢測圓和矩形
將其轉(zhuǎn)為灰度圖像處理,即不利用顏色特征,通過分割,并基于形狀特征實現(xiàn)圓和矩形的檢測。矩形檢測:從理論上看,矩形連通區(qū)域與其最小邊界矩形的像素比是1,所以可自定義設(shè)置閾值大于0.95判斷。圓形檢測:從理論上看,設(shè)圓形半徑為R,最小邊界矩形即正方形邊長為2R,圓形連通區(qū)域與其最小邊界矩形的面積比為0.7854,所以可自定義二值化設(shè)置閾值介于[ 0.76 , 0.80 ]判斷。
if ndims(app.originalpicture)==3
app.originalpicture=rgb2gray(app.originalpicture);
end
binary_img=1-im2bw(app.originalpicture,0.73);
%灰度圖轉(zhuǎn)換成二值圖像,直接進行灰度反轉(zhuǎn),讓圖形區(qū)域置1
for i=202:265
binary_img(188,i)=1;
end
fill_hole=imfill(binary_img,'holes');
fill_hole=bwareaopen(fill_hole,10);
[B,L]=bwboundaries(fill_hole,'noholes');
out_result=regionprops(fill_hole,'Extent','Centroid','boundingbox');
%Extent:各連通區(qū)域像素點與最小邊界像素點比值
centroids = cat(1, out_result.Centroid); %各連通區(qū)域質(zhì)心
draw_rect=cat(1,out_result.BoundingBox); %各連通區(qū)域最小邊界矩形
figure;
subplot(2,2,1);imshow(app.originalpicture,[]);title('原圖');
subplot(2,2,2);imshow(binary_img,[]);title('二值化');
subplot(2,2,3);imshow(fill_hole,[]);title('區(qū)域填充');
subplot(2,2,4);imshow(fill_hole,[]);title('圓和矩形檢測');
for i=1:size(out_result)
rectangle('position',draw_rect(i,:),'EdgeColor','y','LineWidth',2);
%繪出各連通區(qū)域最小邊界矩形
if out_result(i).Extent>0.95
text(centroids(i,1)-20, centroids(i,2)-10,'矩形 ','Color','b','FontSize',9);
elseif out_result(i).Extent>0.76&&out_result(i).Extent<0.80
text(centroids(i,1)-20, centroids(i,2)-10,'圓形 ','Color','b','FontSize',9);
end
end
?
?矩形和圓形檢測的這個算法要求檢測的形狀和背景有強烈的對比度,若對比不明顯,會使檢測是圖像不完整,從而檢測不到完整的圖像,產(chǎn)生錯誤的結(jié)果,并且這個算法只對這張圖片有效,并不是對所有的圖形都可以。(這張圖片中最后一個矩形原是淺黃色,然后檢測不出來......所以我去調(diào)了個色,把黃色變成了橘色...這個算法可以實現(xiàn),但是沒完全實現(xiàn))
-
?一些些創(chuàng)新功能
—————————(這個就沒有介紹了,大多(全部)也是借鑒很多大佬的)————————
-
返回上一步
function Button_3Pushed(app, event)
if isequal(app.lastpicture,'')
msgbox('無上一步','溫馨提示','help');
return;
else
imshow(app.lastpicture,"Parent",app.UIAxes2);
end
end
進行操作以后返回上一步,未進行操作時顯示無上一步
-
水平翻轉(zhuǎn)
app.lastpicture=app.changedpicture;
if isequal(app.originalpicture, '')
msgbox("無圖片",'warning','help');
return;
else
levelpic=flip(app.changedpicture,2);
imshow(levelpic,'Parent',app.UIAxes2);
app.changedpicture=levelpic;
End
-
垂直翻轉(zhuǎn)?
app.lastpicture=app.changedpicture;
if isequal(app.originalpicture, '')
msgbox("無圖片",'warning','help');
return;
else
levelpic=flip(app.changedpicture,1);
imshow(levelpic,'Parent',app.UIAxes2);
app.changedpicture=levelpic;
End
-
角度旋轉(zhuǎn)?
value = app.Knob.Value;
value = double(value);
app.lastpicture=app.changedpicture;
if isequal(app.originalpicture, '')
msgbox("無圖片",'warning','help');
return;
else
anglepic=imrotate(app.originalpicture,value);
imshow(anglepic,'Parent',app.UIAxes2);
app.changedpicture=anglepic;
End
-
相對亮度
changingValue = event.Value;
if isequal(app.originalpicture,'')
msgbox('無圖片','提示',"help");
return;
else
app.lastpicture=app.changedpicture;
brightpic=imadd(app.originalpicture,changingValue);
imshow(brightpic,'Parent',app.UIAxes2);
app.changedpicture=brightpic;
End
(亮)
(暗)
-
?銳化
changingValue = event.Value;
changingValue=double(changingValue);
changingValue1=changingValue./1.00;
if isequal(app.originalpicture, '')
msgbox("無圖片",'warning','help');
return;
else
app.lastpicture=app.changedpicture;
test = double(im2gray(app.originalpicture));
Gx = [-1 -2 -1;0 0 0;1 2 1];
x = filter2(Gx,test);
Gy = [-1 0 1;-2 0 2;-1 0 1];
y = filter2(Gy,test);
test1 = sqrt(x.^2 + y.^2);
test2 = test + test1*changingValue1;
sharpen=uint8(test2);
imshow(sharpen,'Parent',app.UIAxes2);
app.changedpicture=sharpen;
return;
end
?
-
實驗總結(jié)
(以后有空再加)
參考資料(只能找到當時看的一些了)
https://blog.csdn.net/u014655960/article/details/127645119?spm=1001.2014.3001.5502
(老師的代碼放第一個)(小聲bb)
https://blog.csdn.net/ckyckyzmy/article/details/126922975
https://blog.csdn.net/weixin_31831459/article/details/115956112
https://blog.csdn.net/qq_23023937/article/details/110308203
https://blog.csdn.net/new_EAGLE/article/details/125744992
?https://blog.csdn.net/imnoshow/article/details/123808000
遇到問題感謝百度的幫助,課程實驗的幫助以及室友、男朋友(劃重點)。
還有一個,界面配色參考↓文章來源:http://www.zghlxwxcb.cn/news/detail-431845.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-431845.html
到了這里,關(guān)于基于MATLAB APP Designer設(shè)計圖像處理小工具的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!