Counting the squama of lizards
P

1

10

A biologist friend of mine asked me if I could help him make a program to count the squama (is this the right translation?) of lizards.

He sent me some images and I tried some things on Matlab. For some images it's much harder than other, for example when there are darker(black) regions. At least with my method. I'm sure I can get some useful help here. How should I improve this? Have I taken the right approach?

These are some of the images.

pic1

pic2

I got the best results by following Image Processing and Counting using MATLAB. It's basically turning the image into Black and white and then threshold it. But I did add a bit of erosion.

Here's the code:

img0=imread('C:...\pic.png');

img1=rgb2gray(img0);

%The output image BW replaces all pixels in the input image with luminance greater than level with the value 1 (white) and replaces all other pixels with the value 0 (black). Specify level in the range [0,1]. 
img2=im2bw(img1,0.65);%(img1,graythresh(img1));

imshow(img2)
figure;

 %erode
 se = strel('line',6,0);     
 img2 = imerode(img2,se);
 se = strel('line',6,90);   
 img2 = imerode(img2,se);
 imshow(img2)
figure;

imshow(img1, 'InitialMag', 'fit')

% Make a truecolor all-green image. I use this later to overlay it on top of the original image to show which elements were counted (with green)
 green = cat(3, zeros(size(img1)),ones(size(img1)), zeros(size(img1)));
 hold on
 h = imshow(green); 
 hold off


%counts the elements now defined by black spots on the image
[B,L,N,A] = bwboundaries(img2);
%imshow(img2); hold on;
set(h, 'AlphaData', img2)
text(10,10,strcat('\color{green}Objects Found:',num2str(length(B))))
figure;



%this produces a new image showing each counted element and its count id on top of it.
imshow(img2); hold on;
colors=['b' 'g' 'r' 'c' 'm' 'y'];
for k=1:length(B),
     boundary = B{k};
     cidx = mod(k,length(colors))+1;
     plot(boundary(:,2), boundary(:,1), colors(cidx),'LineWidth',2);
     %randomize text position for better visibility
     rndRow = ceil(length(boundary)/(mod(rand*k,7)+1));
     col = boundary(rndRow,2); row = boundary(rndRow,1);
     h = text(col+1, row-1, num2str(L(row,col)));
     set(h,'Color',colors(cidx),'FontSize',14,'FontWeight','bold');
end
figure; 
spy(A);

And these are some of the results. One the top-left corner you can see how many were counted.

Also, I think it's useful to have the counted elements marked in green so at least the user can know which ones have to be counted manually.

enter image description here

Prolix answered 2/4, 2014 at 7:52 Comment(4)
I wish I had more time to spend on this problem! Sounds really interesting! I would start with sharpening the image and then trying to detect lines(using hough transform for intanse) as it seems there are usually straight lines separating the squama. It may be worth it also to invert the images for some cases as there are black squameFragrance
I hadn't thought about using line detection! I will give it a try and update :) Thanks @IvayloStrandjevProlix
You can try both local contrast enhancement filters and Canny edge detecting algorithmCrutch
I have some doubts about the Hough approach, it's better suited for straight or circular features.Sneaker
S
6

There is one route you should consider: watershed segmentation. Here is a quick and dirty example with your first image (it assumes you have the IP toolbox):

raw=rgb2gray(imread('lCeL8.jpg'));

Icomp = imcomplement(raw);
I3 = imhmin(Icomp,20);
L = watershed(I3);
%%
imagesc(L);
axis image

Result shown with a colormap:

watershed

You can then count the cells as follows:

count = numel(unique(L));

One of the advantages is that it can be directly fed to regionprops and give you all the nice details about the individual 'squama':

r=regionprops(L, 'All');
imshow(raw);

for k=2:numel(r)
    if r(k).Area>100 % I chose 100 to filter out the objects with a small are.
        rectangle('Position',r(k).BoundingBox, 'LineWidth',1, 'EdgeColor','b', 'Curvature', [1 1]); 
    end
end

Which you could use to monitor over/under segmentation: bounding boxes

Note: special thanks to @jucestain for helping with the proper access to the fields in the r structure here

Sneaker answered 2/4, 2014 at 13:49 Comment(3)
That works so much better specially in the bottom part! :) thanks a lot. I just tried it here.Prolix
@Prolix you're welcome. By the way, I used one of your images as an example in another post: https://mcmap.net/q/1167560/-matlab-create-window-on-image I hope it's ok.Sneaker
No problem! Make the lizards famous !:)Prolix

© 2022 - 2024 — McMap. All rights reserved.