Search code examples
matlabimage-processingfiltershapesbest-fit-curve

Smooth and fit edge of binary images


i am working on a research about the swimming of fishes using analysis of videos, then i need to be carefully with the images (obtained from video frames) with emphasis in the tail.

The images are in High-Resolution and the software that i customize works with binary images, because is easy to use maths operations on this.

For obten this binary images i use 2 methods:

1)Convert the image to gray, invert the colors,later to bw and finally to binary with a treshold that give me images like this, with almost nothing of noise. The images sometimes loss a bit of area and doesn't is very exactly with the tail(now i need more acurracy for determinate the amplitude of tail moves) image 1

2)i use this code, for cut the border that increase the threshold, this give me a good image of the edge, but i dont know like joint these point and smooth the image, or fitting binary images, the app fitting of matlab 2012Rb doesn't give me a good graph and i don't have access to the toolboxs of matlab.

s4 = imread('arecorte.bmp');
A=[90 90 1110 550]
s5=imcrop(s4,A)
E = edge(s5,'canny',0.59);

image2

My question is that

how i can fit the binary image or joint the points and smooth without disturb the tail?

Or how i can use the edge of the image 2 to increase the acurracy of the image 1?

i will upload a image in the comments that give me the idea of the method 2), because i can't post more links, please remember that i am working with iterations and i can't work frame by frame.

Note: If i ask this is because i am in a dead point and i don't have the resources to pay to someone for do this, until this moment i was able to write the code but in this final problem i can't alone.


Solution

  • I think you should use connected component labling and discard the small labels and than extract the labels boundary to get the pixels of each part

    the code:

    clear all
    
    % Read image
    I = imread('fish.jpg');
    
    % You don't need to do it you haef allready a bw image
    Ibw = rgb2gray(I); 
    Ibw(Ibw < 100) = 0;
    
    % Find size of image
    [row,col] = size(Ibw);
    
    % Find connceted components
    CC = bwconncomp(Ibw,8);
    
    % Find area of the compoennts
    stats = regionprops(CC,'Area','PixelIdxList');
    areas = [stats.Area];
    
    % Sort the areas
    [val,index] = sort(areas,'descend');
    
    % Take the two largest comonents ids and create filterd image
    IbwFilterd = zeros(row,col);
    IbwFilterd(stats(index(1,1)).PixelIdxList) = 1;
    IbwFilterd(stats(index(1,2)).PixelIdxList) = 1;
    imshow(IbwFilterd);
    
    % Find the pixels of the border of the main component and tail
    boundries = bwboundaries(IbwFilterd);
    
    yCorrdainteOfMainFishBody = boundries{1}(:,1);
    xCorrdainteOfMainFishBody = boundries{1}(:,2);
    linearCorrdMainFishBody = sub2ind([row,col],yCorrdainteOfMainFishBody,xCorrdainteOfMainFishBody);
    
    yCorrdainteOfTailFishBody = boundries{2}(:,1);
    xCorrdainteOfTailFishBody = boundries{2}(:,2);
    linearCorrdTailFishBody = sub2ind([row,col],yCorrdainteOfTailFishBody,xCorrdainteOfTailFishBody);
    
    % For visoulaztion put color for the boundries
    IFinal = zeros(row,col,3);
    IFinalChannel = zeros(row,col);
    
    IFinal(:,:,1) = IFinalChannel;
    
    IFinalChannel(linearCorrdMainFishBody) = 255;
    IFinal(:,:,2) = IFinalChannel;
    
    IFinalChannel = zeros(row,col);
    IFinalChannel(linearCorrdTailFishBody) = 125;
    IFinal(:,:,3) = IFinalChannel;
    imshow(IFinal);
    

    The final image: enter image description here