Saturday 1 November 2014

Compiling OpenCV with MinGW for Windows (and setup in CodeBlocks IDE)

For a robotics project, which I may document on this blog at a later stage, I needed OpenCV working on my computer so I could play around with algorithms and ideas. Later the code was ported, without any hassle really, onto a robot that I built with a school robotics team that had an ARM processor doing some computer vision. I discovered that getting the pre-compiled OpenCV binaries to work with my preferred compiler and IDE was never going to work - the only option was to compile the source code into binaries and headers that MinGW64 would be able to work with. Luckily this isn't as hard as it sounds.

Compiling OpenCV yourself can be useful if you want to use a compiler or computer architecture for your projects which does not have pre-compiled binaries officially released for it. Compiling yourself also lets you choose what you want and don't want included. Unless you are cross-compiling, the only way to make things work reliably is to compile your programs with the exact same compiler that you compiled OpenCV with.

I wrote this guide after a lot of research on Google and trial and error in the first step to trying to get into some computer vision. Disclaimer: I accept no responsibility for anything that may come of following this guide or things that may not work.

--Download the following or newer versions--:

OpenCV 2.4.3 for windows:        
http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.4.3/OpenCV-2.4.3.exe/download

MinGW compiler:                  
http://sourceforge.net/projects/mingwbuilds

CMake 2.8.12 installer for windows:
http://www.cmake.org/cmake/resources/software.html

CodeBlocks IDE with no compiler: 
http://sourceforge.net/projects/codeblocks/files/Binaries/13.12/Windows/codeblocks-13.12-setup.exe/download


--Setup the programs--:


    1.) The OpenCV file you downloaded was a self-extracting executable. Extract it to whatever location you want, I would recommend C:\opencv because 
it is easy to remember and get to. You will be entering this path A LOT.

    2.) The MinGW file you downloaded is not actually MinGW, but a program that allows you to choose very precisely what version to download and install. Run it and pick your own settings, I chose these, but it doesn't really matter-
        -Version:               4.8.1
        -Architecture:       x64 (assuming your machine is 64 bit, if not pick x86)
        -Threads:              Posix
        -Exception:           Seh
        -Build revision:     5
After getting MinGw installed(I would recommend putting it in C:\MinGW64), you will have to set up your Windows' PATH variable for Windows to be able to find MinGW's  executables. This is so that you can call any of MinGW's modules, e.g. g++(the c++ compiler) from anywhere on the command prompt. This saves you having to navigate to the MinGW directory every time. It is also crucial that MinGW is included in the PATH so that other programs which rely on it can find it by themselves. The path which you  add to PATH will look something like this: "C:\MinGW64\mingw64\bin" no quotation marks of course.

The PATH can be edited from the command line (google for it), or using  a Windows tool with a GUI: just search for "path" on Windows 7 and 8 in the start menu and a program called "Edit the system environment variables" will come up. Start the program as an administrator (right click on its icon - it's in the menu), click "environment variables". Under the list "System variables", search for "Path" double click it to edit it. All you have to do is add the location of MinGW's bin (stands for binary) directory to the end of the list. Make sure you put a semicolon before (if required) and after to separate it from other paths.

To check that MinGW is setup properly, go to the command prompt and type in "g++", you should get a message saying "g++ fatal error: no input files compilation terminated". Though  it's an error, it is actually a good error, because it confirms MinGW is in the path as the error is coming from g++ rather than Windows. 

    3.) CMake's executable will install CMake all properly for you.
   
    4.) Install CodeBlocks, once again, its installer will do everything for you. While it's installing, it should find the MinGW installation we did earlier, if not, 
don't worry. If it didn't find MinGW, or you installed CodeBlocks before MinGW, we'll have to tell it where it is.

Even if CodeBlocks did find MinGW by itself, I would still go through the following steps to check that everything is setup properly  by default anyway.

