Detect black dots from color background

前端 未结 3 807
攒了一身酷
攒了一身酷 2021-02-01 23:04

My short question

How to detect the black dots in the following images? (I paste only one test image to make the question look compact. More images can be found →here←

相关标签:
3条回答
  • 2021-02-01 23:10

    I was able to get some pretty nice first pass results by converting to HSV color space with rgb2hsv, then using the Image Processing Toolbox functions imopen and imregionalmin on the value channel:

    rgb = imread('6abIc.jpg');
    hsv = rgb2hsv(rgb);
    openimg = imopen(hsv(:, :, 3), strel('disk', 11));
    mask = imregionalmin(openimg);
    imshow(rgb);
    hold on;
    [r, c] = find(mask);
    plot(c, r, 'r.');
    

    And the resulting images (for the image in the question and one chosen from your link):

    enter image description here

    enter image description here

    You can see a few false positives and missed dots, as well as some dots that are labeled with multiple points, but a few refinements (such as modifying the structure element used in the opening step) could clean these up some.

    0 讨论(0)
  • 2021-02-01 23:24

    I was curios to test with my old 2d peak finder code on the images without any threshold or any color considerations, really crude don't you think?

    im0=imread('Snap10.jpg');
    im=(abs(255-im0));
    d=rgb2gray(im);
    filter=fspecial('gaussian',16,3.5);
    p=FastPeakFind(d,0,filter);
    imagesc(im0); hold on
    plot(p(1:2:end),p(2:2:end),'r.')
    

    enter image description here

    The code I'm using is a simple 2D local maxima finder, there are some false positives, but all in all this captures most of the points with no duplication. The filter I was using was a 2d gaussian of width and std similar to a typical blob (the best would have been to get a matched filter for your problem). A more sophisticated version that does treat the colors (rgb2hsv?) could improve this further...

    0 讨论(0)
  • 2021-02-01 23:35

    Here is an extraodinarily simplified version, that can be extended to be full RGB, and it also does not use the image procesing library. Basically you can do 2-D convolution with a filter image (which is an example of the dot you are looking for), and from the points where the convolution returns the highest values, are the best matches for the dots. You can then of course threshold that. Here is a simple binary image example of just that.

    %creating a dummy image with a bunch of small white crosses
    im = zeros(100,100);
    numPoints = 10;
    
    % randomly chose the location to put those crosses
    points = randperm(numel(im));
    % keep only certain number of points
    points = points(1:numPoints);
    % get the row and columns (x,y)
    [xVals,yVals] = ind2sub(size(im),points);
    
    for ii = 1:numel(points)
       x = xVals(ii);
       y = yVals(ii);
       try
           % create the crosses, try statement is here to prevent index out of bounds
           % not necessarily the best practice but whatever, it is only for demonstration
           im(x,y) = 1;
           im(x+1,y) = 1;
           im(x-1,y) = 1;
           im(x,y+1) = 1;
           im(x,y-1) = 1;
       catch err
       end
    end
    % display the randomly generated image
    imshow(im)
    
    % create a simple cross filter
    filter = [0,1,0;1,1,1;0,1,0];
    figure; imshow(filter)
    
    % perform convolution of the random image with the cross template
    result = conv2(im,filter,'same');
    
    % get the number of white pixels in filter
    filSum = sum(filter(:));
    
    % look for all points in the convolution results that matched identically to the filter
    matches = find(result == filSum);
    
    %validate all points found
    sort(matches(:)) == sort(points(:))
    % get x and y coordinate matches
    [xMatch,yMatch] = ind2sub(size(im),matches);
    

    I would highly suggest looking at the conv2 documentation on MATLAB's website.

    0 讨论(0)
提交回复
热议问题