The cue co-ordinates were mapped out as 3's onto the 2-d map, this gives the location of the cue tip.
The cue angle is also an output of the Hough Transform but the angle given needed to be altered to match the physics engine:
Actual Cue Angle = Cue Angle + Theta -90
Theta is the angle of the image rotation, -90 in order to match the Hough angle to the Physics Engine
The ball closest to the cue tip needs to be found in order to apply the Cue angle to it. This is done by calculating the distance of each ball to the cue tip and the shortest distance gives the cue ball. For testing purposes the cue will have a red tip as it makes it much easier to detect.
Testing of the application as a whole project, was to be done by building a 'Database' of 20 images which work in the correct lighting conditions. The image Analysis was very sensitive to the lighting conditions in the room and outside weather can have a big effect on the noise found in the image.
Chris
Augmented Reality: Pool Table App
Saturday, 21 April 2012
Thursday, 19 April 2012
Cue detection
The cue will be detected as a straight line in the image, this means that the hough transform can be used to calculate the angle of the cue. However how can you detect the full 360 degree angle or end of the cue as the hough lines go through the whole image?
The cue has already been filtered using the filtering limits given in the post Revised Image Analysis 2. So find the pixels the hough line and the filtering cross and this finds the pixels the cue is in. The equations to calculate these pixels is given below.
j is the increment through the hough matrix and is always less than rhoHeight, rhoHeight is the size of the hough matrix accumulator in the rho direction
The cue has already been filtered using the filtering limits given in the post Revised Image Analysis 2. So find the pixels the hough line and the filtering cross and this finds the pixels the cue is in. The equations to calculate these pixels is given below.
j is the increment through the hough matrix and is always less than rhoHeight, rhoHeight is the size of the hough matrix accumulator in the rho direction
Tuesday, 17 April 2012
Changes to Code
One Week Until Bench Inspection....AAARRRGGHH!!!
There were problems found in the givens scaling function, sometimes the ball co-ordinates are lost during the shrinking. This is because it is going from a 1024x768 image to a 800x400 model of the table.
In order to overcome this, pixels which contained a 1,2 or 3 could not be overwritten and this meant no data was lost.
The rotation matrix was also altered to that the theta found was negated (theta = -theta) this gave the correct direction of rotation
Chris
There were problems found in the givens scaling function, sometimes the ball co-ordinates are lost during the shrinking. This is because it is going from a 1024x768 image to a 800x400 model of the table.
In order to overcome this, pixels which contained a 1,2 or 3 could not be overwritten and this meant no data was lost.
The rotation matrix was also altered to that the theta found was negated (theta = -theta) this gave the correct direction of rotation
Chris
Thursday, 12 April 2012
Revised Image Analysis (part 2)
In part one it was decided to use the HSV colour space to filter out the unnecessary parts of the image. There are 3 main sections needed; the table co-ordinates, ball co-ordinates and cue angle. After extensive testing the required filtering of each component was found.
To filter for the table the following filtering will be used; 0.22<Hue<0.49
T0 filter for the ball; Hue<0.21 or 0.2<=Hue<0.5 and value>=0.64 or Hue>0.49
To filter for the cue; Hue<0.1 or Hue>0.9
It was decided from the testing that it would be easiest to detect red balls as the values for Hue stayed relatively constant over the testing.
To filter for the table the following filtering will be used; 0.22<Hue<0.49
T0 filter for the ball; Hue<0.21 or 0.2<=Hue<0.5 and value>=0.64 or Hue>0.49
To filter for the cue; Hue<0.1 or Hue>0.9
It was decided from the testing that it would be easiest to detect red balls as the values for Hue stayed relatively constant over the testing.
Tuesday, 10 April 2012
Getting and Using the Pocket Co-ordinates
The Pockets were marked as 1's on the 2-d map of the table. Only the Corner pockets were found, not the centre pockets as these could be added later.
The table was split into quarters as it was assumed the image taken would be close enough to the table so that each pocket would be in a quarter of the image.
The image was then scanned and the 4 corner pockets were found and saved in two arrays; One which stored the X co-ordinates and one which stored the Y Co-ordinates.
Theta (for Rotation) = arctan(Ytopright-Ytopleft)/(Xtopright-Xtopleft)
Xshift = Xtopleft, Yshift = Ytopleft
resize X = Xbottomright
resize Y = Ybottomright
Chris
The table was split into quarters as it was assumed the image taken would be close enough to the table so that each pocket would be in a quarter of the image.
The image was then scanned and the 4 corner pockets were found and saved in two arrays; One which stored the X co-ordinates and one which stored the Y Co-ordinates.
Theta (for Rotation) = arctan(Ytopright-Ytopleft)/(Xtopright-Xtopleft)
Xshift = Xtopleft, Yshift = Ytopleft
resize X = Xbottomright
resize Y = Ybottomright
Chris
Saturday, 7 April 2012
Getting JSON string as an Integer
The Get data algorithm returns the JSON as a string, it is required to convert the string as an integer.
The string contains new lines ("\n") within it so getting the integer was more difficult than it first appeared.
To get the integer from a string , the following JAVA code is used:
Integer.ParseInt(string)
Chris
The string contains new lines ("\n") within it so getting the integer was more difficult than it first appeared.
To get the integer from a string , the following JAVA code is used:
Integer.ParseInt(string)
Chris
Tuesday, 3 April 2012
Text to Speech and New Layout
For reference for the blog, text to speech will be referred to as tts.
Reference to the tts sdk is found at http://developer.android.com/reference/android/speech/tts/TextToSpeech.html
Again, the New Boston gives tutorials on using the Text to Speech :
http://thenewboston.org/watch.php?cat=6&number=187
The tts needs to be initialised, this is done using the OnInitListener, the language is then set to UK.
The phrases for the text to speech are:
Instructions:
Reference to the tts sdk is found at http://developer.android.com/reference/android/speech/tts/TextToSpeech.html
Again, the New Boston gives tutorials on using the Text to Speech :
http://thenewboston.org/watch.php?cat=6&number=187
The tts needs to be initialised, this is done using the OnInitListener, the language is then set to UK.
The phrases for the text to speech are:
- Your Shot will be a Hit
- Your Shot will be a Miss
- No Server Found
It was discovered that the TTS works on a standalone Activity but when the TTs was integrated into the Tab View, it couldn't be initialised.
So a new layout for the application was to be created.
This would be a menu which contained 3 buttons; Start, Instructions and Preferences.
The background colour of this menu is set to be; "009900"
Menu:
Sunday, 1 April 2012
Deadlines
Bench Inspection day is 24th April so the project needs to all be working before then.
The Thesis is due in on 3rd May.
The Thesis is due in on 3rd May.
Friday, 30 March 2012
Linking the three Sections
This is the most important part of the project - if the sections cannot be linked together then we only have 3 individual parts which do not pass information between them.
We've allocated all of the time between now and the bench inspection for linking, testing, and refining the code.
We've allocated all of the time between now and the bench inspection for linking, testing, and refining the code.
Thursday, 29 March 2012
Quitting the Application
It was found that the accelerometer does not turn off when the application had quit by the user and so the phone continued to vibrate. This is because android does not close an application but lets it continue to use some of the memory.
A way of stopping the accelerometer was devised so that the phone didn't continually vibrate.
Method 1.
Use the onDestroy method, code for this is shown below:
protected void onDestroy()//Stops all activity when it is Destroyed
{
super.onDestroy();
// After this is called, your app process is no longer available in DDMS
android.os.Process.killProcess(android.os.Process.myPid());
}
Method 2. - Overwrite Back button to close application when pressed (Android doesnt allow the Home Button to be overwritten) Code for this is shown below:
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode==KeyEvent.KEYCODE_BACK)
{
this.finish();
return super.onKeyDown(keyCode, event);
//Overrides the Back Key to quit Activity when it is pressed
}
Chris
Tuesday, 27 March 2012
Extras to the GUI
The application worked at a basic level, in order to make it more exciting to the user extra features could be added to it. The two ideas which were to be implemented were:
- Using the Accelerometer to make sure the user is holding the phone flat, vibrating if it isn't
- Reading whether the shot is to be a hit or miss to the user.
A lot of modern phones running the android operating system contain accelerometers within them, they also contain a vibrate function normally used when the user wants the phone to be quiet.
The android website contains an example of using the accelerometer:
http://developer.android.com/resources/samples/AccelerometerPlay/src/com/example/android/accelerometerplay/AccelerometerPlayActivity.html
There is also the source code for using the Vibrate function which is found here:
http://developer.android.com/reference/android/os/Vibrator.html
When the activity is created, a new sensor manager is set up which 'listens' for a change in the sensor values, the threshold was set as 1 or -1 in both the x and y direction for the vibrate function to be turned on, the implemented code is shown below:
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.cancel();
// check sensor type
if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
// assign directions
float x=event.values[0];
float y=event.values[1];//Measure the Acceleromter in the X and Y direction
if(x>1||x<-1||y>1||y<-1){//Occurrs if they Exceed defined values
v.vibrate(1000);//Makes Phone Vibrate for 1 Second
}
Chris
Subscribe to:
Posts (Atom)