Tuesday 10 November 2015

Version control ethics with GitHub

The following post is going to cover the standard procedure of contributing to a project hosted by an individual or an organization on GitHub.


  1. Search for the project or open the project you are invited to & fork the repository to your account.
  2. A fork is a copy of a repository. Forking a repository allows you to freely experiment with changes without affecting the original project.
  3. To fork a repo, you will see a "Fork" button on the righter side. Click that. 
  4. Clone the repo to your local machine using GitShell or any git client.
  5. Contribute to the project the way you want. Keep in mind the standards of coding while contributing to a collaborated project.
    A code must not only be smart but also beautiful. A beautiful code is a readable code. This is a must when working in a team so that your fellow mates can understand what you want to do and what they have to do further. Google about coding standards to know more.
  6. Once your module is ready, do not push it directly to master branch. Generally, as a contributor you don't have the permission to commit changes in the master branch of the repository. When you fork a repository, there ought to be a maintainer and/or an owner who takes care of what goes in the master branch of the original repository. Whatever changes you make in the forked repository does not affect the original repository until and unless it is permitted by the owner/maintainer.
  7. So you create your own version of the module and push the code there. This version is called a branch.
  8. Create a branch of any name you want by,
    git branch <branchname>
  9. To change the current branch type,
    git checkout <branchname>
    Refer to the tutorials posted in the earlier post for a clearer idea of this.
  10. Once you have added all your untracked files to your own branch, git push it all.
  11. Now your copy of the module is updated to the forked repository, to merge your branch with the master branch, you need to generate a pull request to the owner.
  12. To generate a pull request, open up your forked repository and click "Pull request" on the righter side, click on "New pull request" and select your branch in one drop down while the master in the other. It will show all the changes you made with respect to the other branch.
  13. Type in the essential commits and comments and generate the request to merge your branch with the master branch.
  14. If the owner/maintainer finds the pull request sufficing then he might merge your branch with master. Else they will comment the problems. Once merged with the master branch, they might open Issues with your request which you will have to solve.
GitHub has bridged the gap between coders overseas. If all is followed correctly, a greatly collaborated teamwork can be exercised online using version control software like GitHub.
Hit the +1 if you like my post, comment your views and confusions.

Start forking, start contributing!

Sunday 8 November 2015

GitHub

Have you ever worked on Google Docs? It has got a feature of adding collaborators to your document and multiple people, wherever they might be, can edit the document at the same time, parallel to each other. You can even see the cursor of the other collaborators moving in real time with a history of edits made by every collaborator in a timeline.

When people work in teams to code on large projects, it becomes hard to keep the work collaborated on everyone's side. Copying all the files from one's computer and pasting it on his. Thereafter he has to read every line of code and change the edits he made which can be tedious and wastes a lot of time.

_________________________________________________________________________

So there is a term called "version control". 

"Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later."  

Google about version control to know more about it.

Git comes into picture here.


"Git (/ɡɪt/) is a widely used version control system for software development."

Git was initially developed and designed by Linus Torvalds, father of Linux. A very popular platform for Git repository hosting is GitHub.

"GitHub is a Web-based Git repository hosting service"

More than 29 million projects are hosted on GitHub at present, with more than 11 million users. The beautiful part about this is that you can fork in the open-source projects and contribute to it and others can contribute in yours.
_________________________________________________________________________

SETTING UP GITHUB :

GIT TERMINOLOGY :

This will be a quick terminology introduction before you start using GitHub :
  • GIT : Git is an open source program for tracking changes in text files.
  • REPOSITORYA repository is the most basic element of GitHub. They're easiest to imagine as a project's folder.
  • COLLABORATOR : A collaborator is a person with read and write access to a repository who has been invited to contribute by the repository owner.
  • CONTRIBUTOR : A contributor is someone who has contributed to a project by having a pull request merged but does not have collaborator access.
  • BRANCH : A branch is a parallel version of a repository. It is contained within the repository, but does not affect the primary or master branch allowing you to work freely without disrupting the "live" version. When you've made the changes you want to make, you can merge your branch back into the master branch to publish your changes.
  • CLONE : A clone is a copy of a repository that lives on your computer instead of on a website's server somewhere, or the act of making that copy. With your clone you can edit the files in your preferred editor and use Git to keep track of your changes without having to be online.
  • PULL : Pull refers to when you are fetching in changes and merging them. For instance, if someone has edited the remote file you're both working on, you'll want to pull in those changes to your local copy so that it's up to date.
  • PUSH : Pushing refers to sending your committed changes to a remote repository such as GitHub.com. For instance, if you change something locally, you'd want to then push those changes so that others may access them.
  • COMMIT : The changes you made in your repository are not in your repository yet. We could add or remove files from the stage before we store them in the repository.
    To store our staged changes we run the commit command with a message describing what we've changed. So basically, it records the changes to the repository.
