Ask Your Question

Trouble finding a way to differentiate two shapes

asked 2014-04-28 04:43:45 -0500

Yaoming gravatar image

updated 2016-05-21 14:13:44 -0500


I am trying to automatically detect fishes in an underwater environment. I have this type of image (after having preprocessed the video input):

image description

Clearly the fish shape has less edges than the bottom algae one. Basically what I would like to do is to either be able to get the aspect of my contour or to get the number of edges of each contours to differentiate my fish from my algae.

Do you have any idea of how I could do that using Python ?
Do you have any other suggestions on how I could differentiate these two shapes ?

Thanks in advance for your answers.

edit retag flag offensive close merge delete


Given that fish can be at odd angles I would think looking for color would be a better place to start.

GrumbleLion gravatar imageGrumbleLion ( 2014-04-28 14:43:20 -0500 )edit

maybe have a look at moments and matchShapes

berak gravatar imageberak ( 2014-04-28 14:57:15 -0500 )edit

I do think so yes. Don't have a system here to check it out for you.

StevenPuttemans gravatar imageStevenPuttemans ( 2014-04-29 04:54:34 -0500 )edit

Colors are not usable since I am in an underwater environment (which means a lot of lighting variations). Working with the inner pixels is cool but once again I'll always have one algae that'll be taken by my algorithm. Basically, every algae are very different from the fishes but I don't know how I could use that in real-time. There's no openCV function that simply says if a shape is smooth or not?

Yaoming gravatar imageYaoming ( 2014-04-30 05:15:43 -0500 )edit

I just tried switching the color space but the results are not good. The detection is less precise. Anyway I've got a thresholded image and I'm quite happy with the results I have. The last thing I need to do is removing the remaining noise now and then. Colors ain't help me for that, or I might have misunderstood what you implied. If you had the exact image I put in my question, and were asked to show only the fish, how would you do?

Yaoming gravatar imageYaoming ( 2014-04-30 05:56:29 -0500 )edit

I will think about it and get back to you!

StevenPuttemans gravatar imageStevenPuttemans ( 2014-04-30 07:39:28 -0500 )edit

Actually with water flow, the algae are moving as well. And I use background subtraction + thresholding + findContours + moments + arcLength + other not OpenCV things to get here. So I've already used the movement. And describing how smooth the edge of my objects contours are is what I'm trying to do now.

Yaoming gravatar imageYaoming ( 2014-04-30 08:45:25 -0500 )edit

2 answers

Sort by ยป oldest newest most voted

answered 2014-05-02 02:20:00 -0500

Combined replies that led to the solution of this problem.

First a summation of the hints leading up to the solution:

  1. If you apply findContours, you retrieve a list of points. An irregular shape will probably have way more points since the border variance is larger. Try it out? As to color, that will only work if the lighting conditions are controlled.
  2. What you could do now, only if your fishes have a large contrast to the algea is for each contour look at all the inner pixels and do some measurements in them. Specifying average color values for example could be used with a simple classifier to decide if it is a fish or not.
  3. If you go into color spaces like HSV or Lab you could easily avoid the large influence of lighting variations.
  4. There should be a way of describing how smooth the edge contours of your objects are. There is way more variation in your plants then in your fish contour. What you could also do is use movement. An algae will stay aproximately static in subsequent frames, while a fish will move around. This could be a fast way to ignore static regions.
  5. Yeah they do move, but their movement is in a stationary region, while the fish can swim around in the image. The algae is somewhere connected to the ground right?

The solution that was implemented:

Well I do this in my spare time so basically programming code for others I do not do nor do I encourage it. Feel free to give it a try and report back with results and problems. I will hapily look into them. I suggest trying something like:

  • Detect the x and y center position of each object
  • Keep a list of lets say 15 frames.
  • Check the variance on the x and y coordinates over these frames
  • Define a threshold, if it is higher, then it is a fish and you keep the detection, if not all detections in that area are due to the algae and you do not visualize detections there anymore.
edit flag offensive delete link more


As an addition - removed all the remarks to clean up the discussion part :) might want to do so too and summate your remarks beneath here? I suggest removing your it is solved answer also or fill it up with the solution itself.

StevenPuttemans gravatar imageStevenPuttemans ( 2014-05-02 02:21:42 -0500 )edit

answered 2014-05-01 05:37:27 -0500

Yaoming gravatar image

updated 2014-05-02 03:35:21 -0500

Problem solved thanks to Steven and his very nice idea! Indeed, he thought about something which is very simple but that I didn't see: algaes are attached to the ground and fishes aren't. Meaning that if we compare the x coordinate of each center of each shapes, we can deduce what's a fish and what's not.

To help those having a similar problem here's how I did it using openCV.

The solution, in details

First, you need to get the contours of your image/video frame (using findContours on a thresholded image).

Second, you need to get the openCV moments for each shape (simply go through your contours returned vector and apply the moments function each time). You can now easily calculate the center of each contours and put it in a list so that you can calculate the variance (have a look at the doc)

Then I created another list to keep the x-variance between each center. By "variance" I mean a simple subtraction (coordX[i] - coordX[i-1] with i running from 1 to (your list length - 1)).

And basically after that you only need to set a threshold and if your variance is higher, then it's a fish (because it moved more than the algae).

Other ideas

I also tried to work with colors but with the sudden and unpredictable lighting condition in an underwater environment, didn't get nice results. Getting the number of edges for each shapes was a good idea as well but not radical enough (I still had algae here and there on my video). Using the solution described above, I have exactly what I wanted :)

Thanks again for helping me, I hope this will help future students :)

edit flag offensive delete link more



Please detail your answer with how you solved your problem.

Will Stewart gravatar imageWill Stewart ( 2014-05-01 10:43:54 -0500 )edit

I will place my comments in a answer. Since it provided the solution, please do accept it as the answer to this topic.

StevenPuttemans gravatar imageStevenPuttemans ( 2014-05-02 02:16:54 -0500 )edit

Thanks for the input and solution!

StevenPuttemans gravatar imageStevenPuttemans ( 2014-05-02 03:27:21 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower


Asked: 2014-04-28 04:43:45 -0500

Seen: 796 times

Last updated: May 02 '14