0

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.

JVidal
  • 3
  • 6
  • http://i.stack.imgur.com/6hmSe.jpg – JVidal Sep 13 '16 at 04:32
  • Don't use canny edge detector for this, its an algorithm for grayscale images, not black and white images. Use `bwperim` http://uk.mathworks.com/help/images/ref/bwperim.html – Ander Biguri Sep 13 '16 at 08:42
  • If that does not include the tail, dilate and erode the image with the same kernel first. https://uk.mathworks.com/help/images/morphological-dilation-and-erosion.html – Ander Biguri Sep 13 '16 at 08:44
  • Thanks you for the advice! I use bwperim (with 6 8 18 26 conn) for bw images and the result is a image with a lot of noise . Now i use the canny edge in gray images without invert and i filled the image, but the images doesn't better than the image1. http://imgur.com/XUr5mp7 O = imread('imagen0001.bmp'); E = edge(O,'canny',0.59); se = strel('disk',4); Ec=imclose(E,se); Ecf=imfill(Ec,'holes'); http://imgur.com/K92CnNR – JVidal Sep 13 '16 at 18:51
  • I am thinking in better work with the image1, but for 300+ images the threshold doesn't works very good and the automatic treshold is inexactly _l=graythresh(ima)_ i use _ima2=im2bw(ima,l)_ to transform bw to binary but i don't know alternatives or like optimize this function – JVidal Sep 13 '16 at 18:52

1 Answers1

0

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

Amitay Nachmani
  • 3,259
  • 1
  • 18
  • 21
  • Thanks you for the answer! When i run, matlab show me the message "Attempted to access index(1,2); index out of bounds because numel(index)=1." and i noticed that CC.NumObjects=1 by that i change the line8 from "<" to ">" and the code runs without problem I try with a lot of images and compare with the _bwbwlabel_ image method and the tail position is very exactly!; but i have a problem, the code doesn't works very fine for all the situations, the images that looks good "in 1 area" (almost all) like this (http://imgur.com/a/rNaVe) have a bad representation (http://imgur.com/a/0DZRg) – JVidal Sep 15 '16 at 05:32
  • Now i need to fill the image (with imfill(_'holes')) for use the maths operations of my code but (all works according to the 'area' and 'orientation'), How i can fix the code for that works fine with all the situations? a distance check? almost all the another noise appear at the other side of the image, this is the worst case for that code, in the moment that i can solve this problem and will run with 1000 images and share the result :D i am very thankful to you. – JVidal Sep 15 '16 at 05:35
  • Regarding the representation have you looked with a zoom on the area? The reason why far a way it looks incomplete is probably because of the resolution of the figure but if you zoom i think you will see it is fine – Amitay Nachmani Sep 15 '16 at 06:10
  • Yes, the representation is with zoom, the area is close and i can fill without problems http://imgur.com/a/aA3dy, but in the image appear an area that doesn't from the fish and now i need to filter them and that the program recognize when is part of the fish and when doesn't http://imgur.com/a/RMXfs – JVidal Sep 15 '16 at 11:06
  • I understand. So yes a distance check sounds like a good solution – Amitay Nachmani Sep 15 '16 at 11:40
  • i have a question, why dont works with images like this?https://www.dropbox.com/sh/xve7oe84xcfj9yt/AACA0dYrK_m7o8Oie0KWWR-2a?dl=0 the 2m_FLXXXX images :( – JVidal Oct 02 '16 at 00:25