Once you are clear with these terminologies, you are ready to go make your own Git repos and start adding collaborators and contributors and host an online repo and work on a perfectly collaborated project. To learn about the syntax of using GitShell, you will find the following videos very helpful. Thanks to LearnCode.academy for these videos.

  1. GitHub Tutorial part 1
  2. GitHub Tutorial part 2

An amazing way to perform your first Git commands is through https://try.github.io/ This a is very fine tutorial provided by GitHub itself. Do try it out! 

Enjoy forking and hosting repos!

Click here to get an idea of how to use GitHub if you want to contribute in projects. >> Version control ethics with GitHub

Friday 31 July 2015

Making a GUI interface in MATLAB

In reference to my last post regarding ping pong game with object tracking, I pushed my work a little bit more and incorporated Kalman Filter and GUI with it.

The following post contains about the GUI creation for beginners in MATLAB. I will post about Kalman Filter soon.


GUI in MATLAB

It is pretty simple to make a GUI in MATLAB. You can find tons of videos on YouTube and even on MATLAB central regarding this.

Type guide and press enter in the command window of MATLAB.
  1. A window will pop-up with "drag and drop" options of various components available for GUI you want to make. 
  2. You may add text-boxes, editable text boxes, sliders, radio buttons, push buttons etc. using panel on the left of guide window and double click on any component to open its property inspector where you can set various fields like Value, Max, Min, Name.
  3. Drag all that you need and save the *.fig file.
  4. To customize a component, right click on component and gotoView  CallBacks > CallBack
  5. This will direct you to the function where Callbacks of components are handled.
    In case of push buttons, type the code you want to be performed on click in that space.
    In case of Value returning components (sliders, radio-buttons), use get() function to get values from component used upon some action performed. For example, to get position of slider,

    variable=get(handles.slider_name,'Value');
where,
           variable is a global variable so that the scope of this variable is beyond a single Class and can be directly used outside the GUI codes in your further process. You can also use varagout() part in the GUI *.m file to get a value returned.
           slider_name is the name of component as specified in the tag field in the Property Inspector of the component.

     6.  If you want to plot a graph or preview an image on the GUI panel, you can add an axes component. To show images on this component, type imshow(image,axes_name)

In the following, video I used guide to make a GUI interface for setting parameters to filter my image for object tracking. On clicking OK, the parameters are transferred to my Tracking and Kalman Filter algorithms which provide a much more effective way of making a generalized object tracking.

Sliders used :
Brightness : Add a positive whole number to every element in image array to increase its brightness.
Contrast : Vary gamma value in imadjust() function for contrast. gamma>1, gamma=1 and  gamma<1 represent relation in intensity of input and output image. Check out Example on imadjust() to use gamma. P.S. : Do not name variable as gamma; it is also a function. :p
Rmin, Rmax, Gmin, Gmax, Bmin, Bmax : RGB minimum and maximum value for segmentation.
Lower Area and Upper Area : Perform connected component analysis and filter Area using lower and upper limit of area from here.

On pressing, a global flag is set high and the program comes out of the infinite loop to continue forward.



Friday 17 July 2015

Integrating MATLAB and Visual Studio using Engine API

Tutorial 2 : Writing Engine scripts.

After having set Visual Studio to be integrated with MATLAB, you need to add some fragments of code along with your C/C++ program to call or send values to MATLAB.

Everything you need will be contained in the libraries engine.h and matrix.h

Every engine application will have a pointer of data type Engine that defines an engine session. We will be using variable addresses to copy values using pointers and using in either MATLAB or C or both.

Opening and closing engine sessions :

Following functions will be needed for its working :
  • ep = engOpen() - where engine session starts. ep of type for MATLAB Engine.
  • engClose(ep) - closes engine session defined by pointer ep
On Windows system, engOpen() will have argument "NULL"

