Tuesday, November 29, 2016

Transition from C/C++/Java to Python

I am trying to learn Python myself, as it greatly expedites prototype development compared to C/C++/Java.
Here is quick conversion of C/C++/Java common codes into Python:

for (int i=0; i<N; i++) {
for i in range(N):

if (x==y) {

if x==y:

!true

not True

else if {

elif:

printf("%d\n", i)

print i

printf("%d ", i)

print i,

for (int i : array) {

for i in array:

vector<int> v;

v.push_back(1);
v.push_back(2);
v = [1,2]

// C++
vector<int> u,v;
...
v = u;
import copy
v = copy.copy(u) // OR // v = u[:]

// C++ vector<int> &u, &v;
...
v = u;
v = u

Sunday, November 27, 2016

How to Compile OpenCV with Debugging Symbols

Here is how to compile OpenCV with debugging symbols so that you can view OpenCV Library's source code as you debug.

When configuring with cmake, run with the following option:
$ cmake -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo ...

This option will add -O2 -g -DNDEBUG flags to the compiler when you build OpenCV.

For Ubuntu/Debian, take a look this post to see how to compile OpenCV from sources.

By the way, if you build OpenCV with clang, then you probably want to use lldb instead of gdb. If you compile with g++, then you may want to gdb instead of lldb. If you are having trouble running gdb on your Mac, check out this post.

Saturday, November 26, 2016

Using Qt as OpenCV HighGUI Backend for Mac OS X

Although I am in love with my new Macbook 12", I must admit that its X11 is quite annoying when used as OpenCV HighGUI's backend--it does not resize the image!

I was so frustrated with it that I looked for an alternative backend, and here it is: Qt5. In this tutorial, I will go over the method of building OpenCV3 on Mac OS X with Qt5 as HighGUI's backend. For simplicity, I will make use of homebrew.

First, you will need to tap into science:
$ brew tap homebrew/science

Next, install opencv3 with qt5 option:
$ brew install opencv3 --with-qt5

This option will add -D WITH_QT=ON in OpenCV's cmake option, thus linking Qt.

That's it! If you are wondering what are other available options, run
$ brew options opencv3

For more info on the package, run
$ brew info opencv3

That's it! You should now be able to launch HighGUI window via Qt5!

Saturday, November 19, 2016

Template Class in C++: Simple Queue Class Example

In this tutorial, I would like to demonstrate C++ template class by providng a very simple Queue class example.

The following shows its source file queue.cpp and header file queue.hpp:

There are a couple of important things to note.

First, the header file actually #includes the source file. This is because Queue class is a template class. In C++, a template class declaration and definition cannot be separated, and therefore by #includeing the source file, the two files are effectively treated as a single file. Of course, you may choose to simply define all the methods in the header file and get rid of the queue.cpp file.

Second, copy constructor, copy operator, and destructors are defined explicitly, because it assigns dynamic memory allocation. Please refer to this post for more details on the Rule of Three.

Lastly, when you compile sources that make use of this template class, all you need to do is to #include the header file. For instance, the compile command should look like:
$ g++ main.cpp

Notice there is no need to compile queue.cpp file or queue.hpp file separately. All you need to do is to make sure that queue.hpp file #includequeue.cpp file, and main.cpp #includes queue.hpp file.

Sunday, November 13, 2016

How to Determine Target Architecture from Library or Executable Files

To determine the target architecture of a library file or executable file, simply type in
$ objdump -x <file> | grep architecture

For example, you could do
$ objdump -x a.out | grep architecture
architecture: i386:x86-64, flags 0x00000012:

So, we now know that it is for x64 architecture!

By the way, if you don't have objdump, you could get it for Debian
$ sudo apt-get install binutils
or for Mac OS X
$ brew install binutils && alias objdump=gobjdump

Monday, November 7, 2016

OpenCV for Android Integration with NDK in Studio 2.2+

Starting with Android Studio 2.2+, NDK integration has become much easier. Thanks a lot, Google!

In the previous post, I showed you how to import OpenCV Android Tutorial 2 sample app into Android Studio and build with NDK integration, which admittedly was quite complicated. I am happy to present much easier method here in terms of NDK integration, starting from Android Studio 2.2.

The only difference from the past post lies in the App module's build.gradle file. The new file should resemble this:
apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "24.0.3"

    defaultConfig {
        applicationId "org.opencv.samples.tutorial2"
        minSdkVersion 8
        targetSdkVersion 22

        ndk {
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }

    externalNativeBuild {
        ndkBuild {
            path 'src/main/jni/Android.mk'
        }
    }

}

dependencies {
    compile project(':openCVLibrary310')
}

That's it! This will now let Android Studio successfully load C/C++ source files in the src/main/jni directory with valid syntax correction, etc.

Wednesday, November 2, 2016

Install Latest Version of OpenCV on Debian from Sources

Here is how to install the latest OpenCV version on Debian from sources. If you are looking for tutorials on Mac OS X, you may want to check out this post.

Before doing anything, make sure to install necessary packages:
$ sudo apt-get install -y build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev

By the way, if you are not sure how to setup sudo in Debian, please take a look here.

Now, download the latest sources from its official Github repository. This will take some time.
$ git clone https://github.com/opencv/opencv.git

Else, you may want to just check out Linux component from here.

Create release folder and run cmake:
$ mkdir opencv/release && cd opencv/release
$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_EXAMPLES=YES ..

For more OpenCV cmake options, take a look here starting at line 171. If you would like to be able to debug the OpenCV library, you will need to compile with debug symbols. This post explains how to do so.

Now, we are ready to compile and install:
$ make -j $(nproc)
$ sudo make install

Let's test and see if you can link the library. Create test.cpp file with the following:
#include <opencv2/core.hpp>
#include <iostream>
using namespace cv;
int main() {
Mat test(3,2,CV_8UC1); 
std::cout << test << std::endl;

return 0;
}

Compile and run:
$ g++ test.cpp $(pkg-config --libs opencv)
$ ./a.out
./a.out: error while loading shared libraries: libopencv_shape.so.3.1: cannot open shared object file: No such file or directory

OK. This is because ldconfig hasn't been updated.
$ sudo ldconfig
$ ./a.out
[ 10,  60;
  71,   0;
   0,   0]

Enjoy!

How to Install VirtualBox Guest Additions on Debian

VirtualBox Guest Additions provides many features, yet it may not be easy to install on Debian system. Here is how to install Guest Additions on Debian guest machine.

In the guest Debian system, insert Guest Additions image by selecting Devices->Insert Guest Additions CD Image from VirtualBox menu. This will insert the image into the guest machine. 

The Debian system will automatically mount the image to /media/cdrom folder. Let's run it:
$ su -
Password:
# cd /media/cdrom
# ./VBoxLinuxAdditions.run
-su: ./VBoxLinuxAdditions.run: Permission denied

This is rather interesting. Permission denied even for root. By the way if you want to run sudo command instead of su in Debian, refer to this tutorial.

The reason for this is actually because the Guest Additions image has been mounted with noexec flag.

# mount | grep cdrom
/dev/sr0 on /media/cdrom0 type iso9660 (ro,nosuid,nodev,noexec,relatime,user)

As clearly seen, the Guest Additions CD image has been mounted with noexec flag set. That is why you couldn't run it even as root. Let's mount it again without noexec flag.

# cd / && mount -t iso9660 /dev/sr0 /media/cdrom
mount: /dev/sr0 is write-protected, mounting read-only
# mount | grep cdrom
/dev/sr0 on /media/cdrom0 type iso9660 (ro,relatime)

OK. The Guest Additions image has been mounted successfully. Let's run the install script;
# /media/cdrom/VBoxLinuxAdditions.run
Verifying archive integrity... All good.
Uncompressing VirtualBox 5.1.8 Guest Additions for Linux...........
VirtualBox Guest Additions installer
Copying additional installer modules ...
Installing additional modules ...
vboxadd.sh: Building Guest Additions kernel modules.
Failed to set up service vboxadd, please check the log file
/var/log/VBoxGuestAdditions.log for details.

Well, let's examine the log file:
# cat /var/log/VBoxGuestAdditions.log
vboxadd.sh: failed: Look at /var/log/vboxadd-install.log to find out what went wrong.
vboxadd.sh: failed: Please check that you have gcc, make, the header files for your Linux kernel and possibly perl installed..

As the log file states, we need to install some necessary packages first, because it needs to compile the Guest Additions from sources.
# apt-get update
# apt-get install -r gcc make linux-hearders-$(uname -r)

Finally, we are ready to install Guest Additions:
# /media/cdrom/VBoxLinuxAdditions.run
Verifying archive integrity... All good.
Uncompressing VirtualBox 5.1.8 Guest Additions for Linux...........
VirtualBox Guest Additions installer
Removing installed version 5.1.8 of VirtualBox Guest Additions...
Copying additional installer modules ...
Installing additional modules ...
vboxadd.sh: Building Guest Additions kernel modules.
vboxadd.sh: Starting the VirtualBox Guest Additions.

You may need to restart the the Window System (or just restart the guest system)
to enable the Guest Additions.
# reboot

You may want to reboot for this to take effect. Enjoy virtual Debian system!

Saturday, October 29, 2016

How to Disable Annoying Paste Function of Mouse Middle Button

If there is one thing I really hate about my current GNOME desktop environment is its default paste function mapped to the mouse middle button. This is simply so annoying that I was looking for a way to get rid of this. After some trials, I have found one that actually works very well, and I would like to share it with anyone who is also having this problem. This post is based on this and this.

First, install xinput package if already not installed.
$ sudo apt-get install -y xinput

Next, list input devices and look for your mouse:
$ xinput list | grep 'id='
⎡ Virtual core pointer                     id=2 [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer               id=4 [slave  pointer  (2)]
⎜   ↳ Microsoft Microsoft® Nano Transceiver v1.0 id=11 [slave  pointer  (2)]
⎜   ↳ Microsoft Microsoft® Nano Transceiver v1.0 id=12 [slave  pointer  (2)]
⎣ Virtual core keyboard                   id=3 [master keyboard (2)]
    ↳ Virtual core XTEST keyboard             id=5 [slave  keyboard (3)]
    ↳ Power Button                             id=6 [slave  keyboard (3)]
    ↳ Video Bus                               id=7 [slave  keyboard (3)]
...


OK, so it tells me what input devices are connected. Under Virtual core pointer, I see my Microsoft Mouse, which is mapped to 11 and 12. In my case, it was the first device:
$ xinput get-button-map 11
3 2 1 5 4 6 7 8 9 10 11 12 13

The second number represents mapping of the middle button, so I simply disable it by setting it to 0:
$ xinput set-button-map 11 3 0 1

That's it. I now confirm that the middle mouse button no longer functions! Well, I want to keep it this way all the time, so I created a script
$ echo "xinput set-button-map 11 3 0 1" > ~/disable_middle.sh
$ chmod u+x ~/disable_middle.sh

I made it execute every time GNOME starts up by creating diable-middle-button.desktop file in ~/.config/autostart/ folder with the following
[Desktop Entry]
Type=Application
Exec=~/disable_middle.sh
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
Name[en_US]=disable-middle-button
Name=disable-middle-button
Comment[en_US]=
Comment=


Now, your mouse middle button will be disable every time you start up GNOME!

Wednesday, October 26, 2016

Three Minutes Daily Vim Tip: Paste without Strange Indentation Behavior

I may have encountered a strange behavior in vim when you try to paste some codes with system-generic method (i.e., Ctrl+V) rather than vim method (i.e., yy and p). Here is how to fix it:

:set paste

This option will let vim know that you will be pasting text, and vim is to paste the text as is, without trying to auto-indent. When you are done pasting, simply set

:set nopaste

Happy vimming!