Tracking Cells: A project on Cell Biology
Abstract
Yeast cells, Dept. of Genetics, Cell Biology and Development, UMN
Most genetic disorders are attributed to mutations in cells and efforts to study and understand these disorders entail the use of model organisms such as yeast. This project seeks to study yeast cells with a central goal of identifying, analyzing and tracking mutations in replicating cells. To accomplish this, a Digital Image Processing (DIP) based Matlab software application that will be used in Biological research performed by Judith Berman, Ph.D (University of Minnesota) will be designed and developed. This software application will utilize digital time-lapse images of replicating yeast cells to, in part; automate the tedious process of manually identifying and tracking mutations. The application will also be designed to produce exportable data reports for analysis and a Graphical User Interface (GUI) that allows switching between visual analysis and the reports will also be integrated into the design. System documentation will be provided along with the final product which will be adopted for studies and research focused on cancer at the University of Minnesota.
Current Development
function [] = tracking_cells() global L X S output_file_name; %global variables clear all; clc; D = dir('*.jpg'); % or jpeg or whatever. S.NAM = {D(:).name}; % Store the name of all items returned in D. % Main UI S.fh = figure('units','pixels',... 'position',[100 50 800 800],... 'menubar','none',... 'name','Verify Password.',... 'resize','off',... 'numbertitle','off',... 'name','Tracking Cells'); movegui(S.fh, 'center'); %center figure % Loaded images ls title S.ed1 = uicontrol('style','text',... 'unit','pix',... 'position',[580 760 50 15],... 'string','Images',... 'fontsize',9,'fontweight','bold',... 'HorizontalAlign','left'); % Output results ls title S.ed2 = uicontrol('style','text',... 'unit','pix',... 'position',[30 40 100 190],... 'string','Output results',... 'fontsize',9,'fontweight','bold',... 'HorizontalAlign','left'); % Output results listbox S.output = uicontrol('style','list',... 'unit','pix',... 'fontsize',10,'position',[30 20 512 195],... 'string','~~~~~~~~~~OUTPUT RESULTS WILL PRINT HERE~~~~~~~~~~',... 'HorizontalAlign','left'); % Output results file pushbutton S.view_out = uicontrol('style','push',... 'units','pix',... 'position',[580 185 100 30],... 'backgroundcolor','w',... 'HorizontalAlign','left',... 'string','View output file',... 'fontsize',9,'fontweight','bold',... 'callback',{@view_output,S}); % Loaded imagest listbox S.ls = uicontrol('style','list',... 'units','pix',... 'position',[580 640 200 120],... 'backgroundcolor','w',... 'string',S.NAM,... 'HorizontalAlign','right'); % Load image pushbutton S.pb1 = uicontrol('style','push',... 'units','pix',... 'position',[580 600 100 30],... 'backgroundcolor','w',... 'HorizontalAlign','left',... 'string','Load Image',... 'fontsize',9,'fontweight','bold',... 'callback',{@pb1_call,S}); % Run detection push button S.pb2 = uicontrol('style','push',... 'units','pix',... 'position',[580 550 100 30],... 'backgroundcolor','w',... 'HorizontalAlign','left',... 'string','Run Detection',... 'fontsize',9,'fontweight','bold',... 'callback',{@pb2_call,S}); % Reset push button S.reset = uicontrol('style','push',... 'units','pix',... 'position',[580 500 100 30],... 'backgroundcolor','w',... 'HorizontalAlign','left',... 'string','Reset',... 'fontsize',9,'fontweight','bold',... 'callback',{@reset,S}); S.ax = axes('units','pixels',... 'position',[30 250 512 512]); set(S.ax,'xtick',[],'ytick',[]); % Get rid of ticks. function get_ls() L = get(S.ls,{'string';'value'}); % Get the editbox string L = L{1}{L{2}}; % Give it a name for the base workspace. X = imread(L); % Read the image. end function view_output(varargin) open(strcat(L, '.txt')); % Open output file end function [] = reset(varargin) set(S.output, 'String','~~~~~~~~~~OUTPUT RESULTS WILL PRINT HERE~~~~~~~~~~'); cla reset; % Delete from the current axes all graphics objects title(''); % Delete from the current axes all titles clear all; clc; % Clear all variables, clear terminal end function [] = pb1_call(varargin) % Callback for pushbutton. S = varargin{3}; %variable length argument list get_ls(); S.im = X; % X from fuction get_ls() S.R = image(S.im); % Display the image on S.ax. title('Original image'); end function print_to_ls(str) str_part = str; old_str = get(S.output, 'String' ); new_str = strvcat(old_str, str_part); %concatenation set(S.output, 'String', new_str) end function [] = pb2_call(varargin) clc; S = varargin{3}; %variable length argument list get_ls(); I = X; % % DETECT FAMILIES % I_Red = I(:,:,1); % divides the image into its three channels I_Green = I(:,:,2); I_Blue = I(:,:,3); N = 512; % N = 512 for the 512 by 512 image I_edged = edge(I_Green,'canny',.35); % uses the blue channel detects edge %figure(1); %imshow(I_edged); %figure(2); %imshow(I); se1 = strel([1,1,1,1,1,1,1,1,1 1,1,1,1,1,1,1,1,1 1,1,1,1,1,1,1,1,1 1,1,1,1,1,1,1,1,1 1,1,1,1,1,1,1,1,1 1,1,1,1,1,1,1,1,1 1,1,1,1,1,1,1,1,1 1,1,1,1,1,1,1,1,1 1,1,1,1,1,1,1,1,1]); I_dialiated = imdilate(I_edged,se1); % dialtes image toward center %figure(3); %imshow(I_dialiated); I_filled = imfill(I_dialiated,'holes'); % fills holes in white up to certain size %figure(4); %imshow(I_filled); I_label = bwlabel(I_filled,8); % labels each white patch 1-num_fam d = max(I_label,[],2); % searches through I_label and finds family = max(d); % the number of family I_thresh = im2bw(I_Red,.22); % thresholds the Red channel so only the nucli show up for h = 1:family; [R,C] = find(I_label == h); upper_lim_x = max(R); %this set of for loops checks to make sure lower_lim_x = min(R); %every family has at least one nuclei in it upper_lim_y = max(C); %I had trouble with noise and this seemed to help lower_lim_y = min(C); x_dim = upper_lim_x - lower_lim_x; y_dim = upper_lim_y - lower_lim_y; cor = [ lower_lim_y lower_lim_x y_dim x_dim ]; I2 = imcrop(I_thresh,cor); D = find(I2 == 1); if(length(D) < 2); for A = 1:N for B = 1:N if(I_label(A,B) == h) I_label(A,B) = 0; end end end end end I_fam = bwlabel(I_label,8); e = max(I_fam,[],2); num_fam = max(e); % % Detect Cells % I_Red = adapthisteq(I_Red, 'clipLimit',0.025,'Distribution','rayleigh'); tic; [accum, circen, cirrad] = CircularHough_Grd(I_Red, [3 20], 10, 8, 1); toc if any(cirrad <= 0) inds = find(cirrad>0); cirrad = cirrad(inds); circen = circen(inds,:); end %Get Nuclei im_yiq = rgb2ntsc(I); i_im = im_yiq(:,:,2); thresh_I = ~(i_im < 0.09); [I_nuclei, num_nuclei] = bwlabel(thresh_I); nuclei = zeros(num_nuclei,2); for i = 1:num_nuclei [R,C] = find(I_nuclei == i); nuclei(i, 1) = mean(C); nuclei(i, 2) = mean(R); end %find family perimeters for numbering purposes BWoutline = bwperim(I_fam); s = regionprops(BWoutline, 'Centroid'); S.im = I; S.R = image(S.im); % Display the image on S.ax. title('Outlined original image') hold on; circen(:,2) = circen(:,2); plot(nuclei(:,1), nuclei(:,2), 'r+'); %Get family boundaries set(S.output, 'String', ''); % clear output listbox first diary output.txt for i = 1:num_fam if i == 1 my_str = strcat('Image processed:-->',L); % img processed fprintf(my_str); print_to_ls(my_str) %call print_to_ls function print_to_ls(sprintf('------------------------------')) end fprintf('\nFamily %d\r------------\n', i); %pring family output to GUI if i > 1 % nsert space after first family is printed F1 = sprintf('\n'); % print new blank line print_to_ls(F1) %call print_to_ls function end F2 = sprintf('Family %d', i); print_to_ls(F2) %call print_to_ls function F3 = sprintf('\r------------\n'); % print new blank line print_to_ls(F3) %call print_to_ls function % end print family output to GUI array(i,1) = i; fam = array; cell_count = 0; [R,C] = find(I_fam == i); upper_lim_x = max(C); lower_lim_x = min(C); upper_lim_y = max(R); lower_lim_y = min(R); x_dim = upper_lim_x - lower_lim_x; y_dim = upper_lim_y - lower_lim_y; rectangle('Position', [lower_lim_x, lower_lim_y, x_dim, y_dim],... 'edgecolor', 'w', 'linewidth', 1); %start label families c = s(i).Centroid; text(upper_lim_x, upper_lim_y, sprintf('%d',i) , ... 'VerticalAlignment', 'Bottom',... 'HorizontalAlignment', 'Right', 'Color','white'); %end label families for j=1:size(circen,1) cell_x = circen(j,1); cell_y = circen(j,2); cell_rad = cirrad(j); if((lower_lim_x <= cell_x) && (cell_x <= upper_lim_x) &&... (lower_lim_y <= cell_y) && (cell_y <= upper_lim_y)) cell_count = cell_count + 1; % plot cell rectangle('Position',[cell_x - cell_rad, cell_y - ... cell_rad, 2*cell_rad, 2*cell_rad],... 'Curvature', [1,1], 'edgecolor', 'b', 'linewidth', 1); %count nuclei per cell nuclei_count = 0; for k=1:size(nuclei,1) %see if distance between cell and nuclei center is less than the radius of the current cell if(sqrt((nuclei(k,1) - cell_x)^2 + (nuclei(k,2) - ... cell_y)^2) < cell_rad) nuclei_count = nuclei_count + 1; end end fprintf('\tCell %d has %d nuclei\n', j, nuclei_count); % print cell output to GUI C = sprintf('\tCell %d has %d nuclei\n', j, nuclei_count); print_to_ls(C) %call print_to_ls function % end print cell output to GUI end end end diary off; movefile('output.txt', strcat(L, '.txt')); % trick to rename output.txt to include image_name delete output.txt; hold off; end end
