Draw Circle on Image Java Frc Without Opencv
Profile Features¶
By this time, yous should have an image that looks like this
but in all reality, your prototype probably looks something like this
Nosotros recommend you utilize "findcontours" for your border detector. Information technology is a rather sometime algorithm, but it is very effective as well as fast. Here is code that calls findcontours and draws them onto an image. Make certain that the paradigm yous are cartoon to is RGB and not GrayScale if you desire to depict things in colour.
List < MatOfPoint > contours = new ArrayList < MatOfPoint >(); Mat hierarchy = new Mat (); Imgproc . findContours ( img , contours , hierarchy , Imgproc . RETR_EXTERNAL , Imgproc . CHAIN_APPROX_NONE ); for ( int i = 0 ; i < contours . size (); i ++) { //...contour code here... }
vector < vector < Indicate > > contours ; vector < Vec4i > hierarchy ; findContours ( img , contours , hierarchy , CV_RETR_EXTERNAL , CV_CHAIN_APPROX_NONE , Point ( 0 , 0 )); for ( size_t i = 0 ; i < contours . size (); i ++ ) { drawContours ( depict , contours , i , Scalar ( 255 , 0 , 255 ), three , 8 , hierarchy , 0 , Point () ); }
img2 , contours , hierarchy = cv2 . findContours ( img , cv2 . RETR_TREE , cv2 . CHAIN_APPROX_NONE ) for contour in contours : cv2 . drawContours ( draw , [ profile ], 0 , ( 255 , 0 , 255 ), iii )
CHAIN_APPROX_NONE is a flag that tells findContours to shop every contour point - including contours within other contours, or multiple forth the same line. If you don't have the strongest of computers (like a Pi), I recommend using CHAIN_APPROX_SIMPLE because it compresses horizontal, vertical, and diagonal segments and leaves only their terminate points.
Moving forward, this is where you lot must go creative. If y'all have contours that are not wanted, you lot must come up with tests that volition pass on the contours that you lot want, merely fail on the ones you lot practice non wish to proceed.
An implementation note: The following tests are meant to be implemented in a for loop, where the developer is looping through every profile.
for ( int i = 0 ; i < contours . size (); i ++ ) { //contours.get(i).... }
vector < vector < Point > > contours ; for ( size_t i = 0 ; i < contours . size (); i ++ ) { //contours[i] .... }
for contour in contours : # do stuff with profile....
Contour Area¶
A quick and easy manner to filter out pocket-sized contours is to check their area. Found a minimum and maximum area, which volition probably have to be plant empirically, and check to see if the profile's area falls within that range.
double contourArea = Imgproc . contourArea ( contour ); if ( contourArea < min_area || contourArea > maxArea ) { go along ; }
float contourArea = contourArea ( contours [ i ]); if ( contourArea > maxArea || contourArea < minArea ) { proceed ; }
contourArea = cv2 . contourArea ( contour ) if contourArea < minArea or contourArea > maxArea : continue
For code readability, I prefer to do that go on approach when looping through contours, instead of nested every contour examination. It makes the code more readable, as well makes the programmer have to worry about counting an absurd amount of curly brackets.
Aspect Ratio¶
Aspect Ratio refers to the ratio between the contour'due south width / contour's height. To do this, one could detect the extreme points, but information technology is easier to apply a bounding rectangle and and so compute the ratio of the divisional rectangle.
Rect boundRect = Imgproc . boundingRect ( contour ); float ratio = ( float ) boundRect . width / boundRect . height
Rect boundRect = boundingRect ( contours [ i ]); bladder ratio = ( float ) boundRect . width / boundRect . height
x , y , w , h = cv2 . boundingRect ( contour ) ratio = float ( west ) / h
Remember to cast to float, otherwise integer sectionalization will occur and you won't go precise ratios.
Solidity¶
The terminal examination nosotros will cover is solidity. That is, the ratio between the contour expanse and the bounding rectangle expanse. This is useful to determine the "rectangle-ness" of the profile. The more than closely the bounding rectangle fits the contours, the closer this ratio will exist to i.
Rect boundRect = Imgproc . boundingRect ( contour ); float ratio = Imgproc . contourArea ( contour )/( boundRect . width * boundRect . top )
Rect boundRect = boundingRect ( contours [ i ]); bladder ratio = contourArea ( contours [ i ]) / ( boundRect . width * boundRect . height );
x , y , w , h = cv2 . boundingRect ( contour ) ratio = cv2 . contourArea ( contour ) / ( w * h )
Finding the middle¶
In typical FRC mode, y'all want your robot to line upwardly with the center of the target (contour). In order to do this, one must first detect the center. Here is how to discover the center using bounding rectangles. CenterX is the centre x coordinate and CenterY is middle y coordinate.
Rect boundRect = Imgproc . boundingRect ( profile ); double centerX = boundRect . x + ( boundRect . width / 2 ) double centerY = boundRect . y + ( boundRect . height / 2 )
Rect boundRect = boundingRect ( contours [ i ]); double centerX = boundRect . x + ( boundRect . width / ii ) double centerY = boundRect . y + ( boundRect . height / 2 )
x , y , w , h = cv2 . boundingRect ( contour ) double centerX = boundRect . x + ( boundRect . w / two ) double centerY = boundRect . y + ( boundRect . h / 2 )
While yous could simply apply a divisional rectangle and so observe the center of that, there is a more precise way: Northward-th order moments. Mathematically, a moment is defined every bit \(\mu _{n}=\int _{-\infty }^{\infty }(ten-c)^{n}\,f(x)\,dx\). For a 2nd continuous role f(x,y) the moment of society (p + q) is divers equally \(M_{{pq}}=\int \limits _{{-\infty }}^{{\infty }}\int \limits _{{-\infty }}^{{\infty }}x^{p}y^{q}f(ten,y)\,dx\,dy\). The area of a contour is the zeroth moment, and moments can exist used to find the centroid of a contour. The centroid is the center of mass of an object. The centroid point is also the center of gravity. Using moments, the centroid, C is defined as \(C_x = M_{x} / M_{00}\) and \(C_y =M_{01} /M_{00}\).
Moments k = Imgproc . moments ( contour ); double centerX = m . get_m10 () / yard . get_m00 (); double centerY = thousand . get_m01 () / m . get_m00 ();
cv :: Moments moment = cv :: moments ( contours [ i ]); cv :: Indicate center = cv :: Point2f ( moment . m10 / moment . m00 , moment . m01 / moment . m00 );
moments = cv2 . moments ( contour ) centerX = int ( moments [ 'm10' ] / moments [ 'm00' ]) centerY = int ( moments [ 'm01' ] / moments [ 'm00' ])
Notation that in previous years for FRC, in that location hasn't been a vision challenge where the vision assistance tape wasn't symmetrical. But in hereafter if the tape isn't symmetrical, you would need to consider whether the centroid is what yous desire.
Drawing¶
A very useful function is drawing the contours on your images. While you can draw every profile using the -ane flag, instead of the contour index, information technology is recommended you only draw the contours that pass all your tests. This allows for fast and effective debugging.
for ( int i = 0 ; i < contours . size (); i ++) { //Tests.... Imgproc . drawContours ( contourImg , contours , i , new Scalar ( 255 , 255 , 255 ), - 1 ); }
for ( size_t i = 0 ; i < contours . size (); i ++ ) { //Tests... drawContours ( draw , contours , i , Scalar ( 255 , 0 , 255 ), iii , 8 , hierarchy , 0 , Point () ); }
for profile in contours : #Tests... cv2 . drawContours ( describe , [ contour ], 0 , ( 255 , 0 , 255 ), 3 )
Putting it all together¶
While other contour tests can be done, such every bit approximating a polygon around a contour, this a a good basis that should permit you to solve just near every FRC computer vision claiming. Hither is a quick rundown of the tests needed to successfully solve the vision challenges over the years:
Year | Tests |
---|---|
2012 | Area, Solidity |
2013 | Expanse, Solidity, Aspect Ratio |
2014 | Expanse, Solidity |
2015 | Area, Solidity |
2016 | Area, Solidity |
2017 | Area, Solidity |
Equally you tin can see, nearly every FRC vision challenge can exist solved with a simple expanse and solidity test.
Hither is an case of what a last prototype for 2017 with contours drawn on the prototype might look like.
Source: https://frc-pdr.readthedocs.io/en/latest/vision/contours.html
0 Response to "Draw Circle on Image Java Frc Without Opencv"
Post a Comment