|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
|||
|
|||
|
Re: Help with Locating Disks with Vision
I think what is going on is that the tutorial you are following uses a very accurate, but very unforgiving method of locating colored objects. It assumes that you have very good control over the type and amount of light, distance to the object, etc.
I'm sure that you can write simple color threshold code to locate a frisbee, and you can do a few additional particle measurements to see if it is round. This approach will be more forgiving in varied lighting conditions. Even then, make sure to follow the recommendations in the white paper regarding camera white balance setting, compressions, focus, etc. Greg McKaskle |
|
#2
|
||||
|
||||
|
Re: Help with Locating Disks with Vision
Quote:
The steps: Acquire image Convert it to HSV (hue, saturation, and value) (Binary) Threshold image to locate only the desired colour (red, white blue) This is where vision programming has a lot of diversity... We found the contour of an image, that is, where black meets white. Approximate a polygon (I promise I will make this better before next build season for squares for teams that want to do pose) then I said if (result > 5)) [ it's a circle; } result being the amount of sides of the contour. From then, you ideally should have located the circle. To find the center: // Calculate the moments to estimate the position of the frisbee CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments)); cvMoments(*yourcontourhere*, moments, 1); // The actual moment values double moment10 = cvGetSpatialMoment(moments, 1, 0); double moment01 = cvGetSpatialMoment(moments, 0, 1); double area = cvGetCentralMoment(moments, 0, 0); posX = moment10/area; posY = moment01/area; This gives subpixel accuracy for the center Now you have the center of a frisbee based off the specified colour. Congrats. BUT, what if there was more than 1 of the same coloured frisbee? This simple algorithm solves this problem (keep in mine that I used opencv and changed the center from the top left to the center of the screen to make the logic easier) Int prevclosestfrisbee = 300 (arbitary pixel value that is high on the screen. *note the greater the y pixel value, the further it will be away.) if (frisbee.y < prevclosestfrisbee) { prevclosestfrisbee = frisbee.y } else { contours = contours ->h_next: } after you go through all the contours (the frisbees that passed the threshold test and the approximate polygon test, then you're left with one with the lowest y value. **note, you can do this with all 3 coloured frisbees, I posted an image on here of a frame while tracking all 3 disks. It does take a fairly large amount of processing power (this program ran ~13 fps while the program that tracked the alliance wall ran at ~27, but it is do able!) Hope this helped! |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|