%% Microarray Spot Finding Example % This example shows a simple method for locating spots on a microarray and % extracting the intensties of the spots. It can be downloaded from *MATLAB % Central*. % http://www.mathworks.com/matlabcentral % % Copyright 2004-2010 RBemis The MathWorks, Inc. %% Start with clean slate clear %empty workspace (no variables) close all %no figures clc %empty command window %% Read image file % MATLAB can read many standard image formats including TIFF, GIF and BMP % using the |imread| command. In addition, the *Image Procesing Toolbox* % provides support for working with specialized image file formats such as % DICOM. This microarray image was stored as a J-PEG file. The image is % much larger than the screen size, so |imshow| scales it down to fit and % let's you know with a warning message. % x = imread('MicroArraySlide.JPG'); % imageSize = size(x) % screenSize = get(0,'ScreenSize') % % iptsetpref('ImshowBorder','tight') % imshow(x) % title('original image') %% Crop specified region % Next we use |imcrop| to extract a region of interest. You can repeat this % for all print-tip blocks for a full microarray study. % y = imcrop(x,[622 2467 220 227]); y=imread('test.tif'); % y=imread('cDNA.png'); % y=imread('test001.tif'); % y = imread('C:\Users\Administrator\Desktop\中国生物医学工程学报(实验结果对比)\实验二\test001.tif'); % y = imread('C:\Users\Administrator\Desktop\中国生物医学工程学报(实验结果对比)\实验三\test003.tif'); f1 = figure('position',[40 46 285 280]); imshow(y) %% Display red & green layers % This image was stored in RGB format. We are only interested in the red % and green planes. To extract the red plane, simply index layer 1. For the % green plane, layer 2. Custom colormaps make visualization more intuitive. % Notice that spot shapes are not necessarily the same in both colors. f2 = figure('position',[265 163 647 327]); subplot(121) redMap = gray(256); redMap(:,[2 3]) = 0; subimage(y(:,:,1),redMap) axis off title('red (layer 1)') subplot(122) greenMap = gray(256); greenMap(:,[1 3]) = 0; subimage(y(:,:,2),greenMap) axis off title('green (layer 2)') %% Convert RGB image to grayscale for spot finding % Initially we care more about where the spots are located than their red % and green intensities. Converting from RGB color to grayscale allows us % to focus first on spot locations. z = rgb2gray(y); figure(f1) imshow(z) %% Create horizontal profile % We are looking for a regular grid of spots so we start by looking at the % mean intensity for each column of the image. This will help us identify % where the centres of the spots are and where the gaps between the spots % can be found. xProfile = mean(z); f2 = figure('position',[39 346 284 73]); plot(xProfile) title('horizontal profile') axis tight %% Estimate spot spacing by autocorrelation % Ideally the spots would be periodicaly spaced consistently printed, but % in practice they tend to have different sizes and intensities, so the % horizontal profile is irregular. We can use autocorrelation to enhance % the self similarity of the profile. The smooth result promotes peak % finding and estimation of spot spacing. The *Signal Processing Toolbox* % allows easy computation of the autocorrelation function using the |xcov| % command. ac = xcov(xProfile); %unbiased autocorrelation f3 = figure('position',[-3 427 569 94]); plot(ac) s1 = diff(ac([1 1:end])); %left slopes s2 = diff(ac([1:end end])); %right slopes maxima = find(s1>0 & s2<0); %peaks estPeriod = round(median(diff(maxima))) %nominal spacing hold on plot(maxima,ac(maxima),'r^') hold off title('autocorrelation of profile') axis tight %% Remove background morphologically % We can use the spacing estimate to help design a filter to remove the % background noise from the intensity profile. We do this with the % |imtophat| function from the *Image Processing Toolbox*. The |strel| % command creates a simple rectangular 1D window or line shaped structuring % element. seLine = strel('line',estPeriod,0); xProfile2 = imtophat(xProfile,seLine); f4 = figure('position',[40 443 285 76]); plot(xProfile2) title('enhanced horizontal profile') axis tight %% Segment peaks % Now that we have clean and anchored gaps between the peaks, we can number % each peak region with the |bwlabel| command. These regions were segmented % by thresholding with |im2bw|. The threshold value was automatically % determined by statistical properties of the data using |graythresh|. This % is a good example of image processing techniques are often useful for 1D % data analysis. level = graythresh(xProfile2/255)*255 bw = im2bw(xProfile2/255,level/255); L = bwlabel(bw); f5 = figure('position',[40 540 285 70]); plot(L) axis tight title('labelled regions') %% Locate centers % We can extract the centroids of the peaks. These correspond to the % horizontal centres of the spots. This is a common blob analysis or % feature extraction task that can be done with |regionprops|. stats = regionprops(L); centroids = [stats.Centroid]; xCenters = centroids(1:2:end) figure(f5) hold on plot(xCenters,1:max(L),'ro') hold off title('region centers') %% Determine divisions between spots % The midpoints between adjacent peaks provides grid point locations. gap = diff(xCenters)/2; first = xCenters(1)-gap(1); xGrid = round([first xCenters(1:end)+gap([1:end end])]) figure(f2) for i=1:length(xGrid) line(xGrid(i)*[1 1],ylim,'color','m') end title('vertical separators') %% Transpose and repeat % We just did the analysis on the vertical grid. Now we want to do the same % for the horizontal spacing. To do this, we simply transpose the image and % repeat all the steps used above. This time without intermediate graphics % display commands in order to summarize the mathematical steps of this % algorithm. yProfile = mean(z'); %peak profile ac = xcov(yProfile); %cross correlation p1 = diff(ac([1 1:end])); p2 = diff(ac([1:end end])); maxima = find(p1>0 & p2<0); %peak locations estPeriod = round(median(diff(maxima))) %spacing estimate seLine = strel('line',estPeriod,0); yProfile2 = imtophat(yProfile,seLine); %background removed level = graythresh(yProfile2/255); %automatic threshold level bw = im2bw(yProfile2/255,level); %binarized peak regions L = bwlabel(bw); %labeled regions stats = regionprops(L); centroids = [stats.Centroid]; %centroids yCenters = centroids(1:2:end) %Y parts only gap = diff(yCenters)/2; %inner region half widths first = yCenters(1)-gap(1); % list defining vertical boundaries between spot regions yGrid = round([first yCenters(1:end)+gap([1:end end])]) %% Put bounding boxes around each spot % We have now found the rectangular grid. Using pairs of neighboring grid % points we can form bounding box regions to address each spot % individually. The position and size coordinates of each bounding box were % tabulated for convenience into a 4-column matrix called |ROI|, which % stands for regions of interest. % figure(f1) figure() imshow(z) line(xGrid'*[1 1],yGrid([1 end]),'color','b') line(xGrid([1 end]),yGrid'*[1 1],'color','b') [X,Y] = meshgrid(xGrid(1:end-1),yGrid(1:end-1)); %xGrid和yGrid中存储了分格子的数据 [dX,dY] = meshgrid(diff(xGrid),diff(yGrid)); ROI = [X(:) Y(:) dX(:) dY(:)]; % first few rows of ROI table ROI(1:5,:) %% % I=y; % location_row=xGrid; % location_col=yGrid; location_row=yGrid; location_col=xGrid; for ii = 1:length(location_row)-1 for jj = 1: length(location_col)-1 subimage = I([location_row(ii):location_row(ii+1)],[location_col(jj):location_col(jj+1)],:);%从I中取出每个grid的数据 subimage_double = double(subimage); %%%% 转换数据到[0,1]之间,然后转换到[0,255]之间 sumimage_01 = (subimage_double-min(subimage_double(:)))./max(subimage_double(:))-min(subimage_double(:)); %将每个grid的数据转换到[0,1]之间 % subimage_norm = uint8(255*sumimage_01);%原文 subimage_norm = uint8(255*sumimage_01); %%%% TV去噪 subimage_norm(:,:,1)= tvdenoise(double(subimage_norm(:,:,1)),0.01); subimage_norm(:,:,2)= tvdenoise(double(subimage_norm(:,:,2)),0.01); subimage_norm(:,:,3)= tvdenoise(double(subimage_norm(:,:,3)),0.01); I_norm([location_row(ii):location_row(ii+1)],[location_col(jj):location_col(jj+1)],:)=subimage_norm;%每个grid的数据 %% %用CV方法进行分割 if mean(mean(subimage_norm(:,:,1)))<5 %%如果均值小于5,增强5图像 subimage_norm=5*subimage_norm; else if mean(mean(subimage_norm(:,:,1)))<30 %%如果均值小于30,增强1.5图像 subimage_norm=1.5*subimage_norm; end end iter=500; dt=0.1; u0=cvseg(subimage_norm,iter,dt); %C-V水平集分割 % u1=im2bw(u0); %非数字的点设为默认值0 [m_u0,n_u0]=size(u0); for i=1:m_u0 for j=1:n_u0 if(isnan(u0(i,j))) u0(i,j)=0; end end end % subimage_bw=u0; %若最后一列的第一个点或最后一个点为白色,则取反 u1=u0; if(u1(end,1)==1 || u1(end,end)) u2=1-u1; else u2=u1; end subimage_bw=u2; % subimage_bw为获得的二值图像,即为传递到下一步的图像 %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%分割结束%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% I_bw([location_row(ii):location_row(ii+1)],[location_col(jj):location_col(jj+1)],:)=subimage_bw;%每个grid的数据; end end figure,imshow(I_bw) %显示与原图大学相等的二值图像 all_bw=zeros(size(y(:,:,1))); all_bw(1:location_row(end),1:location_col(end))=I_bw; figure(),imshow(all_bw) %% I_bw1=all_bw; I_bw_01=choice(I_bw1,100); %%剔除面积大于100的目标(100仅为本次设定的阈值),这里最好用直方图的方法确定阈值,则更具普适性 figure(),imshow(I_bw_01); %% num_sub_I_bw_02=0; for ii = 1:length(location_row)-1 for jj = 1: length(location_col)-1 sub_I_bw_01 = I_bw_01([location_row(ii):location_row(ii+1)],[location_col(jj):location_col(jj+1)],:); sub_I_bw_02=choosemaxobj(sub_I_bw_01,8);%剔除面积小于20的点 [m,n]=size(sub_I_bw_02); for i=1:m for j=1:n if(sub_I_bw_02(1,j)==1 || sub_I_bw_02(i,1)==1|| sub_I_bw_02(m,j)==1 || sub_I_bw_02(i,n)==1) num_sub_I_bw_02=num_sub_I_bw_02+1; end end end if(num_sub_I_bw_02>10) sub_I_bw_02=zeros(size(sub_I_bw_02)); end num_sub_I_bw_02=0;%每次计算完毕清零 I_bw_Last_01([location_row(ii):location_row(ii+1)],[location_col(jj):location_col(jj+1)],:)=sub_I_bw_02;%每个grid的数据; end end all_bw_01=zeros(size(y(:,:,1))); all_bw_01(1:location_row(end),1:location_col(end))=I_bw_Last_01; figure(),imshow(all_bw_01);