Pointers to store values for transferring between MATLAB and C :

Remember, for transferring arrays and values with MATLAB, we need to have an intermediate data-type, mxArray. Creates MATLAB arrays.

Define pointers of mxArray data-type as an array using, mxCreateDoubleMatrix, mxCreateNumericMatrix, etc. (See documentation for further types and its arguments)
For example, mxArray *array = mxCreateDoubleMatrix(5,3,mxREAL); 
creates a pointer to a double matrix with 5 rows and 3 columns and has elements belonging to Real Numbers.

Performing the actual putting,getting and evaluation of values in MATLAB workspace :

Following functions might be used to get or put value in mxArray variables from/into MATLAB workspace :
  • engEvalString(ep,"MATLAB code") - Puts whatever written in string to MATLAB workspace opened by ep Engine session pointer.
  • engPutVariable(ep,"MATLAB variable",mxArray pointer) - Puts values from an address in C space to an address in MATLAB workspace.
  • mxArray pointer = engGetVariable(ep,"MATLAB variable") - Gets values from MATLAB workspace variable specified in " " and is stored in mxArray pointers.
  • mxGetPr(mxArray pointer) - Gets the starting address of the first real element of pointer.
We know how to start engine, how to make MATLAB array pointers, how to run commands on MATLAB workspace, how to put and get values in MATLAB array pointers from workspace but we still have the gap between MATLAB and C; to get values from mxArray pointers to int/double/etc. data type variables in C we use 
memcpy(address of destination,address of source,number of bytes to be copied)

Use (void *) , also called General Purpose Pointer as it can be used as any data-type pointer.

Moreover, along with engOpen you can add error messages with it.(Refer Documentation of MATLAB)

engwindemo.c is a good example to learn from. Below will be the screenshots of my code, describing stages of Engine session. For full code, you can visit my github repo HERE



Initialize Engine session and define MATLAB array pointers.


Sending commands to MATLAB workspace


Getting values from MATLAB workspace

Closing engine session


Saturday 11 July 2015

Ping-Pong game using Object Tracking

I thought of this project way back but had to pause working on it for about a month. So when I sat free again, I finally made it work the way I wanted. (Needs debugging though)

This project has three modules:
1. A C program of Ping Pong
2. Real time Object Tracking using MATLAB
3. Integration of MATLAB and Visual Studio using Engine API.

If you visit my older posts, you may find enough description of Object Tracking and Engine API (I remember I have to write the other part of Integration tutorial, it will be soon). The remaining one, Ping Pong game, was not very hard to make. You just need to make four independent objects, two bats, a ball and a game arena and keep them displaying at every loop.

The important logic behind the motion of balls is the direction x and direction y. When the ball hits the walls, its y direction will negate but its x direction is same. On the other hand when hit by a bat its x direction changes while y remains same. This is enough to design a simple Ping Pong game. You can go through the code at my github link posted at the end.


This video was taken a few hours after my code gave the first desired output. The results have a lot of errors still, but it is just a prototype. Given some time I can try to make it as flawless as possible.
The only part to explain is the integration of both softwares, which I shall post soon. Hit a +1 if you liked it and do comment out your views and suggestions.

Here's the github link, Ping-Pong-with-finger-tracking-

Tuesday 7 July 2015

Integrating MATLAB and Visual Studio using Engine API

This one made me scratch my head to the scalp; literally. So I am going to provide a thorough tutorial on "Using MATLAB Engine API for C++(C)".

TUTORIAL 1 : SETTING IT ALL UP

Requirements :

1. Microsoft Visual Studio (This tutorial will be based on version 2010, moreover they are all similar)
2. MATLAB

Things to know before starting?

  • Find out on what platform is your MATLAB running, that is 32 bit or 64 bit. To do so, go to Start > Right Click on Computer >Properties > Advanced system settings > Environment Variables > In System Variables scroll down to Path > Double click and check whether it has MATLAB bin under win64 directory or win32.

