4

Okay guys, I think I have done everything I can except one important thing: Shape Extraction. I already do this fairly in a fairly simple way, but there are some cases where it really messes up. The way I do this is:

  • Pick a point in the outline list by generating a bounding rectangle and selecting the closest point to the top left (Point p).
  • Create a new Shape object and add p to the shape's outline.
  • If the main picture has no more points available for us to test, we simply return the shape object.
  • Get a closest point from p and store it in closest.
  • while the distance from the closest
    point to p point is less than or
    equal to ten
  • ----Add it to the outline
  • ----Remove it from the master point list
  • ----Set p to closest
  • ----Get another closest point from closest
  • ----Repeat
  • If the shape has ten points or less in its outline, return a null object (ignore all small shapes)
  • Otherwise, return the shape object.

I repeat this process until the main point list becomes empty. This means we extracted all the shapes.

Now I do a combine shapes several times. This makes it so if I have |, ---, and | next to each other, it will combine to create a rectangle. Do you understand what I mean? Lets say I have a circle, the above extracting code will sometimes say half of the circle is one shape, and the other half is another shape. So when I combine the shapes, it becomes one circle.

Sigh, I cannot post pictures too and I cannot upload this anywhere but an uploading site. This has some issues. Take a look at the following:

enter image description here

The picture on the left is the starting picture, and the one on the right is the outline points. Now I click the determine shape button. It determines the shape of the most dominant shape in the picture (the shape object that contains the most points in its outline).

enter image description here

Now, it correctly says this is a quadrilateral but for the wrong reasons. Due to my combine shapes (which needed to be done in order to even get a rectangle shape otherwise it will be a small line for one shape and another small line as another shape), it added the outline of the fingers to the testing.

So the entire single shape (the black outline to the right in the second picture) is tested. Not just the "rectangle" part, but everything in that picture is tested. Can you guys think of any way to clean this thing up and extract JUST the rectangle portion instead of having the fingers included? I was thinking of some variation of A* for this, but in a case like this picture, it does not create a loop. So what do I do once A* visits every single point (since it cannot return to the starting point). What do I do then?

Can anybody help me try to get this figured out please?

Kara
  • 6,115
  • 16
  • 50
  • 57
Nathan
  • 251
  • 1
  • 2
  • 4
  • Hi, I think a little more information is needed. How do you create the outline list? What exactly are you trying to separate (big black rectangle in the photo, the object on the foreground, all edges of all objects)? – Binus Apr 12 '11 at 21:42
  • My code is about 700 lines. Do you really want me to go through every single part of it? My goal is to just get the shape of the most dominant object in the picture. So one rectangle is what I should get. – Nathan Apr 12 '11 at 21:44
  • OutlineLines method is where I get the main outline: https://phstudios.svn.beanstalkapp.com/c458/trunk/Project/CSharpRobotImaging/LineRecognition/Form1.cs – Nathan Apr 12 '11 at 21:45
  • Sorry, I later realized it was in the tittle :). And do you plan to use it for searching for black rectangles, or various objects with one color or even objects with multiple colors? – Binus Apr 12 '11 at 21:49
  • Color will not matter. I just have that for visual representations. I just basically have List outline. They will not be colored. I basically have everything all finished, except a proper "cleanup/extraction" algorithm. As you notice the fingers are added to the list of points. I need to stop that from happening, and I also need it to work for all shapes, rotations, distortions, and sizes. – Nathan Apr 12 '11 at 21:50

1 Answers1

1

I think the following part of your code is not so wise:

    int iSelected = selected.ToArgb();
    int iNextRight = nextRight.ToArgb();
    if (Math.Abs(iSelected - iNextRight) > alpha)

because the result is you compare almost only against red color (the others are stored in less significant bites) assuming you don't use alpha in the images.

If you want to achieve better results, you can use Canny Edge Detector or at least take a look at its processing steps.

Other option is to use feature similar to magic wand to separate main object from the background and later extract its edges. For that purposes for example potts model can be used.

