Chủ Nhật, 19 tháng 7, 2015

OpenCV vs Matlab in Image Processing

OpenCv and Matlab are frequently used in image processing and computer vision because of their well-supported from OpenCv developers and Mathworks. In this post, I would like to highlight some differences in some basic concepts in memory layout, model, math expressions and etc. These concepts are very vital for programmers who use these tools.

1. Memory layout of an image
  • OpenCV supports only interleaved images (packing multiple channels one after the other for each pixel). This is more ridiculous and take notices when reading pixel values of opencv image.
  • Always to like this in scanning an image in Opencv 
    int channels = I.channels();

    int nRows = I.rows;
    int nCols = I.cols * channels;

    if (I.isContinuous())
    {
        nCols *= nRows;
        nRows = 1;
    }

    int i,j;
    uchar* p;
    for( i = 0; i < nRows; ++i)
    {
        p = I.ptr<uchar>(i);
        for ( j = 0; j < nCols; ++j)
        {
            p[j] = table[p[j]];
        }
    }
  • Matlab all of the channels clustered into image planes with the planes placed one after another. There is one advantage that matlab is homogenous, and single invariant to deal with.
2. Memory model
  • OpenCV is row-major
  • Matlab is column-major.

3. Matrix allocation and copy
  • Opencv: Do not expect a deep copy of an assignment operation in OpenCv. It just copies the header of Mat object.

  • Matlab: Somehow, Matlab will delay the deep copy until necessarily.
Ex: a = rand(5000);
      b = a;                // still not copy from a
      a(1) = 1;            // a will make a deep copy of itself and modify first element to 1.

This is the only way to implement Mat in opencv, because Mat will be shared between many variables rather than deep copying around, which is heavily prohibited for large object in memory.

4. Math experssions:
Although cv::Mat supports some mathematical expressions, it is very limited. Matlab is very intuitive and expressive language of math.

5. Matrix dimension in Opencv:
Semantic meaning x ~ width, y ~ height. But the first dim is y, second dim is x. 
For example, to access elements in position (x, y) in Mat, we should do
mat.at<int>(y, x).
Similarly, Matlab also uses the same notations.

6. Continuity of memory layout:
Memory layout for a matrix in Matlab is continuous, column after column. However, in Opencv, it can be separate or continuous. We can check its continuity by calling function Mat::isContinuous() in Mat objects. 
http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-iscontinuous

7. Size vs. Size
OpenCV returns size() method as Size(cols, rows). This is inconsistent with Mat constructor Mat(rows, cols, type). While Matlab is always consistent, a matrix will return size as index dimensions of matrix (0, 1, 2, ...).
The problem with OpenCV that it has notations of width, height with width ~ x ~ cols, height ~ y ~ rows. Remembering this correspondence is problematic.
REMEMBER: Size(x, y).

Selamat Hari Raya
@An

Thứ Tư, 26 tháng 11, 2014

What happened if GCC search for libraries in C/C++

Hi all,
In some beautiful days, we wonder how GCC search for standard libraries like libstdc++.so. Cool! It really matters for those guys who works on developments of new standard libraries. They want to have both versions of libraries at the same time. It is a controversial topics. After I googled it, here is the summary I found.

There are two definitions denoted as ld you need to differentiate: linker in GCC and loader in linux. ld can refer to ld (GNU linker) (at compiling time). It can also refer to loader ld.so in linux (at running time).

How to know search path during linking and running time? 

During linking of GCC, we can use this instruction:
1/ You can do this by executing the following command:
ld --verbose | grep SEARCH_DIR | tr -s ' ;' \\012

2/ gcc passes a few extra -L paths to the linker, which you can list with the following command:
gcc -print-search-dirs | sed '/^lib/b 1;d;:1;s,/[^/.][^/]*/\.\./,/,;t 1;s,:[^=]*=,:;,;s,;,;  ,g' | tr \; \\012

The answers suggesting to use ld.so.conf and ldconfig are not correct because they refer to the paths searched by the runtime dynamic linker (i.e. whenever a program is executed), which is not the same as the path searched by ld (i.e. whenever a program is linked).

The most important keynote: GCC search -L paths first, then the default library (i.e, 2 first, then 1).

During run-time:
ldconfig -v 2>/dev/null | grep -v ^$'\t'

Thứ Năm, 22 tháng 5, 2014