Steps :

  1. Open Visual Studio and create a new project. You might probably choose "Win32 Console Application" and check the "Empty Project" option in dialog box.
  2. Visual Studio by default runs on a 32 bit platform. If your MATLAB is running on a 64 bit platform (most probably this will be the case) then you will have to make sure that VS(Visual Studio) is going to build applications on a 64 bit platform otherwise skip this step. To do so, click on Project menu > project-name properties (this will open Property Pages dialog box)> Configuration Properties > Configuration Manager > Click on drop down menu of "Active solution platform" > New > from drop down select x64 > close and click ok.
  3. Now your VS is capable of building files on 64bit platform. Open Property Pages and select VC++ directories and make sure you have something like "$(VCInstallDir)bin\x86_amd64;" at the beginning, which ensures the 64 bit platform if your MATLAB is on 64 bit too.
  4. In the Property Pages, click on Debugging and in the Environment field add this,

    PATH=(MATLAB installation directory)\bin\win64
  5. In the Property Pages, click on VC++ directories and add the path to include directories by opening,

     (MATLAB installation directory)\extern\include

    I will suggest copy pasting the path from properties dialog box.
  6. Now add library path in Library directories field by opening,

    (MATLAB installation directory)\extern\lib\win64[or win32, whatever you are working on]\microsoft
  7. Now you have to add the executable directories which is as follows,

    (MATLAB installation directory)\bin
  8. Now click on Linker on the left side pane and add the same library path to the "Additional Library Directories" field. Make sure "Enable Incremental Linking" is set to "No" (It pops some error that I don't know why but read this fix somewhere and it works).
  9. In the Linker dropped down, select Input and add the following libraries by clicking on "Additional Dependencies" and move cursor to end and write with semicolons after every library as follows,

    libmx.h;libmex.h;libmat.h;libeng.h;
  10. Hit OK!
If all went well then this is it. Now you are ready to use Engine functions to call MATLAB from Visual Studio.

I will post the next part of this tutorial about writing a Engine file and calling MATLAB soon. If you face problems in setting this up, comment out and I will try to solve because I skipped few minor things.

To check it's working you can go to MATLAB documentation, search for MATLAB engine API and open C,C++ and Fortran and copy paste an example in VS project and see if it works!

Saturday 20 June 2015

A college assignment - Tic Tac Toe using simple A.I. algorithms.

I got a call from my friend asking me to help with his college assignment on C programming. It had a 3x3 Sudoku solver on list which I had worked earlier here using MATLAB; so I picked up a tic tac toe game, both multiplayer and Computer opponent.

I didn't use Google this time and came up with a fully home-made logic recipe which you can find below :

Here is the formal initialization parts and I declared a function called printer() which prints my tic tac toe game board along with 'x' and 'o' pieces every time called.



So this is an another function called  win() which is a pretty long one; long but dumb. I just ran three to four loops to check horizontally, vertically and both diagonally for a three same 'x' or 'o's and return a flag if found one, implying the end of game. The final case is a no space on game board and all place filled with 'x' or 'o' declaring a draw. It also prints the winners name. (Don't worry I will add a link to the complete code if you want to look through it)


This is my main() function. An infinite loop runs till 'e' character is pressed or a win or draw flag is raised. In this infinite loop, an input is taken from the player whenever the chanceflag is 0 implying that it is Player's chance. 'w','a','s' and 'd' keys are used to print a "_" on the game board to show cursor position. When a ' '(space) is hit, the program checks for that place to be empty and if empty then the user is allowed to input a character. The character is permanently placed there if it is 'x'. The chanceflag is set 1 once input is confirmed.

Next comes the A.I. part.

The c_row and c_col variables contain position of last input from player. The Computer performs a check for two 'x' on the same c_row,c_col and cases where the place is on diagonal; c_row=c_col(main diagonal) or c_row=2-c_col(anti diagonal). If 2 'x' are found then the priority of program is to fill the empty space with an 'o'; otherwise it fills the space with a randomly picked value of row and column using rand()/15000(Because maximum value of rand() is 32767, i.e. if divided by 15000 quotient is between 0 and 2). Labels have served a great purpose in program, check them for sure.

You can find the complete code here : Tic Tac Toe using simple A.I.

Do comment a better approach to this program! Thank you!

Friday 12 June 2015

Object Tracking using MATLAB.

This might sound like a tough one but believe not that much of a rocket science.

I wore a red cloth on my finger and took a video of me moving the finger.(Still don't have webcam hardware support; do share me a link to download this externally, not from MATLAB site because my software is cracked). This video was fed in MATLAB by following the examples in documetation of how to take in video inputs using VideoReader() function. It makes a video object from which frames can be extracted in a structure in the following way,

















So what we do here is create a structure(which is analogous to C structures) which contains frames in fields called 'cdata' while its colormap in 'colormap'. I am working with a RGB image so it doesn't need colormap. A loop is run until no frames are left in the object and structure stores frames in it during every iteration.

This makes our frames ready to be image processed. I took out the R, G and B frame separately from every frame(RGB images are formed by stacking three layers of Red, Green and Blue images). But just picking high Red value from a frame doesn't define it Red. Say for example, white has RGB components (255,255,255); so all my white colors will also be segmented, which I don't want.

A red component means high R, low G and low B component. Use impixelinfo on a frame to see the practical values.

imshow(s(150).cdata); impixelinfo;

Keeping the values in mind, threshold all three frames and then add them up to show only red regions of frame.


Now it's time to filter the minor noises using connected component analysis as did in Sudoku Solver project and dilate the remaining red component to form a good shape. Run all this in a for loop till the last structure element arrives and keep outputting image using imshow() and pause(0.01) functions. Pausing is necessary to see the video.

Now all you have to do is take the mean of all white pixels and show shape on its gray-scale image.
Happy object tracking!
The following video is a demonstration of the object-tracking. The yellow spot on finger follows the finger in x and y both, while the bar on left takes only y components. I aim to use this to play a ping-pong game.

Where should you start to image-process?

If you are interested in image-processing, download MATLAB from torrents. Probably it is the only place you can get it for free. But the problem is you don't get hardware support packages cracked. So if you want to start anew, start with OpenCV. I will be soon moving to OpenCV because it is open-source.
For tutorials, you can go through,
1. https://www.youtube.com/playlist…
The above playlist covers only very simple basics that will comfort you with the environment. The key is MATLAB documentation. Open up an example go through it and search for every function, read its syntax and what it does.
The problem with this project is it is not very robust. It will occasionally pick noises or wipe out a number from Sudoku image. My image processing techniques work but they ain't fool-proof. To counter that I have provided a manual correction method within the code.

You scroll down the blog what problems were faced earlier, what alternate solutions I came with, why I discarded some etc.

Right now, I am working on a Finger controlled Ping Pong game, integrating C and MATLAB. Till now I am successful to object track and make a ping-pong game in C. Will soon integrate them and blog. Feel free to share your views. :)

Friday 5 June 2015

Finalized my Sudoku Solver project.

So finally, I was able to solve a few Sudoku problems from newspapers using my program. The Sudoku solving algorithm seems fool-proof till now yet image-processing not satisfactory to me.
You may look out for my project in the CustomizationOfGrid branch of following link to GitHub here. Don't forget to view README.md.

Following are raw ideas of my image-processing script :
1. Cropping the image by finding the corners of the cleared border image.
2. Straightening by finding mean corners.
3. Perform Contrast enhancement, Connected components analysis and filter.
4. Setting up ROIs for each Sudoku cell and prompt menu to adjust ROI manually if found incorrectly placed w.r.t. the number in cell or surrounding cell.
5. Perform OCR.
6. For characters below certain Confidence levels print 'x' and the user must amend to it.

Don't forget to comment any better methods to image process such images of puzzles.


Wednesday 27 May 2015

GitHub.

I setup a GitHub account yesterday.
At first, you might find it difficult to understand but it is a piece of cake actually.

GitHub is an online platform for sharing open-source projects and software developments. Basic motto of it is to keep everything in sync in a team. You can invite someone to contribute to your code, you can check on-going various projects, contribute to them and push it on for responses.

You'd need a GitHub account, GitHub installed on your computer and know 5 to 6 commands. There comes a GUI as well as a Shell application of GitHub on your computer. I'd prefer command line one.

Follow the link below for learning basics of GitHub. Great tutorials. (Y)
GitHub tutorial by LearnCode.academy

Backtracking algorithm is a great tool.

So I wanted to solve the SUDOKU I just recognized from the image I fed in MATLAB and I tried various logic but nothing worked better than "Backtracking". You can find a great explanation of this on YouTube or  http://www.geeksforgeeks.org/backtracking-set-3-n-queen-problem/  .
Basically, a function is made to recur and return values as true or false if the consistency is maintained or not respectively.

Unlike N-Queen problem where you can output simultaneously, you might find need a global variable that stores the ANSWER matrix of SUDOKU if no empty boxes are possible; or else returning values and stepping out of recurring functions might result in losing of the solved matrix.
I could solve a 9x9 SUDOKU in 3 seconds. My program needs optimization.

Will keep posted on program optimization and better image processing techniques because the current one carries several cons.

Tuesday 26 May 2015

Getting better OCR results from mazes or puzzles - Method 1.

ocr() function in MATLAB supports few helpful attributes.
Following three(roi , TextLayout and CharacterSet) might help you increase OCR efficiency in reading characters from puzzles or places where you may have an idea of spacing between characters.

Step 1: Set up a grid of Region Of Interest(roi).
I am working on a Sudoku puzzle solving program. So basically, I know the size of Sudoku I am feeding my program. This gives me a rough idea of each small cell dimensions. Or you can find it a more non-rigid way by :
1.Find size of image processed and cropped maze.
2.Divide rows and columns as Sudoku dimensions.

"Moreover, your region of interest is not the complete cell Of course, the interested character lies in middle of the cell. So amend the rectangle dimension as necessary and set up an array of xmin, ymin, width and height of rectangle."

[row column]=size(out); %out is my image-processed array
r_round=round((row)/9);
c_round=round((column)/9);
u=1;
for i=0:8
    for j=0:8
        xinit= i*c_round+20;          % +20 and -35 is for adjusting coordinate a bit from theoretical
         yinit= j*r_round+35;       %value as  we are interested in central part of cell where element lies.
         roi(u,1:4)=[xinit yinit 125 125];
        u=u+1;
    end
end

Step 2: This step is probably the final step. It is kind of simple. Just direct the in-built ocr() function to do the job and provide parameters correctly.

ocrtext=ocr(out,roi,'TextLayout','Block','CharacterSet','123456789');

%Here 'TextLayout' attribute specifies the layout of characters to be read. I have set it to 'Block' as %my characters won't have a continuity in background and moreover, they are like blocks. You can %check Documentation of MATLAB for other values. 'CharacterSet' specifies  which characters %shall be considered for matching the values. I have put 1 through 9 as my Sudoku puzzle has only %digits.

----------------------------------------------------------------------------------------------------------------------
ocrtext cell contains ocrWords, ocrConfidences and various useful props.
The ocrtext will contain 81 ocrtext cells. Each corresponding to a cell on SUDOKU maze.
Store these cells in an array and use it for further SUDOKU solving.
Be careful about cells and arrays. Know difference between them and convert cells to matrices using cell2mat().
Refer Documentation of MATLAB  by typing "doc"(without quotes) in command window.

Friday 22 May 2015

Glitch in the "Bounding Box" method.

Regarding the last post. The method I posted had a major drawback.
I will explain with the help of an example.

I tried to feed my code a real sudoku problem. And it so happened that my OCR results storing array had a number "95126".

This was because it considered the less spaced numbers as a single number and hence stored in a single cell. This was a havoc for me; but I found an alternative. I will post that soon,
Keep smiling. :)

Found a solution to storing characters recognized from MATLAB in an array in a program to solve Sudoku.

The key were bounding boxes.
I found out the elements recognized having same bounding box row coordinates and hence stored their column coordinates in same row of an array and changed row of array when it didn't meet my condition of same row location.
This way I got an array of elements of my sudoku puzzle sorted row-wise.

Here's the trick for storing it column-wise.
I made a scale of pixels showing distance between a block and first block. You can find out prcatically using impixelinfo how many pixel difference corresponds to number of blocks.
Like in my case 150 pixels corresponded to center to center of two adjacent boxes. Hence I named a variable to store "what-multiple-of-150" is the non-empty character containing pixel.

This way you can sort it column-wise and hence get a complete Sudoku puzzle from page to matrix using basic knowledge of MATLAB.

P.S. This method has major drawbacks. I will post the alternative I found soon. Thank you.  

Wednesday 20 May 2015

Stuck. Need help.

I am making a sudoku solver using MATLAB. So far I completed cropping my sudoku puzzle from image and even extracting numbers accurately. But the problem is the numbers are extracted in text file of OCR regardless of position of where they are. Need help to store my recognised characters in a matrix to further process for solution.

Tuesday 12 May 2015

Summer.

So here it is. Summer vacations. Time to set aims clear and start Image Processing and look forward to Advanced AVR. Heads up.