If you want something simpler what about detect edges the way yo do it, but use sum of difference of all color channels. Then assume that the point in the middle is part of searched object and fill the shape between nearest edges like paintbrush. If you choose right treshold you will eliminate those fingers.

I wish you good luck.

Binus
  • 1,065
  • 7
  • 14
  • You think the issue is with the outline detection instead of the shape extraction? – Nathan Apr 12 '11 at 22:20
  • It is much easier to extract the shape with good outliers. I think you cannot simply connect the outliers, because than the fingers will be always selected. – Binus Apr 12 '11 at 22:53
  • What if, while I am getting the outline, convert the selected color to grayscale and do the basic algorithm that way. Would that work out better than what I have it at now? – Nathan Apr 12 '11 at 22:56
  • And what about image segmentation? You can connect neighbor pixels having similar colors to flat object. Then find the largest central object and classify the shape of its edge. – Binus Apr 12 '11 at 22:57
  • So do you think I should take color into account during the shape extraction phase as well? What if the shape has a green label on it or something? – Nathan Apr 12 '11 at 23:00
  • I think converting to grayscale would work in this particular case, but generally it is better to count with all the components. If you want to simulate human eye, you can weight the components so the contrast will be _0.2989 * abs(R1-R2) + 0.5870 * abs(G1 - G2) + 0.1140 * abs(B1 - B2)_ – Binus Apr 12 '11 at 23:04
  • And you think that will help my outline generation or shape extraction? I just want to know where I should spend my time. Should I do that in both just to be safe? – Nathan Apr 12 '11 at 23:07
  • If you use the segmentation and the sticker will be small and surrounded by the searched shape, you will be able to integrate it to the shape. Otherwise you will run into troubles. Generally it is hard for computer to select one object if it has multiple colors and the background is not solid as well... – Binus Apr 12 '11 at 23:10
  • Thats where my shape extraction will be beneficial I hope. It ignores all the small shapes that are from the artifacts or bad image quality. Maybe instead of having a List outline, would a List outline be better? That way when I do the shape extraction and look at the closest point, I can compare the color values as well? If a ColorPoint of color White is right next to a ColorPoint of color black, it should not be in the same shape correct? Basically taking what I have in my screen shots, but they will not all be red. – Nathan Apr 12 '11 at 23:14
  • This is not a good idea, because the color of outline can change if background changes. This is why I think it would be better to segment the image to solid shapes and then detect some large object in central part of the image and consider its outer border as a shape you are looking for. And a little of Gaussian blur before processing can help you rid of the noise. – Binus Apr 12 '11 at 23:20
  • Okay so I think I see what you are saying. You are saying if I come across a point and look at another point. If the color values differ by a certain amount, change one to reflect the other one's color? That way it will eliminate some of the quality issues as well? Also, how would the background change? This would just be a static picture test. – Nathan Apr 12 '11 at 23:27
  • The color of the edge of some object is a mixture of the object's color and background color. So if you are following the edge and the background changes, the edge changes as well. This is why I think some segmentation-based method would be more appropriate. – Binus Apr 13 '11 at 00:15
  • What do you suggest for a segmentation-based method? This has to work for all distortions, rotations, and shapes. So is there a way to segment it to where it will work for all cases? – Nathan Apr 13 '11 at 00:18
  • You cannot create simple algorithm capable of finding one main object on photo, because it would require finding the object in some kind of object database and projecting it back. However you should be able to find object satisfying some simple constraint. For example having the same color, having only smooth color change or having the same texture on the surface. What I suggest is to perform some kind of clustering (K-Means, hierarchical) based on color and location. Then take significant clusters near the center, pronounce them to be the object, add inner objects and then extract the border. – Binus Apr 13 '11 at 09:36
  • I cannot create some kind of database though. Would a cluster based approach work though? I have seen cases where it displays something like | |. So that is very far away according to a cluster based approach. – Nathan Apr 13 '11 at 20:08
  • What do you mean by ||? If you are asking about clustering two parallel lines than it is better to use _Single Link_ algorithm instead of _k-means_. For your purposes the _Single Link_ will be almost always better. – Binus Apr 13 '11 at 23:02