Circle detection, line detection,
measurements using cameras
Computer vision systems in robotics very frequently use circle or line detection algorithms. In this lecture you will learn how to set up circle detection, line detection, and how to use line detection to measure objects.
Figure 1 - At the end of this lecture your camera will be able to see all details about lines and circles
- USB camera connected to your PC
- Ozeki Pole: http://www.ozeki.hu/index.php?owpn=6276
- Ozeki 10 installed: http://www.ozeki.hu/index.php?owpn=6066
- Lego connection installed: http://www.ozeki.hu/index.php?owpn=6067
- Snap basics: http://www.ozeki.hu/index.php?owpn=6180
Setup Line detection connection!
The number of pieces or the holes of the Pole can be easily calculated if you can detect the lines on it. For that you only have to create a connection in Ozeki 10, that can detect lines. So, after you opened Control Panel, just click on Create new connection. Here you need to choose the icon of Video method, and after that just select the Vision connection (Figure 2).
Figure 2 - Video connections in Ozeki 10
From the Vision type of connections to detect lines, you have to select the Line connection. Lastly, before you finish the creation, you can set the name of the connection, select the camera that you connected, and you can also set the resolution and the frame rate (Figure 3). In the Vision tab you can set the sensing delay of the camera, and you can also save the detected line as a snapshot.
Figure 3 - Connection details of Line detection connection
To make sure that all the message will arrive to SNAP, you need to create a route in Control Panel, that can steer the information, from one connection to another one. So, select the Routes menu, and click on Create new Route. Here you need to select the Line detection connection, where the messages comes from, and set the SNAP application where the messages will arrive (Figure 4).
Figure 4 - Route creation from the connection to SNAP
Measure the length of one piece/hole with the line detector!
The number of holes will be calculated by the length of the whole Lego piece. For that you need to know, how long is one hole, because you will use this value for the further calculations. So, open the Line detection connection, and place the Pole in front of the camera like in Figure 5. With that only the length of one hole can be detected, so the results will be quite accurate. After the camera detected the line, select the Detected tab, where you can see the details of the detected lines, and you can note the length of a hole. In this example this will be 43.
Figure 5 - Length of one hole measured with the line detector
Write code to store information about the detected lines!
After you measured the length of one hole, you can turn your attention to write the code in SNAP. So, here first you have to drag the 'When green flag clicked' block. After that to collect the information from the Line detection connection drag the 'Get next message' block. After you got the message you need to store it into a variable. That variable will be 'message', so please create it and with the 'Set 'message' to message value (string)' save the message there. To handle this message simpler, you need to split that. So, create a variable with the name 'lineInfo', and with the 'Set' block split it by commas as you can see in Figure 6.
Figure 6 - Message split by commas
Expand code to store the minimum and maximum X values!
The main method of this code will be that to calculate the number of holes on the Pole from the minimum and maximum X values of the line that was detected. So, first you need to create two variables, and give them the names, 'minX' and 'maxX'. In the 'lineInfo' list, the valuable information can be found in the first and the third item of the list, and both of them placed next to an equality sign. So, you can split them easily by that sign. So, please drag the 'Set' block, and select the 'minX' variable. Next to it, place the 'item of' block, because you have to select the second item of the splitted item 1 of 'lineInfo' variable as you can see in Figure 7. You need to do the same for the 'maxX' variable, but now you need to split the third item of the 'lineInfo' list.
Figure 7 - Endpoints of the line stored
Calculate the total length of the line!
After you stored the minimum and maximum X values of the detected line, the calculation of the length is now just an easy subtraction. To store that length, first create a variable with the name 'length'. Then with a 'Set', as you can see in Figure 8 with a '-' operator subtract the 'minX' variable from the value of 'maxX' by dragging them to the right and the left hand side.
Figure 8 - The length of line calculated from the endpoints
Create the block 'Print' to display text on the brick's LCD!
Lastly you just have to display the number of holes on LCD display of the brick. To make it simpler, just create a new block by clicking on 'Make a block'. Here type the name 'Print', click on the + button, add a new input field with the name 'text' and select Command before clicking OK. In the Block Editor just place four 'To [connection] message: [text]' blocks, and select the LCD connection to all of them. The commands in order need to be 'clean' that clears everything from the LCD screen, 'fontsize large' that will set the size of the font larger, the text will be displayed by the 'draw text foreground 10 55' command joined with the 'text' variable like in Figure 9, and lastly commit all these modifications by the 'update' command.
Figure 9 - 'Print' block created for displaying text on the LCD screen
Display the number of holes on the brick's LCD!
The last thing that you have to do, is to divide the total length by the length of one hole, that you calculated before, and display the result on the LCD screen. So, just drag the newly create 'Print' block, and first add the 'Round' block to the field, because you need to display a whole number. In that 'Round' add the division operator, and drag the 'length' variable to the left hand side and type the length of one hole that you measured to the other side (Figure 10).
Figure 10 - Command displays the number of holes on the LCD screen
Setup Circle detection connection!
To detect circles with your USB camera, you have to create a connection in Ozeki 10, that can do this detection. So, as you did with all the previous connections click on Create new Connection in Control Panel, and select the Video connection method as you can see in Figure 11. Then you can select from many types of video connections, but now you need to choose the Vision connection.
Figure 11 - Connection methods in Ozeki 10
From the Vision connections to detect circle objects, select the Circle connection. Before finishing the creation, you need to specify the details of the connection (Figure 12), like the name of it, select the camera that you connected, and modify the resolution and the frame rate at this point. You can also set a sensing delay and save the sensed circles as a snapshot in the Vision tab.
Figure 12 - Details of Circle detection connection
To handle the information from the Circle detector in SNAP, you need to steer the information from it into the SNAP application. For that just click on Routes in Control Panel and select Create new Route. Here you have to select the endpoints of the route which in this case would be, like in Figure 13 the Circle detector connection, where the data will come from, to the SNAP application.
Figure 13 - Information from the Circle detection connection routed to SNAP
Write code to store the information about the detected circle!
The first thing that you have to do in SNAP is to store all the information about the detected circle into a variable. So, first drag the 'When green flag clicked' entry point, then add the 'Get next message' block, which will get the data from the camera thanks to the route you created. When you got the message, you need to store it into a variable. So, create a new one with the name 'message', and with the 'Set 'message' to message value (string)' block save the data. Because this data not only contains the radius that you will use to decide the size of the circle, you have to split this to use it separately. So, create a variable with the name 'circleInfo' and with a 'Set' block, set the 'message' that was split by white spaces like in Figure 14.
Figure 14 - Message from the connection split by white spaces
Categorize the circle by the size of the radius!
Now, with the stored data, you can easily decide the size of the circle with a 'if-else' block, so just place it below all the other blocks. In the head of it, drag a '<' operator, and to the left hand side add the 'item of' operator, where type 7, because in the list the value of the radius is the seventh member. Drag the 'circleInfo' in that block as well as you can see in Figure 15. This example makes difference between small and large circles if the radius is lower or greater than 50.
Figure 15 - 'circleInfo' contains all the information about the detected circle
Display the words 'small' or 'large' depends on the size of the radius!
After you created that block, you just have to place it into the right position. So, add one 'Print' block to the body of the 'if', and also drag one to the 'else' part. In the 'if' part, where the control will move if the radius of the circle is smaller than fifty just type 'small'. Of course this means the control moves to the 'else' only if the radius is bigger than fifty, so here type 'large' in the 'Print' block (Figure 16).
Figure 16 - Text sent to the brick's LCD
Figure 17 - The program can detect lines and circles
|Download program code to detect lines and circles|
The code can detect the number of holes on a Lego piece and the size of a circle.
It is easier to follow the guide if you have the codes in front of you:
Download Ozeki Snap code