diff --git a/dawnchaos.md b/dawnchaos.md deleted file mode 100644 index f90ceba..0000000 --- a/dawnchaos.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: Dawn of Chaos ---- - -For the first of undergraduate study we have to develop a project in either Delphi or OCaml within a team of four during one year. This is the only year when we are allowed to make a video game. That the reason why we decided to create a Diablo-like in Delphi as our school project in 2004. - -The development has been quite hard, because at the time we had no programming skill. Moreover, our team rapidly exploded, with one member quitting the school after a few months and another one not willing to work. - -Nevertheless, this was a truly rewarding experience since I learned the basics of video game creation and DirectX programming. - - -## Graphic engine - -We had the choice between DirectX and OpenGL for developing our graphic engine. Most of the students chose OpenGL but we thought DirectX was more suitable for a Windows game because we had no intention to port the project to Linux. - -We used the Jedi Project headers as a means to use DirectX with Delphi. The first contact with DirextX was harsh but after carefully reading the SDK documentation I was quick to learn the basics. I would like to thank Buckman for helping me figure the logic of DirectX out. - -The 3D models should have been generated with Maya but our graphic member was not able to produce anything. So we search graphism websites for simple models and we modified them with Maya. For the texturing part and the conversion of the Maya file format to the DirectX one, we used Deep Exploration. - -In order to make things dynamic, we just added a game loop with mutable variables (by pressing keys for moving the camera for instance). Unfortunately, the game loop was not set on the time but on the cpu cycles. As a result, it runs as fast as your cpu can, making things lagged. - -Finally, I added a 2D display for game informations such as health. It was done using DirectSprites and DirectFonts. A bug with the proportions forced me to tweak the sprites size manually in order to make the game look as expected on screen. - - -## Pathfinding - -For the pathfinding, I used the classic A*. Each tile of the map is enabled or not, make a boolean map on which I applied the pathfinding. - - -## Sound engine - -"Sound engine" is a big word for what was done. At first I thought I would use the DirectSound library since our graphic engine was done with Direct3D but I quickly changed my mind. - -DirectSound allows you to use incredible 3D sound effects like reverberation but it was a nightmare to use it. I spent an entire night just for trying to play a simple .wav file. Without success. - -Then I tried Fmod that everybody was using at the moment and I was able to play a .mp3 file in 10 minutes and 3 lines of code. - -For the needs of the game, I included a background music and I added step sound effect when the player is walking. - - -## AI - -The AI is just some nested conditions ("if .. then .. else"). The principle was the following: an enemy is making his rounds and it attacks of the hero is close enough. The enemy goes back to making his rounds if he is almost dead or if the hero is getting away (the hero is of course faster than any enemy). - - -## What was done by others - -My friend who actually worked created a truly rich map editor that was used for making the game. He also created the elements of the world. He was then able to define position and rounds for the enemies directly from his editor. Our graphc engine only had to get his data from the editor in order to generate the levels. - -At last, he was in charge for the management of the hero: life, equipment, etc. - - -## Last words - -Our game was quite pretty but it was very slow due to the too detailled models used for the hero and the enemies. It lacks animation too. I really wanted to incorporate animation but I wasn't able to. - - -## Technologies - -DirectX: the official multimedia API from Microsoft \ No newline at end of file diff --git a/maestro.md b/maestro.md deleted file mode 100644 index c874ad1..0000000 --- a/maestro.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: Maestro ---- - -Maestro is an OMR, Optical Musicscore Recognition. You can think of it like a musical OCR. It was my school project in 2005 in a team of four persons. - -In the team, I was responsible for lines detection, stanzas deduction, audio play and user interface. - - -## Why an OMR? - -During the second year of undergraduate study, we have to make a project more oriented algorithm. It doesn't matter if it has nice graphics, it must be powered by interesting algorithms. - -A lot of people just do an OCR which is basically a text extraction from a scanned sheet. This a perfect example of what I just said: all the focus is on an efficient algorithm. But we wanted to innovate! - -Finally, we chose to create an application able to recognize a sheet music and play the melody. We named our OMR Maestro. - - -## How does it work? - -Here are the basic steps: - -1. Clean the image -2. Rotate the image -3. Lines detection -4. Stanzas deduction -5. Cut each stanza into musicscores -6. Musicscores recognition -7. Chains deduction -8. Midi transcription -9. Audio play - -First of all, we must clean the image. As a result, we obtain a binary image (each pixel is black or white). Then we rotate the image in order to have straight lines. - -After that we detect the lines and deduct the stanzas. We cut each stanza and send them to the musicscore recognition module. Once the musciscores are recognized, we look for chains like bemols, fast times, etc. - -Finally, we convert the result in a MIDI file and play it. The MIDI file format is easy to create from scratch with a good quality. - - -## Line detection - -For the lines detection, I created a very simple algorithm. I start from the top middle of the image and I go down. If I find a black pixel I go on the left and on the right unless I find a white pixel. Then I know the length of a line by couting the black pixels. - -At first, I thought this would be the definition of a line: if the length is greater than half the page width, it is a line. But it didn't work because a line can have some white pixels because of the imperfection of the image, and some lines which are not in a stanza can occur. I had to redefine a line. - -I introduced the concept of imperfection. We have now a variable initialized at 5. Everytime we find a white pixel, this variable is decremented and when it reached 0, we stop the traversal. But if we find a black pixel, we increment the variable (up to 5). - - -## Stanza deduction - -Once we got all the lines of the sheet, we had to group them into stanzas. My first approach was to group them 5 by 5. But the problem was that if we miss a line, all the stanzas become wrong. - -So I had to calculate the average distance between two lines, so I could predict if we were off the stanza or not during the grouping. Finally, we were able to detect stanzas perfectly even if we missed some lines. - - -## UI - -This was the first time I had to use Qt, and I was not sure if I should use Qt Designer or do everything in Emacs. Finally, I coded the interface only with Emacs, to be sure to fully understand of Qt works. - -The user interface was pretty simple, since it was just a school project: each step was available at the top of the application. You just had to click to go through all the processing. - - -## Sound module - -At first I tried to use timidity++ in order to play the generated MIDI file but the configuration was way to hard, and we wanted our software to be simple to use. Afther a while, I decided to try SDL with SDL_mixer and it was so simple that we had a functionnal MIDI player in one night. - - -## Mac OS X port - -With the Qt framework, it is quite easy to create a multiplatform application. - -One avantage of the Mac version was that Qt was directly able to play a MIDI file without SDL because it was calling QuickTime. We provided a package file in order to install it under Mac OS X, delivering Qt libraires as well for Mac users so they didn't have to install Qt to use Maestro (unlike Linux users). - - -## Last words - -Our software doesn't recognize every musicscore and is still perfectible, but we are proud of it. Its flaws are only due to the lack of time at the end of the year because our recognition engine is quite flexible to be enhanced - -We couldn't implement everything on time, even with our coding nights before the final presentation. Who knows, it could have been a reference since there is not so much similar applications. Thanks to Maestro, we got the vice-major place among all the projects of the promotion. - - -## Technologies - -[Qt](https://qt-project.org/): Cross-platform application framework from Trolltech \ No newline at end of file diff --git a/projects.md b/projects.md index d14d53a..e00f79b 100644 --- a/projects.md +++ b/projects.md @@ -3,8 +3,8 @@ title: Projects --- \ No newline at end of file +
  • Trailr
  • +
  • Where is my car?
  • +
  • Maestro
  • +
  • Dawn of Chaos
  • + diff --git a/projects/dawnchaos/index.md b/projects/dawnchaos/index.md index 097f65a..8cdb507 100644 --- a/projects/dawnchaos/index.md +++ b/projects/dawnchaos/index.md @@ -2,55 +2,88 @@ title: Dawn of Chaos --- -For the first of undergraduate study we have to develop a project in either Delphi or OCaml within a team of four during one year. This is the only year when we are allowed to make a video game. That the reason why we decided to create a Diablo-like in Delphi as our school project in 2004. +For the first of undergraduate study we have to develop a project in either +Delphi or OCaml within a team of four during one year. This is the only year +when we are allowed to make a video game. That the reason why we decided to +create a Diablo-like in Delphi as our school project in 2004. -The development has been quite hard, because at the time we had no programming skill. Moreover, our team rapidly exploded, with one member quitting the school after a few months and another one not willing to work. +The development has been quite hard, because at the time we had no programming +skill. Moreover, our team rapidly exploded, with one member quitting the school +after a few months and another one not willing to work. -Nevertheless, this was a truly rewarding experience since I learned the basics of video game creation and DirectX programming. +Nevertheless, this was a truly rewarding experience since I learned the basics +of video game creation and DirectX programming. GRAPHIC ENGINE -------------- -We had the choice between DirectX and OpenGL for developing our graphic engine. Most of the students chose OpenGL but we thought DirectX was more suitable for a Windows game because we had no intention to port the project to Linux. +We had the choice between DirectX and OpenGL for developing our graphic engine. +Most of the students chose OpenGL but we thought DirectX was more suitable for a +Windows game because we had no intention to port the project to Linux. -We used the Jedi Project headers as a means to use DirectX with Delphi. The first contact with DirextX was harsh but after carefully reading the SDK documentation I was quick to learn the basics. I would like to thank Buckman for helping me figure the logic of DirectX out. +We used the Jedi Project headers as a means to use DirectX with Delphi. The +first contact with DirextX was harsh but after carefully reading the SDK +documentation I was quick to learn the basics. I would like to thank Buckman for +helping me figure the logic of DirectX out. -The 3D models should have been generated with Maya but our graphic member was not able to produce anything. So we search graphism websites for simple models and we modified them with Maya. For the texturing part and the conversion of the Maya file format to the DirectX one, we used Deep Exploration. +The 3D models should have been generated with Maya but our graphic member was +not able to produce anything. So we search graphism websites for simple models +and we modified them with Maya. For the texturing part and the conversion of the +Maya file format to the DirectX one, we used Deep Exploration. -In order to make things dynamic, we just added a game loop with mutable variables (by pressing keys for moving the camera for instance). Unfortunately, the game loop was not set on the time but on the cpu cycles. As a result, it runs as fast as your cpu can, making things lagged. +In order to make things dynamic, we just added a game loop with mutable +variables (by pressing keys for moving the camera for instance). Unfortunately, +the game loop was not set on the time but on the cpu cycles. As a result, it +runs as fast as your cpu can, making things lagged. -Finally, I added a 2D display for game informations such as health. It was done using DirectSprites and DirectFonts. A bug with the proportions forced me to tweak the sprites size manually in order to make the game look as expected on screen. +Finally, I added a 2D display for game informations such as health. It was done +using DirectSprites and DirectFonts. A bug with the proportions forced me to +tweak the sprites size manually in order to make the game look as expected on +screen. PATHFINDING ----------- -For the pathfinding, I used the classic A*. Each tile of the map is enabled or not, make a boolean map on which I applied the pathfinding. +For the pathfinding, I used the classic A*. Each tile of the map is enabled or +not, make a boolean map on which I applied the pathfinding. SOUND ENGINE ------------ -"Sound engine" is a big word for what was done. At first I thought I would use the DirectSound library since our graphic engine was done with Direct3D but I quickly changed my mind. +"Sound engine" is a big word for what was done. At first I thought I would use +the DirectSound library since our graphic engine was done with Direct3D but I +quickly changed my mind. -DirectSound allows you to use incredible 3D sound effects like reverberation but it was a nightmare to use it. I spent an entire night just for trying to play a simple .wav file. Without success. +DirectSound allows you to use incredible 3D sound effects like reverberation but +it was a nightmare to use it. I spent an entire night just for trying to play a +simple .wav file. Without success. -Then I tried Fmod that everybody was using at the moment and I was able to play a .mp3 file in 10 minutes and 3 lines of code. +Then I tried Fmod that everybody was using at the moment and I was able to play +a .mp3 file in 10 minutes and 3 lines of code. -For the needs of the game, I included a background music and I added step sound effect when the player is walking. +For the needs of the game, I included a background music and I added step sound +effect when the player is walking. AI -- -The AI is just some nested conditions ("if .. then .. else"). The principle was the following: an enemy is making his rounds and it attacks of the hero is close enough. The enemy goes back to making his rounds if he is almost dead or if the hero is getting away (the hero is of course faster than any enemy). +The AI is just some nested conditions ("if .. then .. else"). The principle was +the following: an enemy is making his rounds and it attacks of the hero is close +enough. The enemy goes back to making his rounds if he is almost dead or if the +hero is getting away (the hero is of course faster than any enemy). WHAT WAS DONE BY OTHERS ----------------------- -My friend who actually worked created a truly rich map editor that was used for making the game. He also created the elements of the world. He was then able to define position and rounds for the enemies directly from his editor. Our graphc engine only had to get his data from the editor in order to generate the levels. +My friend who actually worked created a truly rich map editor that was used for +making the game. He also created the elements of the world. He was then able to +define position and rounds for the enemies directly from his editor. Our graphc +engine only had to get his data from the editor in order to generate the levels. At last, he was in charge for the management of the hero: life, equipment, etc. @@ -58,14 +91,12 @@ At last, he was in charge for the management of the hero: life, equipment, etc. LAST WORDS ---------- -Our game was quite pretty but it was very slow due to the too detailled models used for the hero and the enemies. It lacks animation too. I really wanted to incorporate animation but I wasn't able to. +Our game was quite pretty but it was very slow due to the too detailled models +used for the hero and the enemies. It lacks animation too. I really wanted to +incorporate animation but I wasn't able to. TECHNOLOGIES ------------ -DirectX: the official multimedia API from Microsoft - - -SCREENSHOTS ------------ \ No newline at end of file +[DirectX](https://en.wikipedia.org/wiki/DirectX): the official multimedia API from Microsoft diff --git a/projects/maestro/index.md b/projects/maestro/index.md index 760df54..7e7cbdb 100644 --- a/projects/maestro/index.md +++ b/projects/maestro/index.md @@ -2,18 +2,25 @@ title: Maestro --- -Maestro is an OMR, Optical Musicscore Recognition. You can think of it like a musical OCR. It was my school project in 2005 in a team of four persons. +Maestro is an OMR, Optical Musicscore Recognition. You can think of it like a +musical OCR. It was my school project in 2005 in a team of four persons. -In the team, I was responsible for lines detection, stanzas deduction, audio play and user interface. +In the team, I was responsible for lines detection, stanzas deduction, audio +play and user interface. WHY AN OMR? ----------- -During the second year of undergraduate study, we have to make a project more oriented algorithm. It doesn't matter if it has nice graphics, it must be powered by interesting algorithms. +During the second year of undergraduate study, we have to make a project more +oriented algorithm. It doesn't matter if it has nice graphics, it must be +powered by interesting algorithms. -A lot of people just do an OCR which is basically a text extraction from a scanned sheet. This a perfect example of what I just said: all the focus is on an efficient algorithm. But we wanted to innovate! +A lot of people just do an OCR which is basically a text extraction from a +scanned sheet. This a perfect example of what I just said: all the focus is on +an efficient algorithm. But we wanted to innovate! -Finally, we chose to create an application able to recognize a sheet music and play the melody. We named our OMR Maestro. +Finally, we chose to create an application able to recognize a sheet music and +play the melody. We named our OMR Maestro. HOW DOES IT WORK? @@ -31,43 +38,68 @@ Here are the basic steps: 8. Midi transcription 9. Audio play -First of all, we must clean the image. As a result, we obtain a binary image (each pixel is black or white). Then we rotate the image in order to have straight lines. +First of all, we must clean the image. As a result, we obtain a binary image +(each pixel is black or white). Then we rotate the image in order to have +straight lines. -After that we detect the lines and deduct the stanzas. We cut each stanza and send them to the musicscore recognition module. Once the musciscores are recognized, we look for chains like bemols, fast times, etc. +After that we detect the lines and deduct the stanzas. We cut each stanza and +send them to the musicscore recognition module. Once the musciscores are +recognized, we look for chains like bemols, fast times, etc. -Finally, we convert the result in a MIDI file and play it. The MIDI file format is easy to create from scratch with a good quality. +Finally, we convert the result in a MIDI file and play it. The MIDI file format +is easy to create from scratch with a good quality. LINES DETECTION --------------- -For the lines detection, I created a very simple algorithm. I start from the top middle of the image and I go down. If I find a black pixel I go on the left and on the right unless I find a white pixel. Then I know the length of a line by couting the black pixels. +For the lines detection, I created a very simple algorithm. I start from the top +middle of the image and I go down. If I find a black pixel I go on the left and +on the right unless I find a white pixel. Then I know the length of a line by +couting the black pixels. -At first, I thought this would be the definition of a line: if the length is greater than half the page width, it is a line. But it didn't work because a line can have some white pixels because of the imperfection of the image, and some lines which are not in a stanza can occur. I had to redefine a line. +At first, I thought this would be the definition of a line: if the length is +greater than half the page width, it is a line. But it didn't work because a +line can have some white pixels because of the imperfection of the image, and +some lines which are not in a stanza can occur. I had to redefine a line. -I introduced the concept of imperfection. We have now a variable initialized at 5. Everytime we find a white pixel, this variable is decremented and when it reached 0, we stop the traversal. But if we find a black pixel, we increment the variable (up to 5). +I introduced the concept of imperfection. We have now a variable initialized at +5. Everytime we find a white pixel, this variable is decremented and when it +reached 0, we stop the traversal. But if we find a black pixel, we increment the +variable (up to 5). STANZAS DEDUCTION ----------------- -Once we got all the lines of the sheet, we had to group them into stanzas. My first approach was to group them 5 by 5. But the problem was that if we miss a line, all the stanzas become wrong. +Once we got all the lines of the sheet, we had to group them into stanzas. My +first approach was to group them 5 by 5. But the problem was that if we miss a +line, all the stanzas become wrong. -So I had to calculate the average distance between two lines, so I could predict if we were off the stanza or not during the grouping. Finally, we were able to detect stanzas perfectly even if we missed some lines. +So I had to calculate the average distance between two lines, so I could predict +if we were off the stanza or not during the grouping. Finally, we were able to +detect stanzas perfectly even if we missed some lines. USER INTERFACE -------------- -This was the first time I had to use Qt, and I was not sure if I should use Qt Designer or do everything in Emacs. Finally, I coded the interface only with Emacs, to be sure to fully understand of Qt works. +This was the first time I had to use Qt, and I was not sure if I should use Qt +Designer or do everything in Emacs. Finally, I coded the interface only with +Emacs, to be sure to fully understand how Qt works. -The user interface was pretty simple, since it was just a school project: each step was available at the top of the application. You just had to click to go through all the processing. +The user interface was pretty simple, since it was just a school project: each +step was available at the top of the application. You just had to click to go +through all the processing. SOUND MODULE ------------ -At first I tried to use timidity++ in order to play the generated MIDI file but the configuration was way to hard, and we wanted our software to be simple to use. Afther a while, I decided to try SDL with SDL_mixer and it was so simple that we had a functionnal MIDI player in one night. +At first I tried to use timidity++ in order to play the generated MIDI file but +the configuration was way to hard, and we wanted our software to be simple to +use. Afther a while, I decided to try SDL with SDL_mixer and it was so simple +that we had a functionnal MIDI player in one night. MAC OS X PORT @@ -75,22 +107,26 @@ MAC OS X PORT With the Qt framework, it is quite easy to create a multiplatform application. -One avantage of the Mac version was that Qt was directly able to play a MIDI file without SDL because it was calling QuickTime. We provided a package file in order to install it under Mac OS X, delivering Qt libraires as well for Mac users so they didn't have to install Qt to use Maestro (unlike Linux users). +One avantage of the Mac version was that Qt was directly able to play a MIDI +file without SDL because it was calling QuickTime. We provided a package file in +order to install it under Mac OS X, delivering Qt libraires as well for Mac +users so they didn't have to install Qt to use Maestro (unlike Linux users). LAST WORDS ---------- -Our software doesn't recognize every musicscore and is still perfectible, but we are proud of it. Its flaws are only due to the lack of time at the end of the year because our recognition engine is quite flexible to be enhanced +Our software doesn't recognize every musicscore and is still perfectible, but we +are proud of it. Its flaws are only due to the lack of time at the end of the +year because our recognition engine is quite flexible to be enhanced -We couldn't implement everything on time, even with our coding nights before the final presentation. Who knows, it could have been a reference since there is not so much similar applications. Thanks to Maestro, we got the vice-major place among all the projects of the promotion. +We couldn't implement everything on time, even with our coding nights before the +final presentation. Who knows, it could have been a reference since there is not +so much similar applications. Thanks to Maestro, we got the vice-major place +among all the projects of the promotion. TECHNOLOGIES ------------ -Qt: Cross-platform application framework from Trolltech - - -SCREENSHOTS ------------ \ No newline at end of file +[Qt](https://qt-project.org/): Cross-platform application framework from Trolltech diff --git a/projects/trailr/index.md b/projects/trailr/index.md index e69de29..b821193 100644 --- a/projects/trailr/index.md +++ b/projects/trailr/index.md @@ -0,0 +1,21 @@ +--- +title: Trailr +--- + +[Official website](http://www.ltutech.com/case/trailr/) + +Trailr was developed in 2012 during [LTU](http://www.ltutech.com)'s "innovation days" +when employees are free to work on pet projects. + +This was the occasion for us to start using our own image recognition +technologies. + +We pull information about movies each night from +[TMDb](http://www.themoviedb.org/), put it on our database with all the posters, +and then do simple requests on our servers via our mobile apps. + +I started the project and developed the iPhone app. My coworker (whom I started +the project with) did all the backend work (data sync, database, server). + +At a later stage, another coworker developed an Android app and a chrome +extension. diff --git a/projects/whereiscar/index.md b/projects/whereiscar/index.md index 20d2820..968aa52 100644 --- a/projects/whereiscar/index.md +++ b/projects/whereiscar/index.md @@ -2,9 +2,12 @@ title: Where is my car? --- -One of my first image processing based project. It finds cars on a Google Maps view, based on their color. +One of my first image processing based project done in 2007. It finds cars on a Google Maps +view, based on their color. -When I started this project, I had no experience in image processing, so I tried what came to my mind. Looking backward, the sources are a real mess but I acquired my first image processing skills with it. +When I started this project, I had no experience in image processing, so I tried +what came to my mind. Looking backward, the sources are a real mess but I +acquired my first image processing skills with it. Here are the basic steps of the program: @@ -23,12 +26,7 @@ Here are the basic steps of the program: 13. Later, I decided to bind it with a Cocoa GUI. -TECHNOLOGIES ------------- +## Technologies -The CImg Library: a simple but powerful image processing library -Cocoa: the framework behind every Mac application - - -SCREENSHOTS ------------ \ No newline at end of file ++ [The CImg Library](http://cimg.sourceforge.net/): a simple but powerful image processing library ++ [Cocoa](http://developer.apple.com/): the framework behind every Mac application diff --git a/site.hs b/site.hs index c128278..69539fc 100644 --- a/site.hs +++ b/site.hs @@ -20,11 +20,7 @@ import Hakyll main :: IO () main = hakyllWith config $ do - match "favicon.png" $ do - route idRoute - compile copyFileCompiler - - match "images/*" $ do + match ("images/*" .||. "favicon.png") $ do route idRoute compile copyFileCompiler @@ -34,11 +30,12 @@ main = hakyllWith config $ do match "templates/*" $ compile $ templateCompiler - match "*.md" $ do + match ("*.md" .||. "projects/*/*.md") $ do route $ setExtension "html" compile $ pandocCompiler >>= loadAndApplyTemplate "templates/default.html" defaultContext >>= relativizeUrls + -------------------------------------------------------------------------------- config :: Configuration diff --git a/trailr.md b/trailr.md deleted file mode 100644 index e724430..0000000 --- a/trailr.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Trailr ---- - -[Official website](http://www.ltutech.com/case/trailr/) - -Trailr was developed during [LTU](http://www.ltutech.com)'s "innovation days" when employees are free to work on pet projects. - -This was the occasion for us to start using our own image recognition technologies. - -We pull information about movies each night from [TMDb](http://www.themoviedb.org/), put it on our database with all the posters, and then do simple requests on our servers via our mobile apps. - -I started the project and developed the iPhone app. My coworker (whom I started the project with) did all the backend work (data sync, database, server). - -At a later stage, another coworker developed an Android app and a chrome extension. \ No newline at end of file diff --git a/whereiscar.md b/whereiscar.md deleted file mode 100644 index a93ba2f..0000000 --- a/whereiscar.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Where is my car? ---- - -One of my first image processing based project. It finds cars on a Google Maps view, based on their color. - -When I started this project, I had no experience in image processing, so I tried what came to my mind. Looking backward, the sources are a real mess but I acquired my first image processing skills with it. - -Here are the basic steps of the program: - -1. Delete the unnecessary colors from the image -2. Classify the image in 10 colors with the K-means algorithm -3. Delete huge objects that can't obviously be cars -4. Fill tiny holes -5. Classify again -6. Remove odd shapes -7. Fill tiny holes again -8. Restore original colors -9. Delete pixels with low saturation -10. Classify again -11. Remove little objects -12. Remove odd shapes -13. Later, I decided to bind it with a Cocoa GUI. - - -## Technologies - -+ [The CImg Library](http://cimg.sourceforge.net/): a simple but powerful image processing library -+ [Cocoa](http://developer.apple.com/): the framework behind every Mac application \ No newline at end of file