生物細胞計數軟體MATLAB程式碼實現
之前因為工作原因一直沒將程式碼貼上來,這次我比較詳細介紹下MATLAB的程式碼實現,有時間的話可能會出個視訊教程。
首先說下介面設計,我這裡只是說下都用了什麼元件以及一些引數,具體的GUI怎麼設計的我這裡就不詳細介紹,又需要介紹的可以給我留言我可以抽出點時間來簡單介紹。
這裡為了使引數可以靈活的調整,我在介面中將影象處理的每個關鍵的步驟都顯現出來,根據影象來靈活的調整引數,使結果更加精確。
圖1:介面設計圖
圖2:執行介面圖
根據圖來看效果還是可以的,然後接下來就說下每一部分的程式設計。
點選開啟圖片的時候需要開啟需要計算細胞的圖片,則可以使用下面的程式碼來開啟圖片,
function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) [filename,pathname]=uigetfile({'*.jpg';'*.bmp, *.jpg, *.tif';'*.bmp';'*.jpg';'*.tif';},'選擇影象'); if isequal(filename,0)||isequal(pathname,0) errordlg('您還沒有選取圖片!!','溫馨提示');%如果沒有輸入,則建立錯誤對話方塊 return; else global im; %定義全域性變數將開啟的照片放在該變數中。 image=[pathname,filename];%合成路徑+檔名 im=imread(image);%讀取影象 [x,y] = size(im); %讀取圖片的大小 if x>y %根據照片的長寬不同來改變圖片的大小,這裡定義600*800是為了減輕程式執行時電腦的壓力,以及該大小取得的效果也不錯。 im = imresize(im,[600 800]); else im = imresize(im,[800 600]); end set(handles.axes1,'HandleVisibility','ON');%開啟座標,方便操作 axes(handles.axes1);%%使用影象,操作在座標1 imshow(im);%在座標axes1顯示原影象 title('原始影象');
本設計是使用的是灰度圖以及高斯模糊的圖來實現USM銳化的,因此需要將RGB三色圖轉換為灰度圖,而MATLAB中自帶的RGB轉GRAY的函式十分方便,下面是程式碼實現。
global gray %定義灰度圖的全域性變數,方便後面的函式呼叫 gray= rgb2gray(im); %將RGB三色圖轉換成gray gray = imadjust(gray); %該函式是用來增強影象 set(handles.axes2,'HandleVisibility','ON');%開啟座標,方便操作 axes(handles.axes2);%%使用影象,操作在座標1 imshow(gray);%在座標axes1顯示原影象 title('灰度影象');
根據上一篇博文matlab實現生物細胞數目統計方案原理中介紹的USM原理可以知道我們需要的到高斯模糊的影象,高斯模糊影象的原理在之前的博文基於opencv2利用卷積運算元實現高斯模糊也介紹了,但是這篇博文是用的MATLAB,因此我們直接用MATLAB自帶的函式即可。
global Gauss
global filter
Gauss = fspecial('gaussian',[10 10],20);%獲取高斯模糊運算元
filter = imfilter(gray, Gauss); %獲得高斯模糊影象
set(handles.axes3,'HandleVisibility','ON');%開啟座標,方便操作
axes(handles.axes3);%%使用影象,操作在座標1
imshow(filter);%在座標axes1顯示原影象
title('模糊影象');
有了高斯模糊和灰度影象,就可以求出USM影象,原理也不再介紹,直接放程式碼。
global USM
weight = 0.8;
USM = uint8((double(gray)-weight.*double(filter))./(1-weight)); %獲取USM銳化影象
set(handles.axes4,'HandleVisibility','ON'); %開啟座標,方便操作
axes(handles.axes4); %使用影象,操作在座標1
imshow(USM);%在座標axes1顯示原影象
title('銳化影象');
有了USM影象,對比度增強了許多,因此使用將影象二值化後的效果將會很好,下面是二值化函式:
function getbw(handles)
global bw%將bw變數定義為全域性變數
global USM
level = get(handles.slider4,'value');%獲取滑桿4的值,該滑桿是控制閾值
bw = im2bw(USM, level); %將USM銳化後圖像轉換為二值化影象
imorph(3, get(handles.slider5,'value'),
get(handles.slider6,'value'));%該函式是自己編寫的用來腐蝕或膨脹影象
set(handles.axes5,'HandleVisibility','ON');%開啟座標,方便操作
axes(handles.axes5);%%使用影象,操作在座標1
imshow(bw);%在座標axes1顯示原影象
title('二值化影象');
下面是獲取細胞個數的函式,該函式的原理是計算連通區域個數來獲取細胞個數,由於經過以上的步驟,已將細胞核分離出來,因此只用計算連通域便可得到細胞個數,下面是程式碼:
function area(handles)
global bw
global USM
bw_img = ~bw; %將原本的二值化取反。
L = bwlabel(bw_img, 8);%
S = regionprops(L, 'area', 'boundingbox');
bw2 = ismember(L, find([S.Area] >= (get(handles.slider7,'value'))));
img_reg = regionprops(bw2, 'area', 'boundingbox');
areas = [img_reg.Area];
rects = cat(1, img_reg.BoundingBox);
[x, y] = size(areas);
set(handles.edit3, 'string', num2str(y));%這裡的Y便是細胞個數
global im;
temp = im;
set(handles.axes6,'HandleVisibility','ON');%開啟座標,方便操作
axes(handles.axes6);%%使用影象,操作在座標1
imshow(temp);%在座標axes1顯示原影象
title('連通域影象');
% show all the largest connected region
for i = 1:size(rects, 1)
rectangle('position',rects(i, :), 'EdgeColor', 'r');
end