【问题标题】:Detection of pellet on petri dish检测培养皿上的颗粒
【发布时间】:2017-07-29 00:55:41
【问题描述】:

我目前正在做一个关于分批发酵过程中丝状真菌形态学的项目(是的,我不是软件工程师......生物技术)。我在培养皿中拍摄形态的照片。我正在开发一种“快速”方法来描述发酵过程中出现的颗粒(真菌的小聚集体)。为此,我正在 MatLab 中编写代码。 根据颗粒的颜色(浅色或深色),照片是在不同的背景(黑色或白色)上拍摄的。如果平均灰度值低于 70,我会反转图片以区分背景。

图片: White background Dark background

我有几个问题:

  1. 检测培养皿的边缘,使其不会被视为对象(目前使用 edge('log',) 函数完成)。边缘被检测到,但我错过了一些部分,认为是因为顶部光线较暗。
  2. 培养皿内的适当阈值
  3. 颗粒检测 - 现在它是通过组合运行每个颜色通道来完成的,但可能会通过一些斑点检测来完成?

有人有意见吗?

我的代码如下:

close all
clear all
clc

%Empty arrays to hold data
metricD=[];
areaD=[];
perimeterD=[];

% Specify the folder where the files live.
myFolder = pwd;
% Check to make sure that folder actually exists.  Warn user if it doesn't.
if ~isdir(myFolder)
  errorMessage = sprintf('Error: The following folder does not exist:\n%s', myFolder);
  uiwait(warndlg(errorMessage));
  return;
end
% Get a list of all files in the folder with the desired file name pattern.
filePattern = fullfile(myFolder, '*.jpg'); % Change to whatever pattern you need.
theFiles = dir(filePattern);

% Show debugging plots
plotFig = 0;

% parameters that can be tuned
% how many colors channels we minimum want to see a spore in
% e.g. set to 1 for image "P. f Def C.tif"
labelcutOff = 1;

% remove areas larger than
removeLargerthan = 500000;

for k = 1 : length(theFiles)
    baseFileName = theFiles(k).name;
    fullFileName = fullfile(myFolder, baseFileName);

    %% reading as an image array with im
    I = imread(fullFileName);
    % convert to grayscale
    Ig = rgb2gray(I);
    if plotFig
        figure;imagesc(I)
        figure;imagesc(Ig)
    end

    mm=mean(mean(Ig)); 
    if mm < 70
        I=imcomplement(I);
        Ig = imcomplement(Ig);
    end


    % BLOB DETCTION
%     h = fspecial('log', [15 15], 2);
%     imLOG = imfilter(Ig, h);
%     figure;imagesc(imLOG)

    %% find petridish by edges and binary operations
    % HACK - NOT HOW IT SHOULD BE DONE
    Ig = wiener2(Ig,[5 5]);
    imEdge = edge(Ig,'log');
    circle = bwareaopen(imEdge,50);
    circle = imclose(circle,strel('disk',30));
    circle = bwareaopen(circle,8000);
%     circle = imfill(circle,'holes');
    circle = bwconvhull(circle);
    circle = imerode(circle,strel('disk',150));
    if plotFig
        figure;imagesc(circle)
    end

    %% Get thresholds inside dish using otsu on each channel
    imR = double(I(:,:,1)) .* circle;
    imG = double(I(:,:,2)) .* circle;
    imB = double(I(:,:,3)) .* circle;

    thresR = graythresh(uint8(imR(circle))) *max(imR(circle));
    thresG = graythresh(uint8(imG(circle))) *max(imG(circle));
    thresB = graythresh(uint8(imB(circle))) *max(imB(circle));

    if plotFig
    figure;imagesc(imR)
    figure;imagesc(imG)
    figure;imagesc(imB)
    end

    %% classify inside dish
    % check if it should be smaller or larger than
    if sum(imR(circle) < thresR) >  sum(imR(circle) > thresR)
        labelR = imR > thresR;
    else
        labelR = imR < thresR;
    end

    if sum(imG(circle) < thresG) >  sum(imG(circle) > thresG)
        labelG = imG > thresG;
    else
        labelG = imG < thresG;
    end

    if sum(imB(circle) < thresB) >  sum(imB(circle) > thresB)
        labelB = imB > thresB;
    else
        labelB = imB < thresB;
    end

    if plotFig
        figure;imagesc(labelR)
        figure;imagesc(labelG)
        figure;imagesc(labelB)
    end

    labels = (labelR + labelG + labelB) .* circle;
    labels(labels < labelcutOff) = 0;
    labels = imfill(labels,'holes');
    labels = bwareaopen(labels,30);
    if plotFig
    figure;imagesc(labels)
    end

    %% clean up labels
    labelBig = bwareaopen(labels,removeLargerthan);
    labels = labels - labelBig;
    if plotFig
    figure;imagesc(labels)
    end


    BN = labels;


    %% old script


    stats = regionprops(BN,'Basic');
    obj2 = numel(stats);
    [B,L] = bwboundaries(BN,'holes');

    figure
%     imshow(label2rgb(L, @jet, [.5 .5 .5]))
    imshow(I)
    hold on
    title(baseFileName)

    for j = 1:length(B)
      boundary = B{j};

      plot(boundary(:,2), boundary(:,1),'w','LineWidth',2)
    end
    %region stats
    stats = regionprops(L,'Area','Centroid');
    %Threshold for printing in end
    threshold = 0.2;
    %Conversion factor pixel to cm
    conversionF=9/2125;

    % loop over the boundaries
    for j = 1:length(B)

      % obtain (X,Y) boundary coordinates corresponding to label 'j'
      boundary = B{j};

      % compute a simple estimate of the object's perimeter
      delta_sq = diff(boundary).^2;
      perimeter = sum(sqrt(sum(delta_sq,2)));
      perimeterD(j,k)=perimeter*conversionF;

      % obtain the area calculation corresponding to label 'k'
      area = stats(j).Area;
      areaD(j,k)=area*conversionF^2;

      % compute the roundness metric
      metric = 4*pi*area/perimeter^2;
      metricD(j,k)=metric;

      % display the results
      metric_string = sprintf('%d. %2.2f', j,metric);

      text(boundary(1,2)-50,boundary(1,1)+23,metric_string,'Color','k',...
           'FontSize',14,'FontWeight','bold');
    end

      drawnow; % Force display to update immediately.
end
%Calculating stats
areaM=mean(areaD);
pM=mean(perimeterD);
metricD(metricD==Inf)=0;
mM=mean(metricD);

【问题讨论】:

  • 您已经展示了代码,但是图像在哪里?发布一些示例图像,指示还必须检测什么
  • 无法获取文字图片。
  • imfindcirlces 可以检测到培养皿,还是圆环太苍白?
  • “通过每个颜色通道”:这是什么原理,这些图像本质上是单色的?
  • 颗粒可能是蓝色或红色

标签: image matlab image-processing blob edge-detection


【解决方案1】:

提示:

通过二值化(具有恒定阈值?)流动的形态学顶帽过滤器可能是一个好的开始。并且过滤 blob 大小将进行合理的清理。

对于边缘,试试圆形霍夫。

【讨论】:

    猜你喜欢
    • 2012-04-14
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 2017-07-22
    • 1970-01-01
    相关资源
    最近更新 更多