數字圖像處理GUI的設計最後一天
1 頻譜分析
1.1 頻譜圖
function Spectrogram_Callback(hObject, eventdata, handles)
axes(handles.axes2);
x=(handles.img);
if (ndims(x)==3)
m=fft2(x(:,:,1));
y=fftshift(m);
imshow(log(abs(y)),[]);
else
m=fft2(x);
y=fftshift(m);
imshow(log(abs(y)),[]);
end
1.2 高斯高通濾波器
axes(handles.axes2);
x=(handles.img);
if (ndims(x)==3)
msgbox('這是彩色圖像,不能通過高通濾波器','失敗');
else
y1=imnoise(x,'gaussian'); %加高斯噪聲
f=double(y1); % 數據類型轉換
k=fft2(f); % 傅立葉變換
g=fftshift(k); % 轉換數據矩陣
[M,N]=size(g);
nn=2;
d0=3; %截止頻率爲3
m=fix(M/2); n=fix(N/2);
for i=1:M
for j=1:N
d=sqrt((i-m)^2+(j-n)^2); % 計算高通濾波器傳遞函數
if d<=d0
h=0;
else h=1;
end
result(i,j)=h*g(i,j);
end
end
result=ifftshift(result);
y2=ifft2(result);
y3=uint8(real(y2));
imshow(y3);
end
1.3巴特沃斯低通濾波器
axes(handles.axes2);
x=(handles.img);
if (ndims(x)==3)
msgbox('這是彩色圖像,不能通過低通濾波器','失敗');
else
y1=imnoise(x,'salt & pepper'); % 疊加椒鹽噪聲
f=double(y1); % 數據類型轉換
g=fft2(f); % 傅立葉變換
g=fftshift(g); % 轉換數據矩陣
[M,N]=size(g);
nn=2; % 二階巴特沃斯(Butterworth)低通濾波器
d0=10; %截止頻率爲10
m=fix(M/2); n=fix(N/2);
for i=1:M
for j=1:N
d=sqrt((i-m)^2+(j-n)^2);
h=1/(1+0.414*(d/d0)^(2*nn)); % 計算低通濾波器傳遞函數
result(i,j)=h*g(i,j);
end
end
result=ifftshift(result);
y2=ifft2(result);
y3=uint8(real(y2));
imshow(y3); % 顯示濾波處理後的圖像
end
2 圖像轉換
2.1 RGB轉HSV
axes(handles.axes2);
x=(handles.img);
if (ndims(x)==3)
HSV=rgb2hsv(x);
imshow(HSV);
else
msgbox('這是灰度圖像,不能轉換','轉換失敗');
end
2.2 RGB轉NTHC
axes(handles.axes2);
x=(handles.img);
if (ndims(x)==3)
ntsc=rgb2ntsc(x);
imshow(ntsc);
else
msgbox('這是灰度圖像,不能轉換','轉換失敗');
end
2.3 RGB轉YCBCR
axes(handles.axes2);
x=(handles.img);
if (ndims(x)==3)
ycbcr=rgb2ycbcr(x);
imshow(ycbcr);
else
msgbox('這是灰度圖像,不能轉換','轉換失敗');
end
3 圖像塗鴉
恩。。。之前忘記了這個,所以做完後查漏補缺,又重新添加,也再次在GUI界面添加了些東西。
3.1 鼠標響應事件
屬實麻煩,而且我也沒學明白,一點點摸索的,甚至很多都還沒特別明白就用上了。這次使用三種事件,鼠標點擊,鼠標拖動,鼠標鬆開。
塗鴉具體的有塗鴉類型,三種,點,線,矩形,本來還想着嘗試做個多邊形,但是折騰了很久,失敗了,只是存點然後做多邊形會出現bug,莫名其妙丟點,或者直接報錯。而使用凸包又不滿足設計要求。所以放棄了,在網上也沒找到大佬的多邊形代碼,我還是太菜了。
線條包括實線,虛線,及由點組成的線
具體的看代碼吧。
%-------------------鼠標點擊反饋-----------------
% --- Executes on mouse press over figure background, over a disabled or
% --- inactive control, or over an axes background.
function figure1_WindowButtonDownFcn(hObject, eventdata, handles)
global flg mark rgb x0 y0 x y rect graph;
flg=1;
currPt = get(gca, 'CurrentPoint');%gca返回當前axes對象的句柄值
x = currPt(1,1);
y = currPt(1,2);
switch(graph)
case 'POINT'
line(x,y, 'marker', mark,'color',rgb);
otherwise
line(x,y,'LineStyle',mark,'color',rgb);
end
x0=x;y0=y;
%-----------------鼠標移動響應------------------
% --- Executes on mouse motion over figure - except title and menu.
function figure1_WindowButtonMotionFcn(hObject, eventdata, handles)
global flg mark rgb x0 y0 x y rect graph h xy;
if flg
switch(graph)
case 'POINT'
currPt=get(gca, 'CurrentPoint');
x=currPt(1,1);
y=currPt(1,2);
line(x,y, 'marker', mark,'color',rgb);
case'LINE'
currPt=get(gca,'CurrentPoint');
x=currPt(1,1);
y=currPt(1,2);
xy = [];
if x~=x0 && y~=y0
xy(:,1)=[x0;y0];
xy(:,2)=[x;y];
%h=line([x0,x],[y0,y],'LineStyle',mark);
end
case 'RECTANGLE'
currPt=get(gca, 'CurrentPoint');
x=currPt(1,1);
y=currPt(1,2);
if x~=x0
if ~isempty(h)
set(h,'Visible','off')
end
rect=[min([x0,x]),min([y0,y]),abs(x-x0),abs(y-y0)];
if rect(3)*rect(4)~=0
h=rectangle('Position',rect,'LineStyle',':');
end
end
end
end
%--------------------鼠標鬆開響應----------------------
% --- Executes on mouse press over figure background, over a disabled or
% --- inactive control, or over an axes background.
function figure1_WindowButtonUpFcn(hObject, eventdata, handles)
global flg rgb mark h graph rect xy;
flg=0;
switch(graph)
case 'RECTANGLE'
set(h,'Visible','off');
h=[];
if rect(3)*rect(4)~=0
rectangle('Position',rect,'edgecolor',rgb,'LineStyle',mark)%繪製矩形
end
case 'LINE'
set(h,'Visible','off');
h=[];
line(xy(1,:),xy(2,:),'LineStyle',mark,'color',rgb)
end
% --- Executes during object creation, after setting all properties.
function figure1_CreateFcn(hObject, eventdata, handles)
global flg mark rgb graph;
flg=0;
graph='POINT';
mark='.';
rgb=[1,0,0];
2.2 塗鴉的保存
額,這裏又出了問題,並且我沒找到辦法解決,就是圖像塗鴉後的保存問題,通過之前的代碼保存,只能保存圖像,但是圖像上的塗鴉沒有保存,而getframe函數保存的圖形會出現分辨率的變化,經查詢,大概是因爲getframe函數是通過類似於截圖的方式保存的,也就是截取的axes這一個窗口大小,我也嘗試了更改axes大小來觀察對保存的圖片的影響,確實分辨率改變了。
最後只能通過塗鴉保存和保存兩種方式來分別保存圖像來區分了。如果有好的方法,還請評論一下,爲後來人造福,我是用不上了,還是考研複習比較急,這個設計就得過且過吧!
function pushbutton1_Callback(hObject, eventdata, handles)
[filename,pathname] = uiputfile({'*.jpg','JPEG(*.jpg)';...
'*.bmp','Bitmap(*.bmp)';...
'*.gif','GIF(*.gif)';...
'*.*', 'All Files (*.*)'},...
'Save Picture','Untitled');
if isequal([filename,pathname],[0,0])
errordlg('保存失敗','出錯');
return;
else
file = strcat(pathname,filename);
i=getframe(handles.axes2);
imwrite(i.cdata,file);
end