what happened after # in C/C++

Hi all,
If you ever want to know what will happen after including a header, what does GCC look for, or where does it find these headers, or then can I read this header files in Linux. Awesom.......e!!!
If you feel awesome, you need to know a little bit about it.
Well, GCC will look in default "include" folder in Linux such as
     /usr/local/include
     libdir/gcc/target/version/include
     /usr/target/include
     /usr/include

If you mention -Idir option in the command line or makefile scripts, it will search your directory first, then the default folder. For example, if you want to search for headers in current working folder, then use "-I."
More information,
https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html.

Thứ Sáu, 4 tháng 4, 2014

HOW-TO: things after fresh Ubuntu 12.04 Desktop installation as a computing server.

Hi all,
After installing Ubuntu 12.04 Desktop, you should install some packages which is very useful in long term. All of these tips, I collect from Internet. It's totally up to purpose of your machine. My machine is up to running experiments, workstation usages, not for entertainments.
1. If you occasionally build applications from source or make your own deb files, here are some basic packages you should install:

sudo apt-get install build-essential automake make checkinstall dpatch patchutils autotools-dev debhelper quilt fakeroot xutils lintian cmake dh-make libtool autoconf git git-core subversion bzr

2. I install Ubuntu on a workstation as a server. At home or office, you have a personal Windows machine. So, remote desktop logging into Linux workstation from a Windows computer is very important. I recommend you use X11rdp, because you can copy text or files between Windows and Linux computers. Other remote desktop protocols such as VNC don't have this feature. This feature is very useful for developments latter.

3. SSH connection.
If you are a fan of terminal and SSH, you should set up a SSH server on your workstation. Then, it is vital for a connection from Linux machine to a Linux machine w/o using remote desktop logging.

4. If you have a GPU, setting up NVIDIA driver and CUDA development kit are enlightened.

5. Sharing is important. Samba is the most useful way to share files between Linux and Linux machine. It is also compatible with Windows machine.
https://help.ubuntu.com/lts/serverguide/samba-fileserver.html
sudo apt-get install samba.

Thứ Ba, 25 tháng 3, 2014

Peekaboo: Machine Learning Toolkits

Peekaboo: Machine Learning Toolkits: Wow. So much to read today . While following link upon link, I found so many great toolkits that I think it is worth listing them here. On...

Peekaboo: Favourite Code from Andy's blog

Peekaboo: Favourite Code: In gerneral I use Python with Numpy/Scipy/Matplotlib for most of my experiments, so most of these are python tools. Here are some projects ...

Chủ Nhật, 2 tháng 3, 2014

HOW-TO: set up Java environment on Ubuntu.

Hi all,
I am kind of big moving from Windows to Ubuntu including infrastructures, softwares, and even cultures. However, I still use both Windows and Linux. I cannot live isolated with surrounding Windows machine around me in labs even my laptop. Windows are simple and convenient for normal users, but Ubuntu is just great for developers.
I definitely love Eclipse. In this blog, we provide some guide to start Java life in Ubuntu. C/C++ life in Ubuntu are great and simple. I supposed that Java life is also simple across different OSs.
First, you need to install Java Development Kit (JDK) which includes Java Runtime Environments (JRE). Going to Oracle and download the newest jdk1.7 [1]. For example, I downloaded jdk1.7.0_51. Then I untar it.
tar xzf jdk-7u51-linux-x64.gz
 As a admin user, you can add or change these two lines in your /etc/profile to point to the installation and it will affect system-wide. OR as a normal user, you can export an environment variable in ~ /.profile. Where JAVA_HOME is the place you just untar your jdk, for instance, /home/tranlaman/Downloads/jdk1.7.0_51.
export JAVA_HOME=/home/tranlaman/Downloads/jdk1.7.0_51
export PATH=$PATH:$JAVA_HOME/bin
 Then, you log out and in again to see effect of the environment variables. After that, you download and install Eclipse from [2].
Further, if you want to install C/C++ plugin in Eclipse to develop C/C++ programs, you can follow this instruction. Go to Help/Install New Softwares, then add the C/C++ Development Toolkit (CDT) link in the box as http://download.eclipse.org/tools/cdt/releases/kepler.
You can replace kepler as the version of Eclipse. Then press Enter.

[1] http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
[2] https://www.eclipse.org/downloads/