Start CodeBlocks, then head to the drop down menu item at the top called "settings", then click on "Compiler...", click the tab "Toolchain Executables".
First set "Compiler's installation directory" to where MinGW was installed(same as the thing we added to PATH, just minus the bin folder on the end). As for the other  settings:

        -C compiler:                           gcc.exe
        -C++ compiler:                      g++.exe
        -linker for dynamic libs:        g++.exe
        -linker for static libs:             ar.exe
        -Debugger:                             GDB/CDB debugger
        -Resource compiler:               windres.exe
        -Make program:                     mingw32-make.exe (yes, I know we installed a 64bit MinGW)

If for some reason these executables don't exist in your installation, it is most likely they are there but named something slightly different. Go into the \bin directory  of MinGW and have a look and see if you can see something similarly named. Now CodeBlocks should be ready to go. Create a hello world project and see if it all works.


--Compile OpenCV for MinGW--:


    1.) Start cmake-GUI.exe, it should be under "C:\Program Files (x86)\cmake-2.8.12.2-win32-x86\bin", or you could just search for it.

For the text field "Where is the source code:" in the CMake GUI, enter the directory where openCV was extracted (should be: "C:\opencv") don't enter any deeper folders which look like they may have some code. The correct directory is the one with, among other things, a "CMakeLists.txt" file in it. This is the file that tells CMake what user-selectable options there are for our library and how to create compilation instructions for the compiler. CMake WILL NOT compile stuff, just configure stuff ready for compilation.

Now, for "where to build the binaries" I would reccomend making another opencv directory called "opencv_mingw" under "C:\" and use that. Once the directories are sorted, click the "configure" button, in the window that pops up, select "MinGW Makefiles" in the dropdown, and select the radio button "use default compilers" then click "finish". A progress bar will appear and some text in the output, this may last for a minute, all CMake is doing is mainly testing our compiler that we installed(MinGW), which it found because it was included in the PATH. Now, for all those checkboxes in CMake that appear the, defaults will be fine, but the point of compiling is that you get to choose, so if there is anything from other guides that you want to follow, do it. Now click "generate".
   
    2.) Now we leave CMake and go to the command prompt. Navigate to "C:\opencv_mingw" or whatever you named it, just make sure it's the directory you put down for "where to build the binaries" in CMake. You can navigate to the file in the command prompt using the command: "cd <directory>", which stands for change directory. The command won't appear to do anything, but if you look at the bit to the left of the flashing cursor in the prompt, you will see that it now has the name of the directory(if it went successfully). Now type in "mingw32-make", now the command propmt will light up for about 30 minutes depending on your PC's power. When that is done, type in "mingw32-make install" DON'T miss this second step because you see some newly created files and think you are done.

    3.) Open up CodeBlocks, create a new "console application", now you will see it appear in the directory tree on the left of the CodeBlocks window. Right click on your project(should have a logo next to it with 4 coloured blocks), select "build options". Go to the tab "search directories" and select the second-tier tab "compiler" add the directory "C:\opencv_mingw\install\include", now select the second-tier tab "linker" and add the directory "C:\opencv_mingw\install\lib". Now go to the first-tier tab "linker settings", under the currently-empty list "Link libraries" add all the files in "C:\opencv_mingw\install\lib", the directory will contain about 20 files, all which end in ".dll.a". To add them all quickly, just click the "add" button, then the button in the window that pops up with the three dots (right next to where you'd normally ype a path). Now navigate to "C:\opencv_mingw\install\lib" and shift click to select all the files. If you are asked whether you want to use relative paths, click no, this won't affect operation either way, but reltive paths are messy.

YOU WILL HAVE TO DO THE STEPS ABOVE FOR EVERY NEW CODEBLOCKS PROJECT YOU CREATE WHICH YOU WANT TO USE OPENCV IN. There are ways around this: by doing the previous steps in global rather than project settings. To do this, go to the menu bar, go to "settings" then "compiler...". Note if you do this that it will apply to any project you open in CodeBlocks.

    4.) CodeBlocks, OpenCV and MinGW are now all set up to work, but if you try to compile a program which includes OpenCV libraries, the program will compile but crash when you run it. This is because windows can't find the OpenCV dll's we created when we compiled OpenCV (in simple terms dll's are libraries written by humans in C++, etc. turned into machine-readable code through compilation and are used at runtime). So what we are going to do now is add the OpenCV dll's to Windows' PATH environment variable, like we did 
with MinGW. Add the directory "C:\opencv_mingw\install\bin" to PATH.


    5.) Test everything by compiling and running a test program. Here is a test program which should run if everything is working fine:


#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
 
using namespace cv;
 
int main()
{
    Mat image;// new blank image
    image = imread("test.png", 0);// read the file
    namedWindow( "Display window", CV_WINDOW_AUTOSIZE );// create a window for display.
    imshow( "Display window", image );// show our image inside it.
    waitKey(0);// wait for a keystroke in the window
    return 0;



If it compiles but shows no image, there are a few common reasons why, and you should keep the following in mind when using CodeBlocks:

    -You need to create a .png image called "test.png" and put it under the folder "<my_project>\bin\Debug", this is where the executable file will be put whenever you compile your own programs.
    -The "run" button in CodeBlocks (Looks like a green play button) seems to run programs but never see any files which you put in the same directory as the executable (and refer to in software with relative paths). So instead of using the run button in CodeBlocks, navigate to "<my_project>\bin\Debug" in Windows explorer and click the executable file yourself.

 

 

--Credits and Resources--:

http://kevinhughes.ca/tutorials/opencv-install-on-windows-with-codeblocks-and-mingw/
http://zahidhasan.wordpress.com/2013/02/16/how-to-install-opencv-on-windows-7-64bit-using-mingw-64-and-codeblocks/

Friday 31 January 2014

DIY CNC Linear Rail Design

For my CNC machine I decided that I would try and make my own linear rail system using 608 skate bearings and flat steel. This was to try and save money, and I must day that my design, which made the best of the equipment I had on hand, failed miserably. Luckily I decided to try making a prototype with a 1m length and half a carriage before diving in and buying metres and metres of steel and wasting my time building any further.

Here's a drawing of the rail with a carriage riding on it:

This is one side of that carriage made and put together, to get adjustability and thus make up for lack of tolerance (had to do this by hand), I drilled the holes a bit large on purpose so I could (in theory) get the bearings pressing tightly against the linear rail and then just tighten up the bolt:
These are the four pieces of SHS cut and drilled, two of them have cuts which allow for access to get at bolts which have to be tightened. It turns out that there was not adequate room to get at bolts with this design anyway:
The linear rail I put together, it is made of two pieces of steel bolted together, namely 50mm SHS with 3mm walls, and also steel flat which was 5mm thick by 75mm wide if I remember correctly.
For the prototype, I only used construction-grade steel and this showed in the surface finish, in the final design I planned to replace the steel flat with precision-ground steel flat and just use structural SHS for support and rigidity.
Another problem with the overly large holes which I hoped would allow me to get adjustability was that the nut would have less flat area to sit on and thus tend to skew off at an angle easily and not be all that rigid, this problem was exacerbated by the fact that the square tube had very thin walls. Also I couldn't get a washer into the tight space to help the nut. This led me to trying to mill slots for adjustability, since I don't have a milling machine or a milling attachment for my lathe, I just clamped the piece to the tool post which was very finicky, also not very rigid when all the milling force was on the clamp rather than the tool post. It sure did mill fairly well though.

In the end I decided against this method of making home-made linear rails even if I could get easy adjustability and rigidity which were major challenges with the tools I have. The final reasons I decided against this design were: the carriages were too bulky, making the carriages was way too time-consuming given the number I would have to make in total and also the fact that precision-ground steel flat for the bearings to run on would cost a lot and negate any cost savings of going homemade. Bottom line: you're going to get what you pay for and your labour is not worth wasting when the products out of China are so cheap.

Instead I've been considering 16mm supported linear rail mounted on a frame made out of 50mm SHS or larger with thickest walls I can get and the linear bearings to go with it. Lucky for me it turns out that the supplier of the linear rail is a short drive away from me.